mattjlewis / diozero

Java Device I/O library that is portable across Single Board Computers and microcontrollers. Tested with Raspberry Pi, Odroid C2, BeagleBone Black, Next Thing CHIP, Asus Tinker Board and Arduinos / Pico. Supports GPIO, I2C, SPI as well as Serial communication. Also known to work with Udoo Quad.
https://www.diozero.com
MIT License
261 stars 59 forks source link

Nothing happening when used on a Pi with PCA9685 #97

Closed WollfieGitHub closed 1 year ago

WollfieGitHub commented 2 years ago

Here is my code :

this.pca9685 = new PCA9685(I2CConstants.CONTROLLER_1, 0x40, 50);
// Later, called by another thread :
this.pca9685.setDutyUs(index, SERVO_CONFIG[index].getTrim().convertAngleToPulseWidthUs(rotDeg));
// Finally, when the program is shutdown :
this.pca9685.close();

The i2cdetect -y 1 command on the pi gives 0x40 as an address. The servos are not moving and there is no error message when the setDutyUs is called but at the end, on shutdown, I get a SMBUS.writeByteData error : -9 (which seems to correpond to "bad file") which I'm not sure is linked to the problem or not.

The servos are working when controlled via Arduino with the HCPCA9685 library

Expected Behavior : Same output, or no error but the servos should be moving

I have tried taking a look at the sampleapps but when I reproduce the given code for PCA9685 or PCA9685Animation, it gives me an exception telling me that "SERVO" mode is not supported for PCA9685 which is normal since only PWM Mode is added to its pins.

mattjlewis commented 2 years ago

Regarding the write errors - it could be that the device isn't connected to the Pi correctly? Are you able to use it on the Pi via Python? e.g. https://www.aranacorp.com/en/using-a-pca9685-module-with-raspberry-pi/

On the exception - looks like a bug. I probably need to initialise pins as: EnumSet.of(DeviceMode.PWM_OUTPUT, DeviceMode.SERVO)

WollfieGitHub commented 2 years ago

Yes, my current solution is running a websocket in python and sending it instructions from java and it works fine

mattjlewis commented 2 years ago

BTW - I think I've found a bug on this line: https://github.com/mattjlewis/diozero/blob/main/diozero-core/src/main/java/com/diozero/devices/PCA9685.java#L360

It believe it should be:

        int off = (int) Math.floor(((double) dutyUs / (double) periodUs) * RANGE);

and not:

        int off = (int) Math.floor(((double) dutyUs / (double) periodUs) / RANGE);

I will commit and release shortly.

mattjlewis commented 2 years ago

1.3.4 has just been released (it may take a few hours to replicate). Could you please test and let me know.