Quote:
Originally Posted by Matt Krass
Actually, that's going to make the motors go full reverse, since you're handling everything as an 8-bit integer value calculation, anything between 1 and 0 as a decimal defaults to zero, and you're multiplying both sides of the plus by 0, so you'd end with 0 + 0 = 0.
|
Actually, that's not true. The literal value .2 in the #define statement is actually of type double. (You could keep it to just type float by specifying .2f) If the compiler follows the ISO/ANSI standard, it will promote the pwm values to double before doing the arithmetic and then be cast back to unsigned char. However, it would probably be better to do the cast only once as in:
Code:
pwm01 = (unsigned char) (K_LP * pwm01 + (1.0 - K_LP) * pwm01_old);
You are right that avoiding floating point math completely would be a good idea, but I think there's a problem with your example.
The epression:
Code:
(unsigned int)((K_LP*pwm01)/10)
the part to the right of the cast is still, I believe, going to be evaluated as an unsigned char and then the unsigned int cast applied. This is because the expression in the parentheses is evaluated first. You should write it as:
Code:
(unsigned int) K_LP * pwm01 / 10
this will cast K_LP to unsigned int and then the rest of the expression will be promoted to unsigned int and then arithmetic done.
Your expression:
Code:
temp_pwm01 = (unsigned int)((K_LP*pwm01)/10) +
(unsigned int)(((10-K_LP)*pwm01_old)/10);
is a bit inefficient if the compiler isn't smart enough to optimize the division by 10. It would be better to help the compiler and be sure to get efficient code by doing the addition once and then the division.
Code:
pwm01 = (unsigned char) ((unsigned int) K_LP * pwm01 +
(10 - K_LP) * pwm01_old) / 10);
You could make it a bit more readable depending on your style and taste by incorporating the unsigned int cast in the #define as follows:
Code:
#define ((unsigned int) 2) K_LP