Hello everyone!
I am developing a project that involves the recognition of a person's silhouettes through the Kinect and than controls 64 engines with Arduino. To do this I'm using 4 PCA9685 boards with 64 SG90 servomotors.
The code for the Kinect is made with Processing where in practice it generates a string of 64 numbers (0 or 1) every 2 seconds that is sent to the Arduino through the serial port. The Arduino reads this string and runs the corresponding engines accordingly.
The piece of code works perfectly by connecting only one PCA9685 board.
The problem now is the connection of several boards: after making the connection the boards do not work, or rather they work but only individually, whether the external power is only on the first board or that every board is attached to the power supply (however always with the same transformer, 5V-10A)(may be this the problem?) . What I think is that the problem is the power supply but not having specific knowledge about it I hope to find someone who can help me.
Has anyone ever encountered the same problems by connecting multiple PCA9685 boards?
Could there be errors in the code?
Thank you!
This is the Processing code that with the Kinect generates a string every 2 seconds and sends it to Arduino
import org.openkinect.freenect.*;
import org.openkinect.freenect2.*;
import org.openkinect.processing.*;
import org.openkinect.tests.*;
import processing.serial.*;
Serial myPort; //Nome porta seriale
Kinect kinect; //Nome kinect
PImage img;
int row = 3; //NUMERO DI RIGHE DA IMPOSTARE
int col = 5; //NUMERO DI COLONNE DA IMPOSTARE
int nPixel = row*col; //Totale tasselli
int skipx = 512/col;
int skipy = 424/row;
void setup() {
size(512, 424);
kinect = new Kinect(this);
kinect.initDepth();
myPort = new Serial(this, "COM9", 9600);
img = createImage(kinect.width, kinect.height, RGB);
}
void draw() {
frameRate(30);
background(0);
img.loadPixels();
immagineKinect();
byte[] stringa = new byte [nPixel];
for (int r=0; r<row; r++) {
for (int i=r*col; i<col*r+col; i++) {
color pixel = get((i-col*r)*skipx+skipx/2,r*skipy+skipy/2);
if (red(pixel) == 255 && green(pixel) == 0 && blue(pixel) == 150) {
stringa [i] = 1;
}else{
//stringa [i] = 0;
}
}
}
myPort.write(stringa);
println(stringa);
delay(2000);
img.updatePixels();
}
void immagineKinect() {
int[] depth = kinect.getRawDepth();
for (int x = 0; x < kinect.width; x+=skipx) {
for (int y = 0; y < kinect.height; y+=skipy) {
int offset = x + y * kinect.width;
int b = depth[offset];
if (b > 400 && b < 800) {
fill(255,0,150);
rect(x,y,skipx,skipy);
//delay(2);
}else{
fill(0);
rect(x,y,skipx,skipy);
delay(15); //metà del ritardo del motore
}
}
}
}
This is the Arduino code that reads the string and communicates with the PCA9685 boards
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>
Adafruit_PWMServoDriver pwm1 = Adafruit_PWMServoDriver(0x40);
Adafruit_PWMServoDriver pwm2 = Adafruit_PWMServoDriver(0x41);
Adafruit_PWMServoDriver pwm3 = Adafruit_PWMServoDriver(0x42);
Adafruit_PWMServoDriver pwm4 = Adafruit_PWMServoDriver(0x43);
#define SERVOMIN 230 // this is the 'minimum' pulse length count (out of 4096)
#define SERVOMAX 500 // this is the 'maximum' pulse length count (out of 4096)
const int row = 4;
const int col = 16;
const int num_iter = 64; // Numero di tasselli e numero di bytes
byte bytes[num_iter];
byte rot[num_iter];
void setup () {
Serial.begin(9600);
pwm1.begin();
pwm1.setPWMFreq(60); // Analog servos run at ~60 Hz updates
pwm2.begin();
pwm2.setPWMFreq(60);
pwm3.begin();
pwm3.setPWMFreq(60);
pwm4.begin();
pwm4.setPWMFreq(60);
delay(10);
}
void loop() {
}
void serialEvent() {
while (Serial.available()) {
for (int n=0; n <num_iter; n++) {
bytes[n] = Serial.read();
delay(2);
}
for (int n=0; n < 16; n++) {
if (bytes[n] == 1 && rot[n] == 0) {
SetservoMax(n);
rot[n] = 1;
}
else if (bytes[n] == 0 && rot[n] == 1) {
SetservoMin(n);
rot[n] = 0;
}
delay(20);
}
for (int n=16; n < 32; n++) {
if (bytes[n] == 1 && rot[n] == 0) {
SetservoMax1(n-16);
rot[n] = 1;
}
else if (bytes[n] == 0 && rot[n] == 1) {
SetservoMin1(n-16);
rot[n] = 0;
}
delay(20);
}
for (int n=32; n < 48; n++) {
if (bytes[n] == 1 && rot[n] == 0) {
SetservoMax2(n-32);
rot[n] = 1;
}
else if (bytes[n] == 0 && rot[n] == 1) {
SetservoMin2(n-32);
rot[n] = 0;
}
delay(20);
}
for (int n=48; n < 64; n++) {
if (bytes[n] == 1 && rot[n] == 0) {
SetservoMax3(n-48);
rot[n] = 1;
}
else if (bytes[n] == 0 && rot[n] == 1) {
SetservoMin3(n);
rot[n] = 0;
}
delay(20);
}
}
}
void SetservoMax (int servoIndex) {
pwm1.setPWM(servoIndex, 0, SERVOMAX);
}
void SetservoMin (int servoIndex) {
pwm1.setPWM(servoIndex, 0, SERVOMIN);
}
void SetservoMax1 (int servoIndex1) {
pwm2.setPWM(servoIndex1, 0, SERVOMAX);
}
void SetservoMin1 (int servoIndex) {
pwm2.setPWM(servoIndex, 0, SERVOMIN);
}
void SetservoMax2 (int servoIndex) {
pwm3.setPWM(servoIndex, 0, SERVOMAX);
}
void SetservoMin2 (int servoIndex) {
pwm3.setPWM(servoIndex, 0, SERVOMIN);
}
void SetservoMax3 (int servoIndex) {
pwm4.setPWM(servoIndex, 0, SERVOMAX);
}
void SetservoMin3 (int servoIndex) {
pwm4.setPWM(servoIndex, 0, SERVOMIN);
}
The scheme of the components is attached.