-
-
Notifications
You must be signed in to change notification settings - Fork 117
Description
Describe the bug
The PCA9685 chip has a known issue,
it's inbuilt clock isn't the most accurate, in fact it's not even close :-(
What's more different batches of the chip will see it's clock running at different speed for the same settings.
To Reproduce
With the Adafruit16CServoDriver service set to default settings and the servo on pin 0 set to 90°,
it should be outputting a 1500uS pulse at 60Hz.
What I am measuring is 1327uS pulse at 68.9916865Hz.
This is where @Shido/CyberSyntek#1360 was having issues with servos not centring correctly
Additional context
In the Adafruit16CServoDriver.java line 407 the frequency has a 0.9 factor applied to correct for the error in the chips clock frequency.
But testing across multiple PCA9685 has shown this error is not the same for all batches.
This 0.9 should be made available as a setting in the WebGUI and saved in the config.
The function starting at line 499
public void onServoWriteMicroseconds(ServoControl servo, int uS)
Also has an error.
It is using a constant for the calculation for the set microSeconds.
int pulseWidthOff = (int) (uS * 0.45) - 300;
This is based off the PWM frequency is set at 60Hz.
There is a function which will allow you to adjust the PWM frequency between 150Hz and 600Hz at line 390.
This function ignores the current PWM frequency
The function that sets the PWM frequency starting at line 390 also requires the pin passed as a parameter.
This pin value is never used in the function and should be removed.
It should be noted there is only one PWM frequency setting for the chip, all 16 output use this same setting.
You can not have pin 0 running at 60Hz and pin 5 running at 300 Hz at the same time, this is a hardware limitation.
The Pin parameter suggest to the user, that each pin can be set individually when it can not.
Servo positioning is also calculated based on the constants defined on line 160 and 166
This is based on a PWM frequency of 60Hz and is not updated at all if the PWMfrequency is changed.
This results in not being able to use the new digital servos at the higher 300Hz update rates.
SERVOMIN is used on lines 120, 474 and 955
SERVOMAX is used on lines 120, 474 and 955 as well
These values should be int's and updated by the setPWMFreq() function.