Quote:
Originally Posted by Abwehr
We put a low-pass filter on the motor speed command almost every year. A more compact way to accomplish this follows. Note that you can (and I always do) use integers for the fractional part, but it's quicker to show you what's going on with floats:
Code:
// Put this at the top of "user_routines.c"
#define K_LP .2
// Put these at the top of Default_Routine()
static unsigned char pwm01_old = 127;
// Put these in your drive code
pwm01 = (your drive code here)
pwm01 = (unsigned char)(K_LP*pwm01) + (unsigned char)((1.0-K_LP)*pwm01_old);
pwm01_old = pwm01;
Adjust the "K_LP" parameter to change the response of the filter. Higher numbers make the system more responsive, but with more noise. Lower numbers make the system smoother, but with more lag.
|
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.
The concept is right but might I suggest a better execution?
Code:
// Put this at the top of "user_routines.c"
#define K_LP 2
unsigned int temp_pwm01;
// Put these in your drive code
pwm01 = (your drive code here)
temp_pwm01 = (unsigned int)((K_LP*pwm01)/10) + (unsigned int)(((10-K_LP)*pwm01_old)/10);
if(temp_pwm01 > 255)
{
temp_pwm01 = 255;
}
pwm01_old = pwm01 = (unsigned char)temp_pwm01;
This scales everything up for the calculations to avoid floating point (MUCH FASTER, and the extra int we used is still less memory than a float), then divides it back down to minimize rounding errors, then checks to make sure its not too large for a char and sets pwm01 to it.