Problem: Several connected PCA9685 servo boards stop working.
Cause: You have updated to newest lib version.
Solution: Revert to a library version from 2022.
I use four PCA9685 to control 61 servos in my midi controlled reed organ. It used to work nicely, but then I needed a completely different program, a stand alone thing, where I just switch on the thing and it starts playing from memory. No midi, no attached computer.
My Arduino IDE said there were lots of updates on lots of libraries I had installed, so I updated everything. That was before I started writing new software for the organ. Then nothing worked. The servos seemed dead. I tried to search connection failures, I even tried to use the old midi controlled program (recompiling it). Nothing worked. I was afraid all PCA9685 were toasted.
Then I googled. Turns out there are some bugs in the latest updates for the libraries for PCA9685. A version from 2022 was mentioned to be working. I deleted the lib and picked some old version from 2022 instead. Everything came back. The organ plays just fine.
The lib I'm using is PCA9685_RT. That particular lib wasn't mentioned in the text I found about the linking problems. But I guess all libs rely on the same lower level libs, where the bug is. And just reverting to an older lib of PCA9685_RT also reverted to an older, bug free underlying lib.
I should of course check my theory and then report the bug, but I'm a bit lost here, and really don't have time or basic knowledge for digging deeper. I just wanted to share this, if someone runs into the same problem.
Can you be more specific ? Which library was a problem ?
There is no common lower level library. They use the Wire library for the I2C bus, but if the Wire library is wrong, then probably everything on the I2C will go wrong.
The "RT" in the name stands for "Rob Tillaart".
This is his PCA9685_RT library: https://github.com/RobTillaart/PCA9685_RT
He actively maintains his libraries, and a problem will be solved. You did the right thing to select this library. I hope you use the newest version.
In the Open Source world, code is often copied. A bug in one library can end up in an other library and then in yet another library. That is indeed a serious problem.
I still advice to use the newest versions for everything, because old bad code might be replaced by good code. You just had bad luck that a new bug was introduced.
Well, I have everything working right now, after installing an older lib. Whereas the newest lib simply didn't work. When I have time, I will report this. I got the impression that the lib updates have concentrated on single use of PCA9685 and that's how they have missed the bug.
Then I googled. Turns out there are some bugs in the latest updates for the libraries for PCA9685. A version from 2022 was mentioned to be working. I deleted the lib and picked some old version from 2022 instead. Everything came back. The organ plays just fine.
Can you tell me which is the version that works for you?
The lib I'm using is PCA9685_RT. That particular lib wasn't mentioned in the text I found about the linking problems. But I guess all libs rely on the same lower level libs, where the bug is. And just reverting to an older lib of PCA9685_RT also reverted to an older, bug free underlying lib.
The only underlying library is Wire. Did you update / downgrade that too?
0.4.1. I just took one version that I saw was published in 2022. Never tested more of them. My automatic reed organ is a part of a stage setup in a theatre and we have a premiere next Saturday. Everything seems to be working. I won't touch the setup until April, when the last show is held.
0.4.1 doesn't use Wire, does it? Because I don't seem to have Wire at all. This is how I initialize the four boards:
for (int i = 0; i < 4; i++)
{
servobank[i] = new PCA9685(0x40 + i);
servobank[i]->begin();
servobank[i]->setFrequency(50, 0);
}
Investigation difference 0.4.1 and latest == 0.7.1
The most important breaking change between these two versions is a breaking change which involves removing the implicit initialization of the Wire library in begin() and the removal of the ESP specific version of begin().
This change is mentioned in the changelog.md and documented in the readme.md. Apparently
Rationale
The rationale for this change is that different boards (e.g. ESP32 and RP2040) can set SDA and SCL pins of the I2C port during Wire.begin() . As I had the initialization of Wire inside the library (in fact many of my libraries) I had to implement all these variations. Furthermore the implicit initialization of Wire gave rise to problems when the library implicit overruled explicit settings made by the user. The latter should have priority.
Solution
To fix this problem, improve portability to more boards and maintenance efforts I had to decide to extract the Wire.begin() (and more) from the library and made it explicit a responsibility of the user to call Wire.begin() before the call of PCA.begin()
In technical terms I implemented a clean(er) dependency injection of the I2C library.
Note: applied to all my Wire based libraries.
So the solution for your problem is to call Wire.begin() in setup() before you call PCA.begin().
Optional you can pass appropriate parameters, but as the implicit version works I do not think these are needed.
As I cannot see your code in detail, this solution might work or not as there might be other issues.
Wire.begin(); // add this line
for (int i = 0; i < 4; i++)
{
servobank[i] = new PCA9685(0x40 + i);
servobank[i]->begin();
servobank[i]->setFrequency(50, 0);
}
Ok. I never bothered to explicitly initialize Wire. As I mentioned, I don't even see that I had it installed. So this might not be an actual bug. It's just that newer lib versions are not directly compatible with code written for older lib versions. Older libs didn't require Wire.begin(). Newer do. Maybe.
I will definitely look into this later, because my next project is a similar one, using 32 servos.