Closed Sciss closed 3 years ago
Could it be that the "independent" write commands cause problems? I'm not familiar with i2c, but how does it prevent that the last PWM cycle is "cut off"? or does it always complete one cycle? would using a single void write(byte[] buffer)
instead of four individual byte writes help? I see there is an internal locking mechanism, but not sure this has anything to do with ensuring the entire command is atomically received by the chip.
the other thing I see in setFrequency
is that there is some "sleep" mode, e.g.
oldMode = device.read(PCA9685A_MODE1);
int newMode = (oldMode & 0x7F) | 0x10; // sleep
device.write(PCA9685A_MODE1 , (byte) newMode); // go to sleep
device.write(PCA9685A_PRESCALE , (byte) prescale);
device.write(PCA9685A_MODE1 , (byte) oldMode);
Thread.sleep(1);
device.write(PCA9685A_MODE1 , (byte) (oldMode | 0x80));
perhaps something like this "sleep" should be used instead of setAlwaysOff
?
I can confirm that simply setting PCA9685A_LED0_OFF_H
's bit 4 to high works - the motors are off, and there are no erratic movements. So definitely asynchronously setting the lower bits to zero first is wrong.
Is this a known issue, and is there a work-around. In something like one out of ten cases, I have some servos that when I call
setAlwaysOff
inPCA9685GpioProvider.java
- so that a robot arm can rest and doesn't have to use force when "parked" - the servo moves rapidly into the "minimal" angle, I guess below the minimum pwm period defined, rather than turning the PWM off. This makes it impossible to use the feature to turn motors off in an unsupervised installation.The code would be
I don't know if the result can be achieved more safely? I saw this problem with different units of the servos used, so it's definitely not a problem of an individual servo, rather either a problem of the servo type as such, of the PCA9685 board, or the software. Thanks!