Skip to content

Commit 96fbe93

Browse files
committed
Merge branch 'feature/web_socket_live_mode' into develop
2 parents 53409f4 + 28bda08 commit 96fbe93

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+497
-265
lines changed

.github/workflows/ci.yml

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ jobs:
2323
name: "Build examples"
2424
runs-on: ubuntu-latest
2525
strategy:
26+
fail-fast: false
2627
matrix:
2728
example:
2829
[
2930
AdafruitPCA9685,
30-
LiveMode,
31+
SerialLiveMode,
32+
WebSocketLiveMode,
3133
MultiplePCA9685,
3234
Show,
3335
StandardServoLib,
@@ -48,9 +50,8 @@ jobs:
4850
run: pip install --upgrade platformio
4951
- name: Build PlatformIO examples
5052
run: |
51-
pio ci examples/${{ matrix.example }} \
52-
--lib=. \
53-
--project-conf=examples/${{ matrix.example }}/platformio.ini
53+
cd examples/${{ matrix.example }}
54+
pio run
5455
lint:
5556
name: "Lint"
5657
runs-on: ubuntu-22.04

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
.vscode/c_cpp_properties.json
44
.vscode/launch.json
55
.vscode/ipch
6+
examples/*/.vscode
7+
examples/*/.gitignore

README.md

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,9 @@ Servo(id, callback, threshold);
6969
| id | byte | Unique servo ID as specified via the Add-on |
7070
| positions | const int[] | Exported positions per frame |
7171
| callback | void (byte, int) | Function to trigger when a servo is moved |
72-
| threshold | byte | Max allowed position diff (default=20) |
72+
| threshold | byte | Max allowed position diff (default=0 / no threshold handling) |
73+
74+
> Note: the threshold is also used to define the speed for moving a servo to its neutral position when stopping an animation.
7375
7476
### Callback Function
7577
@@ -183,12 +185,7 @@ myBlenderAnimation.live(stream);
183185

184186
> Note: the default mode can not be triggered as it is only handled internally.
185187
186-
When calling the `stop` method, it is possible to pass a delay in milliseconds. This delay will be used when the servos are moved to their neutral position during the stop mode. To get to the neutral position, the current position will either be increased or decreased by 1. The delay therefore controls how fast or smooth this movement will take place. The default value for this parameter is `20`.
187-
188-
```ino
189-
myBlenderAnimation.stop(); // Default reset speed applied
190-
myBlenderAnimation.stop(30); // Servos will reset slower
191-
```
188+
When calling the `stop` method, the threshold values of the animation's servos are considered to control how fast or smooth they are moving towards their neutral position. Keep in mind that the servos will not have a threshold value by default which results in the stop mode to immediately trigger the neutral position of the servos. A slower and safer movement can be achieved by setting the threshold values as low as possible with the actual animation still able to run properly.
192189

193190
To use the `live` method, we have to pass a stream instance which will be used for reading serial commands. For example, we can pass `Serial` if we want to use the standard USB connection of an Arduino compatible board:
194191

@@ -199,6 +196,8 @@ void setup() {
199196
}
200197
```
201198

199+
This library also comes with a `LiveStream` class which allows for a more generic way to listen to live commands. For example, it can be used as part of the web socket based live mode for which you can find a dedicated example [here](examples/WebSocketLiveMode).
200+
202201
To get the current animation mode, we can simply call the `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:
203202

204203
```ino

examples/AdafruitPCA9685/AdafruitPCA9685.ino

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@
1313
// Using the namespace to have short class references (Animation and Servo)
1414
using namespace BlenderServoAnimation;
1515

16-
// Frames per second - see original Blender animation / ik.h
17-
#define FPS 30
18-
19-
// Total animation frames - see original Blender animation / ik.h
20-
#define FRAMES 100
21-
2216
// PWM driver instance to set PWM output
2317
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
2418

examples/AdafruitPCA9685/README.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
# Adafruit PCA9685
2+
3+
Using a PCA9685 PWM Servo Driver to animate 2 servos. The animation is based on the IK example of the Blender Servo Animation add-on which resembles a simple neck mechanism.
4+
5+
![test](../../images/arduino-nano-with-PCA9685.png)

examples/AdafruitPCA9685/ik.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@
66
Seconds: 3
77
Bones: 2
88
Armature: Armature
9+
Scene: Scene
910
File: ik.blend
1011
*/
1112

1213
#include <Arduino.h>
1314

15+
const byte FPS = 30;
16+
const int FRAMES = 100;
17+
1418
// Servo ID: 0
15-
const int NeckLeft[100] PROGMEM = {
19+
const int NeckLeft[FRAMES] PROGMEM = {
1620
375, 376, 377, 380, 384, 387, 391, 396, 400, 403, 406, 408, 410, 410, 409, 406, 402, 396, 390, 382, 373, 364, 355, 346, 338, 330, 323, 318, 314, 311, 309, 307, 305, 305, 305, 305, 306, 307, 309, 311, 314, 317, 320, 323, 327, 331, 335, 339, 343, 347,
1721
351, 356, 360, 364, 369, 374, 380, 386, 392, 398, 404, 410, 415, 420, 425, 429, 432, 435, 436, 437, 437, 436, 435, 434, 432, 430, 428, 426, 423, 421, 418, 415, 412, 409, 406, 403, 400, 397, 394, 391, 388, 386, 384, 381, 380, 378, 377, 376, 375, 375,
1822
};
1923

2024
// Servo ID: 1
21-
const int NeckRight[100] PROGMEM = {
25+
const int NeckRight[FRAMES] PROGMEM = {
2226
375, 376, 379, 383, 388, 394, 401, 409, 417, 426, 434, 443, 450, 457, 463, 468, 471, 472, 471, 469, 466, 462, 457, 452, 447, 441, 437, 432, 428, 424, 420, 416, 411, 407, 402, 398, 394, 389, 384, 380, 375, 370, 366, 361, 356, 352, 347, 342, 337, 333,
2327
328, 324, 319, 315, 312, 309, 308, 307, 306, 306, 306, 307, 308, 309, 310, 311, 312, 313, 313, 313, 313, 314, 315, 316, 318, 320, 322, 324, 327, 329, 332, 335, 338, 341, 344, 347, 350, 353, 356, 359, 362, 364, 366, 369, 370, 372, 373, 374, 375, 375,
2428
};

examples/AdafruitPCA9685/platformio.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
[platformio]
2+
src_dir = ./
3+
14
[env]
25
lib_deps =
36
adafruit/Adafruit PWM Servo Driver Library@^2.4.1
7+
BlenderServoAnimation=symlink://../../
48

59
[env:uno]
610
board = uno

examples/LiveMode/platformio.ini

Lines changed: 0 additions & 18 deletions
This file was deleted.

examples/MultiplePCA9685/MultiplePCA9685.ino

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,6 @@
1313
// Using the namespace to have short class references (Animation and Servo)
1414
using namespace BlenderServoAnimation;
1515

16-
// Frames per second - see original Blender animation / ik.h
17-
#define FPS 30
18-
19-
// Total animation frames - see original Blender animation / ik.h
20-
#define FRAMES 100
21-
2216
// PWM driver instances to set PWM output
2317
Adafruit_PWMServoDriver pwmA(0x40);
2418
Adafruit_PWMServoDriver pwmB(0x41);
@@ -36,12 +30,12 @@ struct servoMap {
3630
// Forward declare the callback as it will be referenced in the following array
3731
void setPWM(byte servoID, int position);
3832

39-
// Define an array of servo maps
33+
// Define an array of servo mapsf
4034
servoMap servoMaps[] = {
4135
// Servo attached to board A on channel 0
4236
{Servo(0, NeckLeft, setPWM), pwmA, 0},
4337

44-
// Servo attached to board A on channel 0
38+
// Servo attached to board B on channel 0
4539
{Servo(1, NeckRight, setPWM), pwmB, 0},
4640
};
4741

examples/MultiplePCA9685/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Multiple PCA9685
2+
3+
Using two PCA9685 PWM Servo Drivers to animate 2 servos. The animation is based on the IK example of the Blender Servo Animation add-on which resembles a simple neck mechanism.
4+
5+
Note that the A0 address jumper has to be soldered on the second driver board. This setup can easily be extended to animate up to 32 servos. If even more servos are needed, you can also add more driver boards to the chain.
6+
7+
![test](../../images/arduino-nano-with-2-PCA9685.png)

examples/MultiplePCA9685/ik.h

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,19 +6,23 @@
66
Seconds: 3
77
Bones: 2
88
Armature: Armature
9+
Scene: Scene
910
File: ik.blend
1011
*/
1112

1213
#include <Arduino.h>
1314

15+
const byte FPS = 30;
16+
const int FRAMES = 100;
17+
1418
// Servo ID: 0
15-
const int NeckLeft[100] PROGMEM = {
19+
const int NeckLeft[FRAMES] PROGMEM = {
1620
375, 376, 377, 380, 384, 387, 391, 396, 400, 403, 406, 408, 410, 410, 409, 406, 402, 396, 390, 382, 373, 364, 355, 346, 338, 330, 323, 318, 314, 311, 309, 307, 305, 305, 305, 305, 306, 307, 309, 311, 314, 317, 320, 323, 327, 331, 335, 339, 343, 347,
1721
351, 356, 360, 364, 369, 374, 380, 386, 392, 398, 404, 410, 415, 420, 425, 429, 432, 435, 436, 437, 437, 436, 435, 434, 432, 430, 428, 426, 423, 421, 418, 415, 412, 409, 406, 403, 400, 397, 394, 391, 388, 386, 384, 381, 380, 378, 377, 376, 375, 375,
1822
};
1923

2024
// Servo ID: 1
21-
const int NeckRight[100] PROGMEM = {
25+
const int NeckRight[FRAMES] PROGMEM = {
2226
375, 376, 379, 383, 388, 394, 401, 409, 417, 426, 434, 443, 450, 457, 463, 468, 471, 472, 471, 469, 466, 462, 457, 452, 447, 441, 437, 432, 428, 424, 420, 416, 411, 407, 402, 398, 394, 389, 384, 380, 375, 370, 366, 361, 356, 352, 347, 342, 337, 333,
2327
328, 324, 319, 315, 312, 309, 308, 307, 306, 306, 306, 307, 308, 309, 310, 311, 312, 313, 313, 313, 313, 314, 315, 316, 318, 320, 322, 324, 327, 329, 332, 335, 338, 341, 344, 347, 350, 353, 356, 359, 362, 364, 366, 369, 370, 372, 373, 374, 375, 375,
2428
};

examples/MultiplePCA9685/platformio.ini

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
1+
[platformio]
2+
src_dir = ./
3+
14
[env]
25
lib_deps =
36
adafruit/Adafruit PWM Servo Driver Library@^2.4.1
7+
BlenderServoAnimation=symlink://../../
48

59
[env:uno]
610
board = uno

examples/SerialLiveMode/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Serial Live Mode
2+
3+
Sending live servo positions via serial commands.
4+
5+
This example requires a USB connection to your PC and a running Blender instance with the Blender Servo Animation Add-on. After starting the live mode by connecting to the micro controller via serial, you can move the servo in real time via Blender.
6+
7+
![test](../../images/arduino-nano-with-servo.png)

examples/LiveMode/LiveMode.ino renamed to examples/SerialLiveMode/SerialLiveMode.ino

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,20 @@
77
*/
88

99
#include <BlenderServoAnimation.h>
10+
11+
#ifdef ARDUINO_ARCH_ESP32
12+
#include <ESP32Servo.h>
13+
#else
1014
#include <Servo.h>
15+
#endif
1116

1217
// Servo object to send positions
1318
Servo myServo;
1419

1520
// Callback function which is called whenever a servo needs to be moved
16-
void move(byte servoID, int angle) {
17-
// Ignore the servoID (there is only one servo) and write the current angle
18-
myServo.write(angle);
21+
void move(byte servoID, int position) {
22+
// Ignore the servoID (there is only one servo) and write the current position
23+
myServo.writeMicroseconds(position);
1924
}
2025

2126
// Animation object to manage the servos
@@ -28,8 +33,8 @@ BlenderServoAnimation::Servo myBlenderServo(0, move);
2833
void setup() {
2934
Serial.begin(115200);
3035

31-
// Attach the servo to pin 9
32-
myServo.attach(9);
36+
// Attach the servo to pin 12
37+
myServo.attach(12);
3338

3439
// Add the Blender servo object to the animation
3540
animation.addServo(myBlenderServo);
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
[platformio]
2+
src_dir = ./
3+
4+
[env]
5+
framework = arduino
6+
7+
[atmelavr_base]
8+
platform = atmelavr
9+
lib_deps =
10+
arduino-libraries/Servo@^1.1.8
11+
BlenderServoAnimation=symlink://../../
12+
13+
[env:uno]
14+
extends = atmelavr_base
15+
board = uno
16+
17+
[env:ATmega2560]
18+
extends = atmelavr_base
19+
board = ATmega2560
20+
21+
[env:nanoatmega328]
22+
extends = atmelavr_base
23+
board = nanoatmega328
24+
25+
[env:esp32dev]
26+
platform = espressif32
27+
board = esp32dev
28+
lib_deps =
29+
madhephaestus/ESP32Servo@^0.13.0
30+
BlenderServoAnimation=symlink://../../

examples/Show/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Show
2+
3+
Setting up a show consisting of 2 animations.
4+
5+
By default, the 2 animations will be played synchronously in a loop.
6+
7+
![test](../../images/arduino-nano-with-servo.png)

examples/Show/Show.ino

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,20 @@
99
#include "scene-a.h"
1010
#include "scene-b.h"
1111
#include <BlenderServoAnimation.h>
12+
13+
#ifdef ARDUINO_ARCH_ESP32
14+
#include <ESP32Servo.h>
15+
#else
1216
#include <Servo.h>
17+
#endif
1318

1419
// Servo object to send positions
1520
Servo myServo;
1621

1722
// Callback function which is called whenever a servo needs to be moved
18-
void move(byte servoID, int angle) {
19-
// Ignore the servoID (there is only one servo) and write the current angle
20-
myServo.write(angle);
23+
void move(byte servoID, int position) {
24+
// Ignore the servoID (there is only one servo) and write the current position
25+
myServo.writeMicroseconds(position);
2126
}
2227

2328
// Show object to manage all Blender animations
@@ -32,8 +37,8 @@ BlenderServoAnimation::Servo myBlenderServoA(0, SceneA::Bone, move);
3237
BlenderServoAnimation::Servo myBlenderServoB(0, SceneB::Bone, move);
3338

3439
void setup() {
35-
// Attach the servo to pin 9
36-
myServo.attach(9);
40+
// Attach the servo to pin 12
41+
myServo.attach(12);
3742

3843
// Add the Blender servo objects to the animations
3944
animationA.addServo(myBlenderServoA);

examples/Show/platformio.ini

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,30 @@
1+
[platformio]
2+
src_dir = ./
3+
14
[env]
5+
framework = arduino
6+
7+
[atmelavr_base]
8+
platform = atmelavr
29
lib_deps =
310
arduino-libraries/Servo@^1.1.8
11+
BlenderServoAnimation=symlink://../../
412

513
[env:uno]
14+
extends = atmelavr_base
615
board = uno
7-
platform = atmelavr
8-
framework = arduino
916

1017
[env:ATmega2560]
18+
extends = atmelavr_base
1119
board = ATmega2560
12-
platform = atmelavr
13-
framework = arduino
1420

1521
[env:nanoatmega328]
22+
extends = atmelavr_base
1623
board = nanoatmega328
17-
platform = atmelavr
18-
framework = arduino
24+
25+
[env:esp32dev]
26+
platform = espressif32
27+
board = esp32dev
28+
lib_deps =
29+
madhephaestus/ESP32Servo@^0.13.0
30+
BlenderServoAnimation=symlink://../../

examples/Show/scene-a.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ const int FRAMES = 100;
1919

2020
// Servo ID: 0
2121
const int Bone[FRAMES] PROGMEM = {
22-
90, 90, 89, 89, 88, 87, 86, 84, 83, 81, 80, 78, 76, 74, 72, 70, 68, 65, 63, 61, 59, 57, 55, 54, 52, 51, 49, 48, 47, 46, 46, 45, 45, 45, 46, 47, 49, 51, 53, 55, 58, 61, 65, 68, 72, 76, 80, 84, 88, 92,
23-
96, 100, 104, 108, 112, 115, 119, 122, 125, 127, 129, 131, 133, 134, 135, 135, 135, 135, 134, 133, 132, 131, 130, 129, 127, 126, 124, 122, 120, 118, 116, 114, 112, 111, 109, 107, 105, 103, 101, 99, 98, 96, 95, 94, 93, 92, 91, 90, 90, 90,
22+
1472, 1473, 1477, 1483, 1492, 1502, 1515, 1529, 1544, 1562, 1580, 1599, 1619, 1640, 1661, 1682, 1704, 1726, 1747, 1768, 1789, 1809, 1828, 1846, 1864, 1879, 1893, 1906, 1916, 1925, 1931, 1935, 1936, 1934, 1926, 1914, 1898, 1879, 1855, 1828, 1799, 1767, 1732, 1695, 1657, 1617, 1577, 1535, 1493, 1451,
23+
1409, 1367, 1327, 1287, 1249, 1212, 1177, 1145, 1116, 1089, 1065, 1046, 1030, 1018, 1010, 1008, 1009, 1013, 1018, 1026, 1035, 1046, 1059, 1073, 1088, 1105, 1122, 1141, 1160, 1179, 1199, 1220, 1240, 1260, 1281, 1301, 1320, 1339, 1358, 1375, 1392, 1407, 1421, 1434, 1445, 1454, 1462, 1467, 1471, 1472,
2424
};
2525

2626
} // namespace SceneA

examples/Show/scene-b.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ const int FRAMES = 200;
1919

2020
// Servo ID: 0
2121
const int Bone[FRAMES] PROGMEM = {
22-
90, 90, 90, 90, 90, 90, 90, 89, 89, 89, 89, 88, 88, 88, 88, 87, 87, 86, 86, 86, 85, 85, 84, 84, 83, 83, 82, 82, 81, 81, 80, 80, 79, 78, 78, 77, 76, 76, 75, 75, 74, 73, 73, 72, 71, 71, 70, 69, 69, 68,
23-
67, 66, 66, 65, 64, 64, 63, 62, 62, 61, 60, 60, 59, 59, 58, 57, 57, 56, 55, 55, 54, 54, 53, 53, 52, 52, 51, 51, 50, 50, 49, 49, 49, 48, 48, 47, 47, 47, 47, 46, 46, 46, 46, 45, 45, 45, 45, 45, 45, 45,
24-
45, 45, 45, 45, 45, 45, 46, 46, 46, 46, 47, 47, 47, 47, 48, 48, 48, 49, 49, 50, 50, 51, 51, 52, 52, 53, 53, 54, 54, 55, 55, 56, 56, 57, 58, 58, 59, 60, 60, 61, 61, 62, 63, 63, 64, 65, 65, 66, 67, 68,
25-
68, 69, 70, 70, 71, 72, 72, 73, 74, 74, 75, 75, 76, 77, 77, 78, 79, 79, 80, 80, 81, 81, 82, 82, 83, 83, 84, 84, 85, 85, 86, 86, 87, 87, 87, 88, 88, 88, 88, 89, 89, 89, 89, 90, 90, 90, 90, 90, 90, 90,
22+
1472, 1472, 1473, 1473, 1474, 1475, 1477, 1479, 1481, 1483, 1485, 1488, 1491, 1494, 1497, 1501, 1504, 1508, 1512, 1517, 1521, 1526, 1531, 1536, 1541, 1546, 1551, 1557, 1562, 1568, 1574, 1580, 1586, 1592, 1599, 1605, 1611, 1618, 1625, 1631, 1638, 1645, 1652, 1659, 1666, 1672, 1679, 1686, 1693, 1700,
23+
1708, 1715, 1722, 1729, 1736, 1742, 1749, 1756, 1763, 1770, 1777, 1783, 1790, 1797, 1803, 1809, 1816, 1822, 1828, 1834, 1840, 1846, 1851, 1857, 1862, 1867, 1872, 1877, 1882, 1887, 1891, 1896, 1900, 1904, 1907, 1911, 1914, 1917, 1920, 1923, 1925, 1927, 1929, 1931, 1933, 1934, 1935, 1935, 1936, 1936,
24+
1936, 1935, 1935, 1934, 1933, 1931, 1930, 1928, 1925, 1923, 1920, 1918, 1915, 1911, 1908, 1904, 1900, 1896, 1892, 1888, 1883, 1878, 1874, 1869, 1864, 1858, 1853, 1847, 1842, 1836, 1830, 1824, 1818, 1812, 1805, 1799, 1792, 1786, 1779, 1773, 1766, 1759, 1752, 1746, 1739, 1732, 1725, 1718, 1711, 1704,
25+
1697, 1690, 1683, 1676, 1669, 1662, 1656, 1649, 1642, 1635, 1629, 1622, 1616, 1609, 1603, 1596, 1590, 1584, 1578, 1572, 1566, 1561, 1555, 1550, 1544, 1539, 1534, 1530, 1525, 1520, 1516, 1512, 1508, 1504, 1500, 1497, 1493, 1490, 1488, 1485, 1483, 1480, 1478, 1477, 1475, 1474, 1473, 1473, 1472, 1472,
2626
};
2727

2828
} // namespace SceneB

0 commit comments

Comments
 (0)