Go Back   EcoModder Forum > EcoModding > Instrumentation > OpenGauge / MPGuino FE computer
Register Now
 Register Now
 

Reply  Post New Thread
 
Submit Tools LinkBack Thread Tools
Old 02-19-2009, 10:00 AM   #841 (permalink)
EcoModding Lurker
 
Join Date: Aug 2008
Location: Massachusetts USA
Posts: 84

Ziggy - '95 Audi S6 Sedan

Manfred - '97 Audi A6 Quattro Sedan
90 day: 20.61 mpg (US)

Clarabell - '03 Audi A4 Quattro Avant

Sherman - '98 Audi A6 Quattro Avant

Cab - '96 Audi Cabriolet
Thanks: 0
Thanked 2 Times in 2 Posts
I think I've identified the source of the erroneous GPH readings. To recap, I'm running a Fundamental Logic MPGuino in my 97 Audi A6. I tapped into an injector for the fuel flow signal. The MPGuino seems to run normally except when coasting. In the instant display, when coasting down a hill, the GPH reading goes to a very large value and the MPG does the same.

Looking at the injector signal when coasting shows that the pulses become very narrow. The ECU appears to be shutting off the injectors. That makes sense for fuel economy reasons. I assumed that the MPGuino was not handling the lack of pulses well.

I observed the behavior of the code by inserting debug variables and displaying them on the MPGuino. Backtracking from the instantgph() routine, I found that the origin of the very large GPH number was in the external interrupt routine "processInjClosed()". That routine executes on the trailing edge of every injector pulse.

The processInjClosed() routine calculates the width of the injector pulse and subtracts the injector settling time. It then updates trip and instant variables with the pulse time and count. It's the pulse width calculation that causes the problem.

Here's the calculation in v0.75:

Code:
void processInjClosed(void){      
  long t =  microSeconds();
  long x = elapsedMicroseconds(injHiStart, t)- parms[injectorSettleTimeIdx];       
  if(x >0)
    tmpTrip.injHius += x;       
  tmpTrip.injPulses++;      

  if (tmpInstInjStart != nil) {
    if(x >0)
      tmpInstInjTot += x;     
    tmpInstInjCount++;
  } else {
    tmpInstInjStart = t;
  }
  
  tmpInstInjEnd = t;
}
The variable "t" is the time right now when the injector closes. Var "x" is the calculated elapsed time of the pulse. "injHiStart" is the beginning time of the pulse. The parameter "injectorSettleTimeIdx" is the settling time. The settling time represents the opening of the injector valve before any fuel starts to spray. In my case, the settling time is set to 500uS. injHiStart is subtracted from t to get the raw pulse width and then the injectorSettleTime is subtracted from that to get the effective pulse width, i.e. the part of the pulse when fuel is actually flowing.

This calculation is where the problem occurs. If the raw pulse width is less than the settling time, a negative number is the result. For example, if the raw pulse width is 300uS then the calculation is 300uS - 500uS = -200uS. Okay, not a big deal but all of the variables here are declared as unsigned long integers. They cannot represent a negative number. So, what happens? The unsigned integer represents the negative number as a very large positive integer.

How can this be solved? I assumed that the raw pulse width can never be negative. I don't know how to deal with negative time anyway! It has to be zero or greater.

So, I modified v0.75 like this:

Code:
void processInjClosed(void){      
  long t =  microSeconds();
//  long x = elapsedMicroseconds(injHiStart, t)- parms[injectorSettleTimeIdx]; 
  unsigned long s = parms[injectorSettleTimeIdx];	
  unsigned long x = t - injHiStart;
  if (x < s) {  //if pulse width < settling time
    x = 0;      //pulse width must be zero
  }else{
    x -= s;     //otherwise subtract settling time from the pulse width
  }
//  if(x >0)    //not needed because x is always zero or greater
    tmpTrip.injHius += x;       
  tmpTrip.injPulses++;      

  if (tmpInstInjStart != nil) {
    if(x >0)
      tmpInstInjTot += x;     
    tmpInstInjCount++;
  } else {
    tmpInstInjStart = t;
  }
  
  tmpInstInjEnd = t;
}
I removed the call to elapsedMicroseconds() just for simplicity and did the calculation directly in this routine. If the raw pulse width (x) is less than the settling time (s) then the pulse width is set to zero. If the raw pulse width is equal to or greater than the settling time then the settling time is subtracted from the pulse width. The result will always be a positive number. I removed the test for x > 0 because it's no longer needed. x is guaranteed to be zero or greater.

I have tested this modification on the road and I no longer see the high GPH values when coasting.


Last edited by rmccomiskie; 02-19-2009 at 10:41 AM..
  Reply With Quote
Alt Today
Popular topics

Other popular topics in this forum...

   
Old 02-19-2009, 10:22 AM   #842 (permalink)
dcb
needs more cowbell
 
dcb's Avatar
 
Join Date: Feb 2008
Location:
Posts: 5,038

pimp mobile - '81 suzuki gs 250 t
90 day: 96.29 mpg (US)

schnitzel - '01 Volkswagen Golf TDI
90 day: 53.56 mpg (US)
Thanks: 157
Thanked 266 Times in 209 Posts
it *might* also be a bug in microseconds, I seem to recall some updated register analysis over on ardino.cc. Let me see if I can dig it up.
__________________
WINDMILLS DO NOT WORK THAT WAY!!!
  Reply With Quote
Old 02-19-2009, 10:46 AM   #843 (permalink)
Master EcoModder
 
Join Date: Nov 2008
Location: 18603, USA
Posts: 759

The Crimson Crawler - '04 Hyundai Elantra GLS
90 day: 36.71 mpg (US)
Thanks: 221
Thanked 60 Times in 45 Posts
I think you have a typo.
Code:
 }else{
    x -= s;     //otherwise subtract settling time from the pulse width
  }
Should be
Code:
 }else{
    x - s;     //otherwise subtract settling time from the pulse width
  }
  Reply With Quote
Old 02-19-2009, 10:47 AM   #844 (permalink)
Master EcoModder
 
Join Date: Nov 2008
Location: 18603, USA
Posts: 759

The Crimson Crawler - '04 Hyundai Elantra GLS
90 day: 36.71 mpg (US)
Thanks: 221
Thanked 60 Times in 45 Posts
Arduino v.013 has native support for the ATMega328 chip, if anyone wants to upgrade.
  Reply With Quote
Old 02-19-2009, 11:10 AM   #845 (permalink)
dcb
needs more cowbell
 
dcb's Avatar
 
Join Date: Feb 2008
Location:
Posts: 5,038

pimp mobile - '81 suzuki gs 250 t
90 day: 96.29 mpg (US)

schnitzel - '01 Volkswagen Golf TDI
90 day: 53.56 mpg (US)
Thanks: 157
Thanked 266 Times in 209 Posts
FYI, I'm not willing to push the 328 till they trim back the bootloader (and until we are happy with 1.0 on the 168).
__________________
WINDMILLS DO NOT WORK THAT WAY!!!
  Reply With Quote
Old 02-19-2009, 11:19 AM   #846 (permalink)
EcoModding Enthusiast
 
Join Date: May 2008
Location: Austin
Posts: 155

Silver Bullet - '03 Mazda Protege LX
90 day: 29.51 mpg (US)

Silver Bullet - '03 Mazda Protege LX
90 day: 37.06 mpg (US)

Blaze - '17 Ford Escape
Thanks: 23
Thanked 2 Times in 2 Posts
Quote:
Originally Posted by Nevyn View Post
I think you have a typo.
Code:
 }else{
    x -= s;     //otherwise subtract settling time from the pulse width
  }
Should be
Code:
 }else{
    x - s;     //otherwise subtract settling time from the pulse width
  }
no, it's just the syntax used to store "x-s" as x
__________________
  Reply With Quote
Old 02-19-2009, 11:26 AM   #847 (permalink)
Master EcoModder
 
Join Date: Nov 2008
Location: 18603, USA
Posts: 759

The Crimson Crawler - '04 Hyundai Elantra GLS
90 day: 36.71 mpg (US)
Thanks: 221
Thanked 60 Times in 45 Posts
Agreed, but at least there's no modding of the IDE for 013.
  Reply With Quote
Old 02-19-2009, 01:20 PM   #848 (permalink)
EcoModding Lurker
 
Join Date: Aug 2008
Location: Massachusetts USA
Posts: 84

Ziggy - '95 Audi S6 Sedan

Manfred - '97 Audi A6 Quattro Sedan
90 day: 20.61 mpg (US)

Clarabell - '03 Audi A4 Quattro Avant

Sherman - '98 Audi A6 Quattro Avant

Cab - '96 Audi Cabriolet
Thanks: 0
Thanked 2 Times in 2 Posts
Quote:
Originally Posted by Nevyn View Post
I think you have a typo.
Code:
 }else{
    x -= s;     //otherwise subtract settling time from the pulse width
  }
Should be
Code:
 }else{
    x - s;     //otherwise subtract settling time from the pulse width
  }
Actually, no. "x - s;" is syntactically incorrect. The calculation must be assigned to something. "x -= s;" is equivalent to "x = x - s;" which subtracts s from x and puts the result in x. I'm glad someone cares enough to look it over though. Cheers.
  Reply With Quote
Old 02-19-2009, 02:04 PM   #849 (permalink)
EcoModding Lurker
 
Join Date: Aug 2008
Location: Massachusetts USA
Posts: 84

Ziggy - '95 Audi S6 Sedan

Manfred - '97 Audi A6 Quattro Sedan
90 day: 20.61 mpg (US)

Clarabell - '03 Audi A4 Quattro Avant

Sherman - '98 Audi A6 Quattro Avant

Cab - '96 Audi Cabriolet
Thanks: 0
Thanked 2 Times in 2 Posts
I found an error in my code mod. The value of x should be determined by a call to elapsedMicroseconds() as shown here:

Code:
void processInjClosed(void){      
  long t =  microSeconds();
  unsigned long s = parms[injectorSettleTimeIdx];	
  unsigned long x = elapsedMicroseconds(injHiStart, t); //using elapsedMicroseconds afterall
  if (x < s) {  //if pulse width < settling time
    x = 0;      //pulse width must be zero
  }else{
    x -= s;     //otherwise subtract settling time from the pulse width
  }
//  if(x >0)    //not needed because x is always zero or greater
    tmpTrip.injHius += x;       
  tmpTrip.injPulses++;      

  if (tmpInstInjStart != nil) {
    if(x >0)
      tmpInstInjTot += x;     
    tmpInstInjCount++;
  } else {
    tmpInstInjStart = t;
  }
  
  tmpInstInjEnd = t;
}
By eliminating elapsedMicroseconds(), I disregarded the case where the injHiStart (start of pulse) could be larger than t (end of pulse). That can occur when the unsigned integer returned by Microseconds() rolls off the end of the number range and starts again from zero.

For example, suppose injHiStart is set to 4294967285, i.e. near the end of the number range for an unsigned long. Then the pulse takes 260uS. When processInjClosed() executes on the trailing edge of the pulse, the number returned by microSeconds() will be 250.

To determine the elapsed time a call is made to elapsedMicroseconds() with startMicroSeconds=4294967285 and currentMicroseconds=250 as parameters. From the v0.75 code:

Code:
unsigned long elapsedMicroseconds(unsigned long startMicroSeconds, unsigned long currentMicroseconds ){  
  if(currentMicroseconds >= startMicroSeconds) return currentMicroseconds-startMicroSeconds;      
  return 4294967295 - (startMicroSeconds-currentMicroseconds);      
}
Since currentMicroSeconds is not >= startMicroSeconds, this calculation is used:

4294967295 - (4294967285 - 250) = 260

So, every so often, the clock will roll off the end of the number range and the values being compared will be reversed. The elapsedMicroseconds() routine handles the situation correctly and returns the true elapsed time (260uS in this case).
  Reply With Quote
Old 02-20-2009, 08:45 AM   #850 (permalink)
Master EcoModder
 
Join Date: Nov 2008
Location: 18603, USA
Posts: 759

The Crimson Crawler - '04 Hyundai Elantra GLS
90 day: 36.71 mpg (US)
Thanks: 221
Thanked 60 Times in 45 Posts
Thanks for the explanation. I'm going to update my code with that today - maybe it'll solve my problem of GPH going .44, .44, .44, 5.27, .44, .44...........


Sketch size is 14288 of 14306.

Do we need the "Weight" variable declared at the beginning? I don't see it used for anything.

  Reply With Quote
Reply  Post New Thread


Thread Tools


Similar Threads
Thread Thread Starter Forum Replies Last Post
My kingdom for a giant, heated workspace MetroMPG The Lounge 14 12-12-2010 09:08 AM
Motorcycle manufacturers beginning to release MPG info MetroMPG Motorcycles / Scooters 1 04-03-2008 05:23 PM



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