Skip to content

Commit ac387a1

Browse files
authored
Merge pull request #5 from rpitv/add-examples
2 parents 397694f + c6d9b5f commit ac387a1

18 files changed

+392
-12
lines changed

README.md

Lines changed: 41 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,25 +9,49 @@
99
1010
## Features
1111

12-
- Control different types of LEDs from your application.
12+
- Control different types of LED and LED arrays from your application.
1313
- Single channel
14-
- RGB/tri-channel
15-
- Arbitrary channel count
16-
- Diode mode, allowing you to remove a dedicated ground.
14+
- Multi channel (e.g. RGB)
15+
- LED segment displays
1716
- Flash LEDs at any frequency.
1817
- Animate your LEDs using your own custom functions.
1918

2019
## Necessary supplies
2120

2221
- Raspberry Pi (any should do, as long as it has GPIO).
23-
- LED(s) w/ necessary resistors.
24-
- Diodes for the ground connection, if using diode mode.
22+
- LED(s).
23+
- Any necessary resistors/transistors.
2524

2625
Hardware instructions coming sometime in the future.
2726

2827
## Usage
2928

30-
TODO Coming soon
29+
### Basic Example
30+
31+
```js
32+
const { LED } = require("pi-led-control");
33+
// Other imports: LEDArray, Animation, Curves
34+
35+
const led = new LED(3);
36+
led.write(true);
37+
led.off();
38+
```
39+
40+
### More Examples
41+
42+
More examples of how to use all the available imports are available in the [`/examples`](./examples) folder.
43+
44+
- [Basic writing](./examples/basic-write.ts)
45+
- [Basic animation](./examples/basic-animate.ts)
46+
- [Custom animation](./examples/custom-animate.ts)
47+
- [Basic LEDArray writing](./examples/basic-write-array.ts)
48+
- [Basic LEDArray animation](./examples/basic-animate-array.ts)
49+
- [Custom LEDArray animation](./examples/custom-animate-array.ts)
50+
- [Signal inverting](./examples/invert.ts)
51+
52+
### Specifications
53+
54+
TODO. For now, please refer to the examples and JSDocs within the code.
3155

3256
## Development
3357

@@ -50,6 +74,16 @@ npm run prepare
5074

5175
You are now ready to write code. All application code is located within [/src](./src). Begin writing in your `.ts` files. It is presumed you will not be developing on a Raspberry Pi. If you do, then you may run the application using `npm start`. Otherwise, use `npm test` to run unit tests on your code.
5276

77+
### Building
78+
79+
The library can be built with the following command:
80+
81+
```shell
82+
npm run build
83+
```
84+
85+
Building and deployment is handled by CI, if you wish to use the main NPM package.
86+
5387
### Testing
5488

5589
A unit test suite is available for the full API. You may run the test suite by executing:

examples/basic-animate-array.test.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Gpio } from "../__mocks__/pigpio";
2+
import run from "./basic-animate-array";
3+
4+
const digitalSpy = jest.spyOn(Gpio.prototype, "digitalWrite");
5+
const pwmSpy = jest.spyOn(Gpio.prototype, "pwmWrite");
6+
it("Should write the correct values to the output pin", () => {
7+
run();
8+
// LED animation is turned off before it even draws its first frame.
9+
expect(digitalSpy).toHaveBeenCalledTimes(6);
10+
expect(pwmSpy).toHaveBeenCalledTimes(0);
11+
12+
expect((digitalSpy.mock.calls[0] as any)[0]).toEqual(1);
13+
expect((digitalSpy.mock.calls[1] as any)[0]).toEqual(0);
14+
expect((digitalSpy.mock.calls[2] as any)[0]).toEqual(1);
15+
expect((digitalSpy.mock.calls[3] as any)[0]).toEqual(0);
16+
expect((digitalSpy.mock.calls[4] as any)[0]).toEqual(0);
17+
expect((digitalSpy.mock.calls[5] as any)[0]).toEqual(0);
18+
});

examples/basic-animate-array.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
import { Animation, Curves, LEDArray } from "../src";
2+
3+
function run() {
4+
// Create your LED
5+
const led = new LEDArray([3, 4, 5]);
6+
7+
// Create an animation with a provided Curve function and options.
8+
// There are multiple overloads of the LEDArray#animate() function. Check
9+
// docs for more options. This one will animate the LEDs so that the ratio
10+
// of brightness between each one is always the same. I.e., when the
11+
// animation is at 30% brightness, the brightness of each LED value in the
12+
// array is multiplied by 0.3.
13+
led.animate(new Animation(Curves.Sawtooth(500)), [255, 50, 170]);
14+
15+
// Start the animation. This creates a Node.js timer.
16+
led.startAnimation();
17+
18+
// This write() will succeed, but it will be immediately overwritten on the
19+
// next frame of the animation.
20+
led.write(true, false, true);
21+
22+
// Stop the animation. Does not turn off the LEDs, and whatever the state
23+
// they were in on the last refresh is persisted until overwritten.
24+
led.stopAnimation();
25+
26+
// Turn off the LED. Also stops the animation, if we hadn't previously
27+
// called stopAnimation()
28+
led.off();
29+
}
30+
31+
export default run;

examples/basic-animate.test.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { Gpio } from "../__mocks__/pigpio";
2+
import run from "./basic-animate";
3+
4+
const digitalSpy = jest.spyOn(Gpio.prototype, "digitalWrite");
5+
const pwmSpy = jest.spyOn(Gpio.prototype, "pwmWrite");
6+
it("Should write the correct values to the output pin", () => {
7+
run();
8+
// LED animation is turned off before it even draws its first frame.
9+
expect(digitalSpy).toHaveBeenCalledTimes(2);
10+
expect(pwmSpy).toHaveBeenCalledTimes(0);
11+
12+
expect((digitalSpy.mock.calls[0] as any)[0]).toEqual(1);
13+
expect((digitalSpy.mock.calls[1] as any)[0]).toEqual(0);
14+
});

examples/basic-animate.ts

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import { LED, Animation, Curves } from "../src";
2+
3+
function run() {
4+
// Create your LED
5+
const led = new LED(3);
6+
7+
// Refresh rate in milliseconds for which the Animation should refresh at.
8+
// Optional, defaults to 60fps.
9+
const refreshRate = Math.floor((1 / 15) * 1000);
10+
// Whether the Animation should automatically start upon construction.
11+
// Optional, defaults to true.
12+
const autoStart = false;
13+
// Period of the Curve function along the X axis (milliseconds). Required.
14+
const period = 1000;
15+
// Create an animation with a provided Curve function and options.
16+
led.animate(new Animation(Curves.Sine(period), refreshRate), autoStart);
17+
// Without the optional values:
18+
// led.animate(new Animation(Curves.Sine(1000)));
19+
20+
// Start the animation. This creates a Node.js timer.
21+
led.startAnimation();
22+
23+
// This write() will succeed, but it will be immediately overwritten on the
24+
// next frame of the animation.
25+
led.write(true);
26+
27+
// Stop the animation. Does not turn off the LEDs, and whatever the state
28+
// they were in on the last refresh is persisted until overwritten.
29+
led.stopAnimation();
30+
31+
// Turn off the LED. Also stops the animation, if we hadn't previously
32+
// called stopAnimation()
33+
led.off();
34+
}
35+
36+
export default run;

examples/basic-write-array.test.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
import { Gpio } from "../__mocks__/pigpio";
2+
import run from "./basic-write-array";
3+
4+
const digitalSpy = jest.spyOn(Gpio.prototype, "digitalWrite");
5+
const pwmSpy = jest.spyOn(Gpio.prototype, "pwmWrite");
6+
it("Should write the correct values to the output pin", () => {
7+
run();
8+
expect(digitalSpy).toHaveBeenCalledTimes(6);
9+
expect(pwmSpy).toHaveBeenCalledTimes(3);
10+
11+
expect((digitalSpy.mock.calls[0] as any)[0]).toEqual(1);
12+
expect((digitalSpy.mock.calls[1] as any)[0]).toEqual(1);
13+
expect((digitalSpy.mock.calls[2] as any)[0]).toEqual(1);
14+
expect((digitalSpy.mock.calls[3] as any)[0]).toEqual(0);
15+
expect((digitalSpy.mock.calls[4] as any)[0]).toEqual(0);
16+
expect((digitalSpy.mock.calls[5] as any)[0]).toEqual(0);
17+
expect((pwmSpy.mock.calls[0] as any)[0]).toEqual(255);
18+
expect((pwmSpy.mock.calls[1] as any)[0]).toEqual(128);
19+
expect((pwmSpy.mock.calls[2] as any)[0]).toEqual(40);
20+
});

examples/basic-write-array.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { LEDArray } from "../src";
2+
3+
function run() {
4+
// Create your LEDArray. Technically each pin can appear multiple times in
5+
// the same array, but there are probably not many cases where you would
6+
// ever want this.
7+
const led = new LEDArray([3, 4, 5]);
8+
// Turn on all three LEDs.
9+
led.write(true, true, true);
10+
// Turn off three LEDs.
11+
led.off();
12+
// Write different PWM values for each LED. These PWMs will immediately stop
13+
// as soon as the program exits, as mentioned in easier examples.
14+
led.write(255, 128, 40);
15+
}
16+
17+
export default run;

examples/basic-write.test.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
import { Gpio } from "../__mocks__/pigpio";
2+
import run from "./basic-write";
3+
4+
const digitalSpy = jest.spyOn(Gpio.prototype, "digitalWrite");
5+
const pwmSpy = jest.spyOn(Gpio.prototype, "pwmWrite");
6+
it("Should write the correct values to the output pin", () => {
7+
run();
8+
// 1 for digital write, 2 for off()
9+
expect(digitalSpy).toHaveBeenCalledTimes(3);
10+
expect(pwmSpy).toHaveBeenCalledTimes(1);
11+
12+
expect((digitalSpy.mock.calls[0] as any)[0]).toEqual(1);
13+
expect((digitalSpy.mock.calls[1] as any)[0]).toEqual(0);
14+
expect((digitalSpy.mock.calls[2] as any)[0]).toEqual(0);
15+
expect((pwmSpy.mock.calls[0] as any)[0]).toEqual(153);
16+
});

examples/basic-write.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { LED } from "../src";
2+
3+
function run() {
4+
// Create your LED
5+
const led = new LED(3);
6+
// Turn on the LED
7+
led.write(true);
8+
// Turn off the LED. Note, if you use led.animate(), this will stop the
9+
// animation while using write(false) will not.
10+
led.off();
11+
12+
// Write a PWM value of 153. This does not mean the LED will be on at 60%
13+
// brightness 100% of the time. Instead, it means the LED will be at
14+
// 100% brightness 60% of the time, and 0% brightness (off) 40% of the
15+
// time. To the naked eye, these will look the same anyway.
16+
led.write(153);
17+
// Turn off the LED. Note, since pulse modulation requires the program to
18+
// be running, if you do not set your LEDs to be either off or on before
19+
// your program exits, whatever the last pulse they received will persist
20+
// until overwritten by another process. E.g., with our last write() call,
21+
// 60% of the time when the program stops, our LED will remain on. The
22+
// other 40% of the time it will remain off.
23+
led.off();
24+
}
25+
26+
export default run;

examples/custom-animate-array.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { Gpio } from "../__mocks__/pigpio";
2+
import run from "./custom-animate-array";
3+
4+
jest.useFakeTimers();
5+
6+
const digitalSpy = jest.spyOn(Gpio.prototype, "digitalWrite");
7+
const pwmSpy = jest.spyOn(Gpio.prototype, "pwmWrite");
8+
it("Should write the correct values to the output pin", () => {
9+
run();
10+
jest.runAllTimers();
11+
12+
// LED animation is turned off before it even draws its first frame.
13+
expect(digitalSpy).toHaveBeenCalledTimes(3);
14+
expect(pwmSpy).toHaveBeenCalledTimes(3);
15+
16+
expect((digitalSpy.mock.calls[0] as any)[0]).toEqual(0);
17+
expect((digitalSpy.mock.calls[1] as any)[0]).toEqual(0);
18+
expect((digitalSpy.mock.calls[2] as any)[0]).toEqual(0);
19+
20+
expect((pwmSpy.mock.calls[0] as any)[0]).toEqual(130);
21+
expect((pwmSpy.mock.calls[1] as any)[0]).toEqual(130);
22+
expect((pwmSpy.mock.calls[2] as any)[0]).toEqual(134);
23+
});

0 commit comments

Comments
 (0)