EcoModder.com

EcoModder.com (https://ecomodder.com/forum/)
-   OpenGauge / MPGuino FE computer (https://ecomodder.com/forum/opengauge-mpguino-fe-computer.html)
-   -   Help w/ mpguino space shuttle code please (https://ecomodder.com/forum/showthread.php/help-w-mpguino-space-shuttle-code-please-4976.html)

forgottenmindset 09-05-2008 09:42 PM

Help w/ mpguino space shuttle code please
 
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];
}


forgottenmindset 09-05-2008 09:44 PM

Basically, I'd like someone to throw any input they can and/or install the code on their box and perfect it

dcb 09-06-2008 02:41 AM

LOL, I like the "Space Shuttle" characterization :)

I did try it, and it was still bouncy (would drop to 17 from 27mph on occasion).

Tried a couple other things:
1. track the last 3 pulse time stamps and do a "vote", still wonky

2. track last 4 vss pulse lengths and average. Better, but jumpier than just vss tic count per half second.

3. keep track of the minimum pulse timing (max speed), reset when instantmph() is called (every 1/2 second). Actually was pretty consistent reading, a couple minor jumps, but it was really off. @20mph the guino was saying 35mph.

4. keep track of the maximum pulse timing (min speed), reset when instantmph() is called. Even more consistent, but also off. @20mph the guino was saying 12mph.

So something to mull over anyway.

I also did some coasting with the raw instant screen to see how the vsspulse looked. The number of pulses per half second would drop smoothly, not dropping more than 1 pulse at a time when slowly decelerating. So the counter logic looks good, just this instant timing is hard to nail down.

I got some metro bits from coyote (thx coyote/shultz!) so will probably hook up a reed switch on the bench and hack at it, and dissect an ECU :)

dcb 09-06-2008 12:32 PM

I was thinking about a "speedometer algorithm" this morning, after dissecting a speedometer. You know, add a "spring" component to reduce the speed towards zero, and weigh each pulse evenly and have that as a force input, and the balance would be the actual speed. BUT,

I went for a drive this morning, and watched the speedo more closely than usual, and the needle itself bounces. Like up and down 1mph 4 times a second at 20mph! I realized this is not just warn bushings, but the cable itself and it's sheath, and the junctions/gears, plus reed switch fun on top of all that for the guino.

I also took a look at the ecu circuit, nothing special there as far as I can tell. Just a diode for protection and a voltage divider. I think I realized that this particular car computer doesn't really care about accurate mph at lower speeds. When monitoring the speed value on the obd port, it is really slow to react, doesn't bounce like the mechanical speedo, so they probably just look at a lot of pulses over a longer period of time.

So, we could take that approach too, but I was encouraged by the discovery that keeping track of the maximum pulse length produced fairly consistent results. It may be that we add another setup parameter to compensate for the "slop", i.e. 1.6 (or 1600) for the metro. This would not be a memory or computationally expensive thing. Hopefully the "slop" isn't too speed sensitive :)

bbjsw10 09-06-2008 03:18 PM

Quote:

Originally Posted by dcb (Post 59317)
I went for a drive this morning, and watched the speedo more closely than usual, and the needle itself bounces. Like up and down 1mph 4 times a second at 20mph! I realized this is not just warn bushings, but the cable itself and it's sheath,

I was thinking about this last night while trying to fall asleep. I think it would be a good idea on older cars to pull cable and re-lube them just to help smooth out a little more. Or maybe making or finding some kind of adapter that would go on the tranny end of cable to get rid of this problem. That just means more money and not so plug and play, which is nice.

ac7ss 09-06-2008 05:49 PM

Quote:

Originally Posted by forgottenmindset (Post 59216)
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
// Mod By AC7SS

unsigned long g_vssReading[3];
//AC7SS Remove unneccesary global variables

//AC7SS I assume this is to return valid VSS time value correct?
unsigned long instantmph(){     
  cli();
//AC7SS remove  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);
//AC7SS: Added internal values:
  unsigned long minVssPulseTime;
  unsigned long maxVssPulseTime;
  unsigned long avgVssPulseTime;

 
  //////////////////////////////////////////////////////////////////////////
  // VALIDATE
  // WEED OUT ANY ODD READINGS FROM VSS Sensor
  //////////////////////////////////////////////////////////////////////////
 
  // Counter Mechanism
// AC7SS replace with shift of registers. 
//  if( g_vssReadingCount < 3 ) 
//    g_vssReadingCount++;
//  else
//    g_vssReadingCount = 0;
  g_vssReading[0] = g_vssReading[1];
  g_vssReading[1] = g_vssReading[2];
  // Update vss reading chain
  g_vssReading[2] = tmp1[1];
 
 
//AC7SS: simpler algorithm:
  //Three cases:
    //find minimum/max/average of all three values:
    minVssPulseTime = g_vssReading[0];
    maxVssPulseTime = g_vssReading[0];
    if(g_vssReading[1]<minVssPulseTime) minVssPulseTime = g_vssReading[1];
    if(g_vssReading[2]<minVssPulseTime) minVssPulseTime = g_vssReading[2];
    if(g_vssReading[1]>maxVssPulseTime) maxVssPulseTime = g_vssReading[1];
    if(g_vssReading[2]>maxVssPulseTime) maxVssPulseTime = g_vssReading[2];
    avgVssPulseTime = (g_vssReading[0] + g_vssReading[1] + g_vssReading[2])/3;

  //case 1: all are within tolerances (say 3%), return last reading.
    if((minVssPulseTime/maxVssPulseTime)>0.97) return g_vssReading[2];

  //case 2: last reading is anomalous: return previous reading. (Please re-write to get the correct method, I am away from my reference material)
    if(1.03>(g_vssReading[2]/avgVssPulseTime)>0.97) return g_vssReading[1];
  //case 3: either of the other readings is the anomalous one:
    return g_vssReading[2];

}

Run this through the compiler and check the byte counts. (I know I made errors, deal with them.)

The meat of the program is the last 3 lines of code. no conversion to mph is necessary, all you want to do is set a threshold for rejection (3% in this code example). You never change the actual values of the readings, so if they are real readings that are outside of the range, it will still return the real value. I figure you will not be able to make a 3% change in speed between pulses. at 5 mph, you would have to speed up to 6 mph in 7 pulses. At 50 mph, you would have to speed up to 53 mph in 2 pulses. at 4000 pulses per mile, NOT BLOODY LIKELY. :)

dcb 09-06-2008 05:56 PM

Do you guys not have guinos that you can test your own work? I appreciate the effort, but it can cause a lot of frustration to publish non unit tested code and take a loooong time to get sorted out. Testing is in many ways the hardest part.

ac7ss 09-06-2008 06:04 PM

Averaging the 2 non-anomalous readings is bad, it introduces instability to the equation. With 3 readings we are counting on only one being bad, if 2 are bad, it will return the bad average anyway.

The plan that I had proposed would return the least anomalous of the last 2 readings.

If we need a larger sample to average, it would take a bit more code and variable space and we would merely make a average of 10 (Slower 'instant' readings at low speed) or running average of the last 10 (Instant update, lagging by 5 values). IMO, this would bypass the entire 'instant' reading idea. both also introduce errors at low speeds.

ac7ss 09-06-2008 06:05 PM

my parts are on order. I should have a guino in 2 weeks and will try it with the public code and try it with the additions.

dcb 09-06-2008 06:16 PM

I might be on to something with the min vss pulse spacing per half second approach mentioned in post 3 & 4. Need to do some more experiments though. An occasional glitch on the instant reading is ok, one can filter them out without much fuss, but it needs to be more stable than it is if you are trying to dial in best cruise mpg.

I'm not wild about just increasing the size of the sample pool either, or inviting floating point math to the party.

ac7ss 09-06-2008 06:28 PM

I would not use a large sample pool. that was just a reasoning for not doing it. I did not realize that a 'last 1/2 second' solution was in the works. (too large a data set imo, and it seems to me that you would loose data intregrity for the mpg reading.)
I was merely showing an algorithm for screening out single anomylous readings. (Tossing out the signal would be bad, causing dropped counts for total miles.)
Using the min vss pulse for a time frame seems like it would show a little high for the speed if you have a glitch.

ac7ss 09-06-2008 06:30 PM

of course, if we had a trace output of the anomalous pulses it would be easy to determine the easy way to screen them out.

dcb 09-07-2008 03:32 AM

Collecting data for a half second is entirely appropriate for display purposes, because that happens to be the display refresh rate. I have not suggested anything that would interfere with the accuracy of the trip accumulators, those are more important than the instant display. And yes, you need a "slop factor", as mentioned, my metro looks like 1.6.

re: traces, Here are a couple pulses (pm'd you the link):
http://ecomodder.com/forum/showthrea...html#post50053

The problem comes in when you want to do something like an accurate coast down test to determine your cda/crr. cda/crr doesn't exist yet, but 1/2 a second resolution is less than ideal for that task, more than one pulse is also less than ideal too, the signal on the metro itself is far from ideal, there's only so much you can do with it.

The nice thing about the "slop theory" and tracking the min and/or max vss pulses per 1/2 second in the interrupt handler is that it is based on a physical limit of the existing system, i.e. the min or max should be mostly those readings where most/all the slop was at it's maximum extents, and thus we have a reference point, sort of :)

ac7ss 09-07-2008 03:15 PM

The signal is very noisy on first look.
http://farm4.static.flickr.com/3293/...7c5db3.jpg?v=0
A little filtering would go a long way.

A simple circuit called a "Window Detector" will do this. Waiting for a specific value to turn on, and waiting for a lower value to turn off.

ac7ss 09-07-2008 03:17 PM

Nasa guys huh? :)


All times are GMT -4. The time now is 09:55 AM.

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Content Relevant URLs by vBSEO 3.5.2
All content copyright EcoModder.com