-
Notifications
You must be signed in to change notification settings - Fork 305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Simplify and improve the writeMicroseconds() calculations #66
Conversation
Checked the calculations by hand Use Datasheet 7.3.5 Equation 1 for frequency from prescale https://cdn-shop.adafruit.com/datasheets/PCA9685.pdf Frequency = (ClockFrequency/(PreScale+1))*(1/BitRate) and from the rest of the calculation us per period = PulseLength/Frequency us per bit = us per period/BitRate we can combine to get us per bit = (PulseLength/((ClockFrequency/(PreScale+1))*(1/BitRate)))*(1/BitRate) This can be simplified to (PulseLength (PreScale + 1))/ClockFrequency this formula was implemented in proposed code checked by setting chip frequency to 60Hz read prescale = 105 us per bit = 4.069 with 25Mhz (a PWM frequency of about 57.3hz) Choosing the FREQUENCY_CALIBRATED constant listed at 104.3% higher or 26.075MHz we get us per bit = 4.1035 or a PWM frequency of about 60.056Hz much closer to the set 60Hz Overall this change makes less calculation steps, and uses fewer variables. The change should be faster and more accurate to the intended results.
debug statements should be Wrapped in `#ifdef ENABLE_DEBUG_OUTPUT`
I looked to it yesterday and had the same thoughts how it could be shortened. The code also runned in some rounding problems that seems to be solved now. PS: You could make prescale uint16_t |
@Bolukan Thanks. I'll make that change. |
|
@Bolukan Got it. Thanks. |
Prescale values are integers 3 to 255 with a maximum of 255+1 for the calculations.
@ladyada Let me know if there are any other changes. This should be good to go now. |
ok is this ready for my review now? |
@ladyada Yes, it is ready for review. |
ok i refactored the way we tell the PCA9685 the freq its running at. please check the version in 'master' now :) |
@ladyada Version 2.2.0 seems to be working as expected on my Uno with the two Adafruit PCA9685 16-Channel Servo Drivers I have. With the refactored changes in 2.2.0 the new default after setting That matches what I was getting before, the refactor is nice. |
Overall this change makes less calculation steps, and uses fewer variables. The change should be faster and more accurate to the intended results.
Checked the calculations by hand
Use Datasheet 7.3.5 Equation 1 for frequency from prescale
https://cdn-shop.adafruit.com/datasheets/PCA9685.pdf
Frequency = (ClockFrequency/(PreScale+1))(1/BitRate)
and from the rest of the calculation
us per period = PulseLength/Frequency
us per bit = us per period/BitRate
we can combine to get
us per bit = (PulseLength/((ClockFrequency/(PreScale+1))(1/BitRate)))*(1/BitRate)
This can be simplified to (PulseLength (PreScale + 1))/ClockFrequency
this formula was implemented in proposed code
checked by setting chip frequency to 60Hz
read prescale = 105
us per bit = 4.069 with 25Mhz (a PWM frequency of about 57.58hz)
Choosing the FREQUENCY_CALIBRATED constant listed at 104.3% higher or 26.075MHz
we get
us per bit = 4.1035 or a PWM frequency of about 60.056Hz much closer to the set 60Hz
Overall this change makes less calculation steps, and uses fewer variables. The change should be faster and more accurate to the intended results.
Describe any known limitations with your change.
setServoPulse()
method)Please run any tests or examples that can exercise your modified code.
Calculations were checked by hand and are an improvement