so I got the boards, and I ran the code below and it works:
#include <Bela.h>
#include <pca9685.h>
PCA9685 pwm1;
PCA9685 pwm2;
PCA9685 pwm3;
bool setup(BelaContext* context, void* userData) {
pwm1.begin(0x40);
pwm2.begin(0x41);
pwm3.begin(0x42);
pwm1.setPWM(15, 0);
pwm2.setPWM(15, 0);
pwm3.setPWM(15, 0);
usleep(1000000);
pwm1.setPWM(15, 4000);
pwm2.setPWM(15, 4000);
pwm3.setPWM(15, 4000);
usleep(1000000);
for(unsigned int n = 0; n < 10; ++n)
{
pwm1.setPWM(15, 0);
pwm2.setPWM(15, 4000);
pwm3.setPWM(15, 4000);
usleep(300000);
pwm1.setPWM(15, 4000);
pwm2.setPWM(15, 0);
pwm3.setPWM(15, 4000);
usleep(300000);
pwm1.setPWM(15, 4000);
pwm2.setPWM(15, 4000);
pwm3.setPWM(15, 0);
usleep(300000);
}
pwm1.setPWM(15, 4095);
pwm2.setPWM(15, 4095);
pwm3.setPWM(15, 4095);
return true;
}
void render(BelaContext* context, void* userData) {
}
void cleanup(BelaContext* context, void* userData) {
}
see proof here:
The only problems I encountered were weak/wobbly "jumpers" for the addresses: I don't have a soldering iron here, so I just taped some stranded wire across the pads. Initially, I was cutting the plastic sleeve off. This proved to be fairly unreliable, that a given board would occasionally (often!) change address. When that happened while the program was running, I would then get the 121 error. However, even if one of the boards failed (because of wrong address), the others would still work, and when two boards were on the same address, you could just address them both in one go!
However, now that I leave the sleeve in place, as in the pic below, this is much more reliable:
I tried running the above also in an AuxiliaryTask
, and it all works as expected. E.g.:
#include <Bela.h>
#include <pca9685.h>
PCA9685 pwm1;
PCA9685 pwm2;
PCA9685 pwm3;
void auxFunc(void*)
{
pwm1.setPWM(15, 0);
pwm2.setPWM(15, 0);
pwm3.setPWM(15, 0);
usleep(1000000);
pwm1.setPWM(15, 4000);
pwm2.setPWM(15, 4000);
pwm3.setPWM(15, 4000);
usleep(1000000);
for(unsigned int n = 0; n < 10; ++n)
{
if(gShouldStop)
return;
pwm1.setPWM(15, 0);
pwm2.setPWM(15, 4000);
pwm3.setPWM(15, 4000);
usleep(300000);
pwm1.setPWM(15, 4000);
pwm2.setPWM(15, 0);
pwm3.setPWM(15, 4000);
usleep(300000);
pwm1.setPWM(15, 4000);
pwm2.setPWM(15, 4000);
pwm3.setPWM(15, 0);
usleep(300000);
}
pwm1.setPWM(15, 4095);
pwm2.setPWM(15, 4095);
pwm3.setPWM(15, 4095);
}
bool setup(BelaContext* context, void* userData) {
pwm1.begin(0x40);
pwm2.begin(0x41);
pwm3.begin(0x42);
Bela_scheduleAuxiliaryTask(Bela_createAuxiliaryTask(auxFunc, 90, "i2c", NULL));
return true;
}
void render(BelaContext* context, void* userData) {
}
void cleanup(BelaContext* context, void* userData) {
}
So, I am not sure what is the problem you are encountering, but I would suggest:
- check your hardware connections and the jumper
- make sure i2cdetect
reliably detects the correct address. I run it like this watch -n0.2 i2cdetect -y -r 1
so it refreshes automatically every 0.2 seconds. Remember to stop this when running the Bela program, as it may interfere with that one, as both use the bus.
- make sure you use 0x
if you are specifying the hex address (and viceversa, don't use it if you are not). Pretty basic, I know, but it got me a couple of times today!