Quote:
Originally Posted by MPaulHolmes
I'm getting close to being done with a complete rewrite of the code. I'm pretty sure there's a bug in the original software for the pwm filter. It tries to take sort of a running average for pwm, but look at this:
pwmAverage = (127*pwmAverage + 1*pwmNewValue)/128
Let's say, for instance, pwmAverage is 10, and pwmNewValue is 20. pwmAverage will never be able to creep toward 20. If the new value of pwm average is 10 < pwmAverage < 11, it will be truncated to 10, and won't ever get to 20.
|
Paul,
If the intention is to have a pwmNewValue of 20 move the pwmAverage towards 20 with each evaluation. Then the pwmAverage needs to be a floating point number or somehow be saved with about 3 decimal places of precision. If an integer is used then a pwmNewValue of 20 isn't high enough to step the average up to the next integer value.
Another approach would be to multiply the pwmAverage by 100 before storing it. Then dividing it by 100 whenever it is used.
pwmAverage = ((( 127 * (pwmAverage / 100)) + (1 * pwmNewValue)) / 128 ) * 100
pwmAverage = ((( 127 * (1000 / 100)) + (1 * 20)) / 128 ) * 100
pwmAverage = ((( 127 * (10)) + (1 * 20) / 128 ) * 100
pwmAverage = (( 1270 + 20) / 128 ) * 100
pwmAverage = (1290 / 128 ) * 100
pwmAverage = 10.078125 * 100
pwmAverage = 1007.8125
Stored as an integer we get 1007
Next evaluation with pwmNewValue = 20 we get
pwmAverage = ((( 127 * (pwmAverage / 100)) + (1 * pwmNewValue)) / 128 ) * 100
pwmAverage = ((( 127 * (1007 / 100)) + (1 * 20)) / 128 ) * 100
pwmAverage = ((( 127 * (10.07)) + (1 * 20) / 128 ) * 100
pwmAverage = (( 1,278.89 + 20) / 128 ) * 100
pwmAverage = (1,298.89 / 128 ) * 100
pwmAverage = 10.147578125 * 100
pwmAverage = 1014.7578125
Stored as an integer we get 1014
And so on and so on until we approach pwmAverage of 20 or pwmAverage stored value of 2000
If you didn't want to change the magnitude of the pwmAverage value (if it is used elsewhere) then you could use a second value to hold the more precise pwmAverage value.