Skip to content

Commit c0d9279

Browse files
committed
add multiple PCA9685 example
1 parent 381b581 commit c0d9279

File tree

3 files changed

+116
-1
lines changed

3 files changed

+116
-1
lines changed

examples/AdafruitPCA9685/AdafruitPCA9685.ino

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ using namespace BlenderServoAnimation;
1919
// Total animation frames - see original Blender animation / ik.h
2020
#define FRAMES 100
2121

22-
// Servo object to send positions
22+
// PWM driver instance to set PWM output
2323
Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();
2424

2525
// Callback function which is called whenever a servo needs to be moved
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
Using a struct to map Servos to a PWM driver and channel.
3+
4+
This approach can be useful if you don't want to equate the servo ID with the
5+
PWM board channel or use multiple PCA9685 boards. The Adafruit PCA9685 PWM
6+
Servo Driver Library is used to send the servo positions.
7+
*/
8+
9+
#include "ik.h"
10+
#include <Adafruit_PWMServoDriver.h>
11+
#include <BlenderServoAnimation.h>
12+
13+
// Using the namespace to have short class references (Animation and Servo)
14+
using namespace BlenderServoAnimation;
15+
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+
22+
// PWM driver instances to set PWM output
23+
Adafruit_PWMServoDriver pwmA(0x40);
24+
Adafruit_PWMServoDriver pwmB(0x41);
25+
26+
// Animation object to represent the original Blender animation
27+
Animation animation(FPS, FRAMES);
28+
29+
// We use a struct to map a servo to a PCA9685 board and channel
30+
struct servoMap {
31+
Servo servo;
32+
Adafruit_PWMServoDriver pwm;
33+
byte channel;
34+
};
35+
36+
// Forward declare the callback as it will be referenced in the following array
37+
void setPWM(byte servoID, int position);
38+
39+
// Define an array of servo maps
40+
servoMap servoMaps[] = {
41+
// Servo attached to board A on channel 0
42+
{Servo(0, NeckLeft, setPWM), pwmA, 0},
43+
44+
// Servo attached to board A on channel 0
45+
{Servo(1, NeckRight, setPWM), pwmB, 0},
46+
};
47+
48+
// Calculate the amount of servos so that we can easily extend the array
49+
const byte servoAmount = sizeof(servoMaps) / sizeof(servoMaps[0]);
50+
51+
// Callback function which is called whenever a servo needs to be moved
52+
void setPWM(byte servoID, int position) {
53+
// Iterate through the available servos
54+
for (int i = 0; i < servoAmount; i++) {
55+
// Check if the current servo ID matches the target servo ID
56+
if (servoMaps[i].servo.getID() == servoID) {
57+
// Get the PWM driver instance and channel from the mapping
58+
Adafruit_PWMServoDriver pwm = servoMaps[i].pwm;
59+
byte channel = servoMaps[i].channel;
60+
61+
// Set the current position as PWM output
62+
pwm.setPWM(channel, 0, position);
63+
64+
// Break the loop as we already handled the servo movement
65+
break;
66+
}
67+
}
68+
}
69+
70+
void setup() {
71+
// Dynamically add the Blender servo objects to the animation
72+
for (int i = 0; i < servoAmount; i++) {
73+
animation.addServo(servoMaps[i].servo);
74+
}
75+
76+
// Trigger the animation play mode
77+
animation.play();
78+
79+
// Initialize servo drivers
80+
pwmA.begin();
81+
pwmA.setPWMFreq(60);
82+
pwmB.begin();
83+
pwmB.setPWMFreq(60);
84+
85+
delay(10);
86+
}
87+
88+
void loop() {
89+
// Update the animation state on each loop
90+
animation.run();
91+
}

examples/MultiplePCA9685/ik.h

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
Blender Servo Animation Positions
3+
4+
FPS: 30
5+
Frames: 100
6+
Seconds: 3
7+
Bones: 2
8+
Armature: Armature
9+
File: ik.blend
10+
*/
11+
12+
#include <Arduino.h>
13+
14+
// Servo ID: 0
15+
const int NeckLeft[100] PROGMEM = {
16+
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,
17+
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,
18+
};
19+
20+
// Servo ID: 1
21+
const int NeckRight[100] PROGMEM = {
22+
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,
23+
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,
24+
};

0 commit comments

Comments
 (0)