Skip to content

Commit 53409f4

Browse files
committed
Merge branch 'feature/show' into develop
2 parents e387567 + 040b494 commit 53409f4

File tree

39 files changed

+2408
-485
lines changed

39 files changed

+2408
-485
lines changed

.github/workflows/ci.yml

Lines changed: 74 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -7,59 +7,85 @@ jobs:
77
name: "Build"
88
runs-on: ubuntu-latest
99
steps:
10-
- uses: actions/checkout@v3
11-
- name: Build library ZIP
12-
run: |
13-
mkdir BlenderServoAnimation
14-
cp -R src examples library.properties README.md LICENSE BlenderServoAnimation
15-
zip -r blender_servo_animation_arduino_library BlenderServoAnimation
16-
- name: Archive library ZIP
17-
uses: actions/upload-artifact@v3
18-
with:
19-
name: blender_servo_animation_arduino_library.zip
20-
path: |
21-
blender_servo_animation_arduino_library.zip
10+
- uses: actions/checkout@v3
11+
- name: Create library ZIP
12+
run: |
13+
mkdir BlenderServoAnimation
14+
cp -R src examples library.properties README.md LICENSE BlenderServoAnimation
15+
zip -r blender_servo_animation_arduino_library BlenderServoAnimation
16+
- name: Archive library ZIP
17+
uses: actions/upload-artifact@v3
18+
with:
19+
name: blender_servo_animation_arduino_library.zip
20+
path: |
21+
blender_servo_animation_arduino_library.zip
22+
build-examples:
23+
name: "Build examples"
24+
runs-on: ubuntu-latest
25+
strategy:
26+
matrix:
27+
example:
28+
[
29+
AdafruitPCA9685,
30+
LiveMode,
31+
MultiplePCA9685,
32+
Show,
33+
StandardServoLib,
34+
SwitchModeButton,
35+
]
36+
steps:
37+
- uses: actions/checkout@v3
38+
- uses: actions/cache@v3
39+
with:
40+
path: |
41+
~/.cache/pip
42+
~/.platformio/.cache
43+
key: ${{ runner.os }}-pio
44+
- uses: actions/setup-python@v4
45+
with:
46+
python-version: "3.10"
47+
- name: Install PlatformIO Core
48+
run: pip install --upgrade platformio
49+
- name: Build PlatformIO examples
50+
run: |
51+
pio ci examples/${{ matrix.example }} \
52+
--lib=. \
53+
--project-conf=examples/${{ matrix.example }}/platformio.ini
2254
lint:
2355
name: "Lint"
2456
runs-on: ubuntu-22.04
2557
steps:
26-
- uses: actions/checkout@v3
27-
- name: Install dependencies
28-
run: |
29-
sudo apt-get update
30-
sudo apt-get install --no-install-recommends -y clang-format-13
31-
- name: Lint with clang-format
32-
run: |
33-
find src test -regex '.*\.\(cpp\|h\)' -exec clang-format-13 --dry-run --Werror {} \;
34-
find examples -regex '.*\.ino' -exec clang-format-13 --dry-run --Werror {} \;
35-
- name: Lint with arduino-lint
36-
uses: arduino/arduino-lint-action@v1
37-
with:
38-
library-manager: update
58+
- uses: actions/checkout@v3
59+
- name: Lint with clang-format
60+
uses: jidicula/[email protected]
61+
with:
62+
exclude-regex: 'examples\/.+\/.+\.h'
63+
- name: Lint with arduino-lint
64+
uses: arduino/arduino-lint-action@v1
65+
with:
66+
library-manager: update
3967
test:
4068
name: "Test"
4169
runs-on: ubuntu-latest
42-
env:
43-
LD_LIBRARY_PATH: /home/runner/.platformio/packages/tool-simavr/lib
4470
steps:
45-
- uses: actions/checkout@v3
46-
- name: Cache PlatformIO directory
47-
uses: actions/cache@v3
48-
with:
49-
path: /home/runner/.platformio
50-
key: platformio-dir
51-
- name: Set up Python 3.10
52-
uses: actions/setup-python@v3
53-
with:
54-
python-version: "3.10"
55-
cache: 'pip'
56-
cache-dependency-path: requirements-dev.txt
57-
- name: Install dependencies
58-
run: |
59-
sudo apt-get update
60-
sudo apt-get install --no-install-recommends -y libelf-dev
61-
python -m pip install --upgrade pip
62-
pip install -r requirements-dev.txt
63-
- name: Run tests with platformio
64-
run: |
65-
pio test --without-uploading
71+
- uses: actions/checkout@v3
72+
- name: Cache PlatformIO directory
73+
uses: actions/cache@v3
74+
with:
75+
path: /home/runner/.platformio
76+
key: platformio-dir
77+
- name: Set up Python 3.10
78+
uses: actions/setup-python@v4
79+
with:
80+
python-version: "3.10"
81+
cache: "pip"
82+
cache-dependency-path: requirements-dev.txt
83+
- name: Install dependencies
84+
run: |
85+
sudo apt-get update
86+
sudo apt-get install --no-install-recommends -y libelf-dev
87+
python -m pip install --upgrade pip
88+
pip install -r requirements-dev.txt
89+
- name: Run tests with platformIO
90+
run: |
91+
pio test -e native

README.md

Lines changed: 121 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
This library helps to control servos based on an exported Blender animation. It is specifically designed to work with the [Blender Servo Animation Add-on](https://github.com/timhendriks93/blender-servo-animation).
44

5+
[![Continuous Integration](https://github.com/timhendriks93/blender-servo-animation-arduino/actions/workflows/ci.yml/badge.svg)](https://github.com/timhendriks93/blender-servo-animation-arduino/actions/workflows/ci.yml)
6+
57
## Installation
68

79
Please refer to the official [Arduino documentation](https://docs.arduino.cc/software/ide-v1/tutorials/installing-libraries) to see how you can install this library.
@@ -27,6 +29,9 @@ BlenderServoAnimation::Servo(...);
2729

2830
// Blender animation object
2931
BlenderServoAnimation::Animation(...);
32+
33+
// Blender show object
34+
BlenderServoAnimation::Show();
3035
```
3136
3237
When not using the standard servo library, you can use the namespace and therefore skip the namespace prefix:
@@ -39,6 +44,9 @@ Servo(...);
3944
4045
// Blender animation object
4146
Animation(...);
47+
48+
// Blender show object
49+
Show();
4250
```
4351

4452
## Defining Servos
@@ -125,20 +133,21 @@ This is usually done inside the `setup` function after the servo objects have be
125133
Alternatively, we can also create an array of servos and call the `addServos` method instead:
126134

127135
```ino
136+
Animation myBlenderAnimation(30, 1000);
137+
128138
Servo myBlenderServos[] = {
129139
Servo(0, BoneA, move),
130140
Servo(1, BoneB, move),
131141
Servo(2, BoneC, move),
132-
...
133142
}
134143

135-
Animation myBlenderAnimation(30, 1000);
136-
137144
void setup() {
138-
myBlenderAnimation.addServos(myBlenderServos);
145+
myBlenderAnimation.addServos(myBlenderServos, 3);
139146
}
140147
```
141148
149+
> Note: the `addServos` function expects the amount of servos in the array to be passed via the second argument.
150+
142151
### Updating the Animation State
143152
144153
The animation needs to be triggered regularly in order to update its state and check if any servos have to be moved. We therefore need to call the `run` method during each `loop`:
@@ -210,12 +219,118 @@ On top of manually checking the animation mode, we can also register a callback
210219

211220
```ino
212221
void modeChanged(byte prevMode, byte newMode) {
213-
// Do something (e.g. using another switch)
222+
// Do something (e.g. using a switch statement)
214223
}
215224

216225
void setup() {
217226
myBlenderAnimation.onModeChange(modeChanged);
218227
}
219228
```
220229
221-
The [SwitchModeButton example](examples/SwitchModeButton) shows how to combine all mode methods to control an animation based on a single button. Make sure to also check out the other [examples](examples) to get started quickly.
230+
The [SwitchModeButton example](examples/SwitchModeButton) shows how to combine all mode methods to control an animation based on a single button.
231+
232+
## Defining a Show
233+
234+
A show object allows you to combine multiple animations and control their play back in an easy way. You can also think of a show as a playlist of animations. Since the show object does not expect any arguments, the initialization is very simple:
235+
236+
```ino
237+
Show myBlenderShow;
238+
```
239+
240+
### Registering Animations
241+
242+
After defining some animations as shown above, we have to register them to the show object by calling the `addAnimation` method:
243+
244+
```ino
245+
myBlenderShow.addAnimation(myBlenderAnimation);
246+
```
247+
248+
This is usually done inside the `setup` function after the animation and servo objects have been defined globally (outside of any function like `setup` or `loop`).
249+
250+
Alternatively, we can also create an array of animations and call the `addAnimations` method instead:
251+
252+
```ino
253+
Show myBlenderShow;
254+
255+
Animation animations[3] = {
256+
{FPS, FRAMES_A},
257+
{FPS, FRAMES_B},
258+
{FPS, FRAMES_C},
259+
};
260+
261+
void setup() {
262+
myBlenderShow.addAnimations(animations, 3);
263+
}
264+
```
265+
266+
> Note: the `addAnimations` function expects the amount of servos in the array to be passed via the second argument.
267+
268+
### Updating the Show State
269+
270+
Just like single animations, we have to regularly trigger the show instance in order to update its state and internally handle the servo movement of the current animation. We therefore need to call the `run` method during each `loop`:
271+
272+
```ino
273+
void loop() {
274+
myBlenderShow.run();
275+
}
276+
```
277+
278+
### Show Modes
279+
280+
The show modes are similar to the previously mentioned animation modes. In addition to those, there are various playback modes to handle a multitude of animations.
281+
282+
Just like with animation modes, a show will be in the default mode at first. The following table is focusing on the differences and additions of the show modes compared to the animation modes:
283+
284+
| Constant | Method | Description |
285+
|----------|--------|-------------|
286+
| MODE_PLAY | play() | Start or resume playing the show once |
287+
| MODE_PLAY_SINGLE | playSingle(index) | Start or resume playing a single animation once |
288+
| MODE_PLAY_RANDOM | playRandom() | Start or resume randomly playing animations of the show |
289+
290+
The modes can be changed or triggered by calling the respective methods on the show object:
291+
292+
```ino
293+
myBlenderShow.play();
294+
myBlenderShow.playSingle(index);
295+
myBlenderShow.playRandom();
296+
myBlenderShow.pause();
297+
myBlenderShow.loop();
298+
myBlenderShow.stop();
299+
myBlenderShow.live(stream);
300+
```
301+
302+
> Note: the default mode can not be triggered as it is only handled internally.
303+
304+
To get the current show mode, we can again call a `getMode` method. This will return a `byte` representing one of the mode constants mentioned in the table above. We can then compare the return value to those constants to act according to the current mode:
305+
306+
```ino
307+
byte currentMode = myBlenderShow.getMode();
308+
309+
switch (currentMode) {
310+
case Show::MODE_DEFAULT:
311+
// Do something
312+
break;
313+
case Show::MODE_PLAY:
314+
// Do something else
315+
break;
316+
...
317+
}
318+
```
319+
320+
> Note: The actual byte values of the show modes differ from the animation modes. For example, `Show::MODE_PAUSE != Animation::MODE_PAUSE`.
321+
322+
As with animations, we can also register an `onModeChange` callback function:
323+
324+
```ino
325+
void modeChanged(byte prevMode, byte newMode) {
326+
// Do something (e.g. using a switch statement)
327+
}
328+
329+
void setup() {
330+
myBlenderShow.onModeChange(modeChanged);
331+
}
332+
```
333+
334+
There is also a specific [Show example](examples/Show) to illustrate a simple setup based on 2 different animations.
335+
336+
Make sure to also check out the other [examples](examples) to get started more quickly.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[env]
2+
lib_deps =
3+
adafruit/Adafruit PWM Servo Driver Library@^2.4.1
4+
5+
[env:uno]
6+
board = uno
7+
platform = atmelavr
8+
framework = arduino
9+
10+
[env:ATmega2560]
11+
board = ATmega2560
12+
platform = atmelavr
13+
framework = arduino
14+
15+
[env:nanoatmega328]
16+
board = nanoatmega328
17+
platform = atmelavr
18+
framework = arduino
19+
20+
[env:esp32dev]
21+
board = esp32dev
22+
platform = espressif32
23+
framework = arduino

examples/LiveMode/platformio.ini

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
[env]
2+
lib_deps =
3+
arduino-libraries/Servo@^1.1.8
4+
5+
[env:uno]
6+
board = uno
7+
platform = atmelavr
8+
framework = arduino
9+
10+
[env:ATmega2560]
11+
board = ATmega2560
12+
platform = atmelavr
13+
framework = arduino
14+
15+
[env:nanoatmega328]
16+
board = nanoatmega328
17+
platform = atmelavr
18+
framework = arduino
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
[env]
2+
lib_deps =
3+
adafruit/Adafruit PWM Servo Driver Library@^2.4.1
4+
5+
[env:uno]
6+
board = uno
7+
platform = atmelavr
8+
framework = arduino
9+
10+
[env:ATmega2560]
11+
board = ATmega2560
12+
platform = atmelavr
13+
framework = arduino
14+
15+
[env:nanoatmega328]
16+
board = nanoatmega328
17+
platform = atmelavr
18+
framework = arduino
19+
20+
[env:esp32dev]
21+
board = esp32dev
22+
platform = espressif32
23+
framework = arduino

0 commit comments

Comments
 (0)