Here's my attempt at smoothing out the vss output
(idea courtesy ac7ss)
Takes 3 values (say 50, 51, 70)
Finds out if the current reading is way off (70) by comparing it to the other two values (50, 51).
If it is a strange number, it just takes the other two values and averages them:
return (50 + 51) / 2
I think it helps some but it still will show an absurd value time to time like when accelerating or putting the clutch in, mabey my threshold needs to be adjusted...
This code could be added to your mpguino for better accuracy if you have funny readings
dcb, I'm sure you could write a better version, but I think it needs to be added for us guys with worn out speed sensors, it won't hurt the guys with good ones
Code:
// CUSTOM BY FORGOTTENMINDSET
// FOR ERROR PROOFING
unsigned long g_vssReading[3];
unsigned long g_vssSorted[3];
unsigned long g_vssReadingCount = 0;
unsigned long instantmph(){
cli();
unsigned long vssPulseTimeuS = (lastVSS1 + lastVSS2) / 2;
sei();
init64(tmp1,0,1000000000ul);
init64(tmp2,0,parms[vssPulsesPerMileIdx]);
div64(tmp1,tmp2);
init64(tmp2,0,3600);
mul64(tmp1,tmp2);
init64(tmp2,0,vssPulseTimeuS);
div64(tmp1,tmp2);
//////////////////////////////////////////////////////////////////////////
// VALIDATE
// WEED OUT ANY ODD READINGS FROM VSS Sensor
//////////////////////////////////////////////////////////////////////////
// Counter Mechanism
if( g_vssReadingCount < 3 )
g_vssReadingCount++;
else
g_vssReadingCount = 0;
// Update vss reading chain
g_vssReading[g_vssReadingCount] = tmp1[1];
// Find any way off readings, 10 mph threshold
switch( g_vssReadingCount )
{
case 0:
// Is 0 similar to 1?
if((g_vssReading[0]-g_vssReading[1])<5000ul || (g_vssReading[1]-g_vssReading[0])<5000ul)
// Is 0 similar to 2?
if((g_vssReading[0]-g_vssReading[2])<5000ul || (g_vssReading[2]-g_vssReading[0])<5000ul )
// Good reading, return normal
return g_vssReading[g_vssReadingCount];
// Unsimliar value found, return best guess
return (g_vssReading[1] + g_vssReading[2]) / 2;
break;
case 1:
// Is 1 similar to 0?
if((g_vssReading[1]-g_vssReading[0])<5000ul || (g_vssReading[0]-g_vssReading[1])<5000ul)
// Is 1 similar to 2?
if((g_vssReading[1]-g_vssReading[2])<5000ul || (g_vssReading[2]-g_vssReading[1])<5000ul )
// Good reading, return normal
return g_vssReading[g_vssReadingCount];
// Unsimliar value found, return best guess
return (g_vssReading[0] + g_vssReading[2]) / 2;
break;
case 2:
// Is 2 similar to 1?
if((g_vssReading[2]-g_vssReading[1])<5000ul || (g_vssReading[1]-g_vssReading[2])<5000ul)
// Is 2 similar to 0?
if((g_vssReading[2]-g_vssReading[0])<5000ul || (g_vssReading[0]-g_vssReading[2])<5000ul )
// Good reading, return normal
return g_vssReading[g_vssReadingCount];
// Unsimliar value found, return best guess
return (g_vssReading[0] + g_vssReading[1]) / 2;
break;
}
// return normal since no bad reading was found
return g_vssReading[g_vssReadingCount];
}