From EcoModder

Jump to: navigation, search

1997 Audi A6 Quattro



My MPGuino Installation

Mpguino front.jpg

18.5 miles per gallon for this tank, 212 miles estimated remaining to empty tank, estimated 360 miles total on the tank. Odometer displays 148 miles since fill-up.


I wanted to retrofit a stock trip computer in my 1997 Audi A6. The trip computer was available in other parts of the World but not in North America. After much research, I found that a European trip computer would fit in the instrument cluster but North American Audis do not have the correct wiring harness. So, I was unable to retrofit without major wiring modifications.

My ultimate goal is to have a completely stock looking installation. Eventually, I’ll use the stock trip computer switches in the wiper stalk and mount a small graphic display in the trip computer location inside the instrument cluster. There’s an unused cutout there already. Until then I'm using the display shown above.


I started searching for an alternative and ran across the ecomodder forum and the MPGuino by dcb. This seemed like a perfect fit to satisfy my desire for a trip computer and my love of messing around with electronics.

Searching the Web, I found the ECU signals available in my car and the specifications for the signals. The information available on the MPGuino Forum gave me the confidence that I could do this.

Vehicle Connections

I needed two signals, VSS for speed and fuel consumption. These signals are available from ECU. They are ordinary square wave signals. The VSS is pulses 6703 times per mile. The fuel consumption signal is a pulse for each injector pulse for all injectors. So, for every 2 revolutions of the engine, there are 6 pulses (6 cylinder engine).

Tools: Oscilloscope

I needed some way to examine the injector and ECU signals. I found a free SoundCard Oscilloscope program online ([1]). It runs on my laptop to monitor the ECU signals. It uses the laptop sound card to capture the signal and displays it in an oscilloscope form on the screen. It is adequate for the low frequency signals. I had to fabricate a small adapter to drop the 12 volt ECU signals down to about .7 volts for the soundcard input.


This is what the ECU signals look like:



Fuel Consumption


The top green line shows the pulses directly from one injector. The bottom line in red is the ECU signal. I compared the two signals to prove to myself that the ECU signal was really a composite of all the injector pulses. Notice that there are 6 ECU pulses for each injector pulse. Each injector is pulsed once in every two revolutions. For a 6 cylinder engine, there are 3 injector pulses in each revolution.



I initially used a Fundamental Logic iDuino on breadboard to prototype my MPGuino. The breadboard worked well enough in my car to prove that the inputs would allow the MPGuino to perform as designed.


Later, Fundamental Logic offered the MPGuino[2] as a purpose built kit so I bought one and switched from breadboard. That eliminated possible wiring mistakes. I wanted a red display to match my car instrument lights so I replaced the LCD that came with the kit with a red 2x16 LCD from SparkFun[3].


I found a Hammond plastic box (PN 1591) and mounted the MPGuino inside the cover. Switch extensions were fabricated from a plastic ballpoint pen refill so they fit through the front of the box cover.

Mpguino open.jpg

Mpguino back.jpg


I didn’t want to destroy my dash panel by drilling holes so I found a spare trim piece at a junkyard. I made a couple of sheet metal brackets, screwed them to the trim and bolted the box to the brackets.



The best place to tap into the signals is in the passenger footwell. Behind the panel on the right are a number of colored connectors as shown below. The upper red arrow points to the cruise control module only for reference.


The bottom red arrow points to the white blue wire in the green connector. That is the VSS signal.


Here the junction bracket is unbolted to get at the backside. The blue black wire in the red connector is the fuel consumption signal. There's a temporary yellow wire shown here that brings out the signal. The thick green wire on the right is the MPGuino ground wire that I attached to the ground post.

I found that a normal automotive spade electrical connector makes a nice secure connection. Crimp the spade connector onto the end of the MPGuino wire used to bring out the signal. Bend the tip of the spade into a slight U shape and push into the green or red connector next to the appropriate wire.

Fuel Flow Calibration

Fill your fuel tank and reset the MPGuino tank setting (top & middle buttons). Now drive until the next fill-up. Pump the fuel and compare the fill gallons to the MPGuino tank gallons used (tank screen). Go into Settings (top/bottom buttons) and adjust the microSeconds per gallon setting up or down until the MPGuino tank gallons matches the actual fill-up gallons. Keep changing the setting until they match (It's a pain to keep cycling through all the settings!) Once you've matched the MPGuino tank gallons to the actual fillup gallons, reset the MPGuino tank (top/middle buttons) and run through another tankful. After 2 or 3 tanks, the setting should be very close to ideal.

In practice, I've created a spreadsheet to capture the information at every tank fill-up. The spreadsheet calculates the average uSec/gal for all the fill-ups that are within 2% of the MPGuino calculated gallons. I enter that uSec/gal number in the MPGuino and drive for another tankful. When the fill-up is within +/- 1% of the MPGuino gallons used, I keep that uSec/gal number for 2 or 3 tankfuls to see if it's stable. Right now my fill-ups are within +/- 1% when I fill-up at the same gas station, same pump and fill the tank to the third nozzle click-off.

Update 11/6/2014: There is significant variability from car to car. I bought a different car but same make/model/engine. I moved my MPGuino to the new car, hooked it up in exactly the same way. It worked right away but indicated gas mileage seemed too high versus my manual calculations. It displayed 21.8 MPG while my manual calculations said 20.0. So, I recalibrated across several tankfulls and changed the uSec/gal setting from ~129,000,000 down to ~120,000,000. The display is now an accurate 20.0 MPG. Of course, I'm annoyed that this car gets nearly 2 MPG less mileage but that's another research project.


Year Make Model Engine Transmission VSS (count/mile) uSec/gal Inj DelayuS Notes
1997 Audi A6 Quattro 2.8L Automatic 13406 128027612 72uS VSS: Audi (97 A6) speedometer has K=6703 on bezel. That's pulses per mile. MPGuino counts VSS rising and falling edges so 2 x 6703 = 13406 counts per mile. uSec/gal: uSec per gallon is based on the fuel flow signal from the ECU. The latest calibration of uSec/Gal is based on 32 tanks of gas and is within +/-1% at fill-up.


I added a number of screens to aid my debugging efforts. The extra screens allowed display of debug variables that I inserted in the code. Displaying full 10 digit values made the debugging easier. I declared global debug variables early in the code and then inserted them where needed to capture values within subroutines. I brought the variables out into the main loop() for display.


Fuel Remaining - Using the total tank capacity setting (Tank Gal * 1000), I added code to calculate the fuel remaining in the tank and then calculate from that the miles remaining. The capacity for my tank is advertised as 19.8 gal. Adding the miles already traveled to the calculated miles remaining totals up to the distance that will be traveled on the total tank. Without an input from the fuel level sender, the MPGuino doesn't really know how much fuel is left in the tank. So, this calculation only works if I always fill the tank.

New Screens - I created some additional screens to display information not in the basic MPGuino. For example, I wanted a single screen that would show me the tank MPG, the estimated distance remaining on the tank and the estimated total distance on the tank based on the current MPG rate. That's the information I've found most useful in normal driving.

MPG Averaging - I found that the Instant MPG was constantly changing which was a little annoying. I put in some code to average the MPG values across 10 display cycles (about 5 seconds). Now it's much more stable.

Code Changes

Negative ECU Injector Signal

/* Located around line 350 */

/* Change from positive signal to negative signal */
//  attachInterrupt(0, processInjOpen, FALLING);  //For positive inj signal      
//  attachInterrupt(1, processInjClosed, RISING);      
 attachInterrupt(0, processInjOpen, RISING);  //For negative inj signal      
 attachInterrupt(1, processInjClosed, FALLING);

Note: dcb may have included a parameter for this in the latest code making the above code change unnecessary.

High GPH Problem

I found that my MPGuino would operate except when coasting. When coasting the GPH would suddenly jump to very high value. Something like 40 GPH. The high value is then accumulated causing the calculations of GPH, MPG, etc. to be off. I isolated the cause to the fact that the ECU shuts off the injectors to save fuel when coasting. That would be okay but there's actually still a small positive blip in the fuel consumption signal even though the injectors are off. The blips are seen by the MPGuino as a negative signal and mistakenly captured as a very long injection signal. It starts counting on the falling edge and stops on the rising edge. Since the blips are opposite to the normal injector signal, the MPGuino measures the time between blips instead of the duration of the blips. You can see this happening as the car coasts slower and slower and the GPH goes higher and higher. Just the opposite of what it should do.

I modified the code to avoid this behavior. The code changes below were based on MPGuino Version 0.75.

/* High GPH Fix for 1997 Audi A6 using ECU fuel consumption signal
   by R. McComiskie
   Based on MPGuino v0.75 by dcb

/* this is located around line 22 */
unsigned long  parms[]={69ul,13406ul,128000000ul,6ul,420000000ul,17700ul,72ul,4097ul,0ul,2ul,4000ul};//A6 defaults w/ECU signal
char *  parmLabels[]={"Contrast","VSS Pulses/Mile", "MicroSec/Gallon","Pulses/2 revs","Timout(microSec)","Tank Gal * 1000","Injector DelayuS","Weight (lbs)","Scratchpad(odo?)","VSS Delay ms","Pulsewidth Limit"};

/* this is located around line 217 */
void processInjClosed(void){      
 unsigned long t = microSeconds();
 unsigned long s = parms[injectorSettleTimeIdx];  //set injectorSettleTime to 0, no change in behavior.
 unsigned long pwLimit = parms[pulsewidthLimit];
 unsigned long x = elapsedMicroseconds(injHiStart, t);
 if (x >= s && x < pwLimit) {  //if elapsed time > settling time and < upper threshold
   x -= s;                     //then normal pulse, subtract settling time
   x = 0;                      //otherwise pulse width assumed to be zero
 tmpTrip.injHius += x;       

 if (tmpInstInjStart != nil) {
   tmpInstInjTot += x;     
 } else {
   tmpInstInjStart = t;
 tmpInstInjEnd = t;
Personal tools