maxint-rd / FastPwmPin

Arduino library to generate a fast PWM signal on an output pin at maximum frequency. Example included.
40 stars 14 forks source link

Duty cycle calculation #3

Closed cesarab closed 3 years ago

cesarab commented 4 years ago

I've noticed that an nPeriodPercentage of 40, 50 or 60 gives you always a 50% duty cycle, and that's because the calculations to get the OCRxB use integers for the inner division, so 100/nPeriodPercentage = 2 for those three values.

I think the solution is to do that division as a floating point division, so that you can take into account the decimal numbers in the outer division. Something like this:

OCR2B = (OCR2A+1)/(100.0/(nPeriodPercentage>50?(100-nPeriodPercentage):nPeriodPercentage))-1; // pwm bottom, determines duty cycle, for 50%: (top+1)/2-1
maxint-rd commented 4 years ago

Good finding. Thanks! Although I do mention possible integer rounding issues in the readme; I appreciate any improvement I can make. I'll first see if I can reproduce this and then incorporate your suggestion. I'm not sure when I can find the time, but I will put this on my todo-list.

aiditz commented 3 years ago

@cesarab Thank you for your solution, it helped me a lot.

@maxint-rd I faced the same problem as @cesarab and I tested his solution and it works. Thank you for your library!

maxint-rd commented 3 years ago

Sorry, it took some time for me to test myself. Just now I reproduced the issue on an LGT8F328P. The fix by @cesarab works wonders. It's a great improvement in accuracy. Well done! (I spend some days getting Timer3 working on the LGT. My next upload will include this fix for all supported MCU's).

maxint-rd commented 3 years ago

Uploaded the latest version.

maxint-rd commented 3 years ago

@aiditz - thank you for confirming this fix. It's a great improvement. Feel free to submit more issues as you find them. I may not always have time to work at it, but I try to give each issue the attention it deserves.