Ideas for a instantaneous MPG display

neiltechspec

Senior Member
Title says it all really.
I would like to display my instantaneous MPG in my fuel injected classic car.

I have a digital speedo / odometer, so know the pulses per mile, which is 3210 or 321 for 1/10th of a mile.
(taken from a sensor on the propshaft giving 2 pulse per revolution x diff ratio & wheel /tyre circumference)

I know the injector flow rate - 480cc minute & can take the injector opening pulse X the number of injectors (2)
which should give me the fuel flow rate.
e.g at idle injector timing is 3.5ms approx with 2 pulses per rev per injector (alternating) - it's a V8.

So the hard part is converting this into readable info on a 2 or 3 dig 7 seg display.

There used to be a device called MPGuino which would do exactly that (on a 16x2 LCD), but seems to be long dead & gone now.

Any ideas / suggestions welcome.

edit:
1st thoughts are measuring injector time for a given speed pulse count,
should be fairly consistant but the maths is gonna be complicated.
 
Last edited:

neiltechspec

Senior Member
I think you missed the bit that said classic car.

It's a 1972.

Has to be over 40 to be a classic to me.
 
Last edited:

oracacle

Senior Member
Seems like an intersting idea, if you were to use the external counter of a 28x2 to count the mile pulses and an interrrupt to deal with the pulses from one of the injectors (or the other way round maybe) could get the info into the system.

the biggest problem that I can see is the maths. each time an injector fire it delivers 0.0004666cc of fuel, twice that for each time the engine goes round. This is where the problems start, and you will need to decide on accuracy you want, or figure out floating point maths routines for a picaxe.

It aprears that MPGuino was open source
MPGuino - EcoModder Forum Wiki
I can't find a full code set for it, but arduino does have some support for float and double removing a lot of issues within the maths. It also isn't burdened by an interpreted code base.
There is also some teensy based or arm cortex that have built in FPU and will run 32 floats at the same speed as normal interger maths, 64 bit double precision at half that speed. IIRC STM32 has an FPU too, but never personally used them. There is clear signs that micro cotrollers are moving towards 32bit, I hope picaxe will conme along for the ride.
 

AllyCat

Senior Member
Hi,

My car's trip computer gives the option of "average" and "instantaneous" fuel consumption (updated every 10 and 2 seconds respectively) but I find the instantaneous value almost useless because it's far too dependent on very minor speed or road gradient variations, etc.. Also, "infinity" occurs quite frequently (displayed as 99.9 mpg) on overrun/downhill, etc..

However, your title specifies "instantaneous" which should be much easier to do. The problem with "average" is that you would indeed need to detect the speed (distance) and fuel consumed "continuously" in parallel (without missing any pulses) and after an hour or more, the numbers will be quite large, probably requiring some form of "floating point" calculation. But for an instantaneous result you should be able to take "sample" measurements in sequence, the numbers won't be very large, and you can then spend some time calculating and sending the data to the display before starting another "instantaneous" cycle:

First you could measure the amount of fuel used in (say) one second by accumulating the injection pulse widths, then determine the road speed from the period between just two consecutive odometer pulses (note that PICaxe has an automatic timeout of typically 655 ms if the car is stationary). Or maybe take the average of a few odometer periods before and after the fuel detection period to improve the accuracy. PICaxe calculates natively to 16-bit resolution, with multiplication to 32 bits (using the * and ** operators) and many years ago I posted a Code Snippet to divide 32 bits by 16 bits (or strictly 15 bits) to return a 16-bit result. That should be easily sufficient, the only "trick" being to use appropriate units, i.e. don't work with miles and gallons, but for example milli-litres and metres (or even micro-litres and mm ! ). Then use the appropriate scaling or conversion constant to display the desired format, e.g. mpg or litres/100km. Again, the ** operator can be useful for high accuracy scaling or conversion (because it effectively multiplies two 16-bit values together and then divides by 65536).

Cheers, Alan.
 

neiltechspec

Senior Member
I'm afraid I don't get all that ardyweeno stuff. Might as well be written in Chinese for me, maybe it is !!!!.

Alan,
That's the sort of idea I had in mind, I will know the amount of fuel used for a given short distance travelled,
so was think of some kind of lookup table. It doesn't have to be 100% accurate - just a guide.

If I want temporary accuracy, I can plug in the laptop with a gps into the ECU. But that's not what I'm after.
 

hippy

Technical Support
Staff member
I am also thinking this should be quite easy. If we count the fuel pulses over a period we know how much fuel we have used in that period, and likewise by counting the distance pulses how far we have travelled, and MPG is simply distance travelled divided by fuel used. For example 60 miles using 60 gallons is 60m/60g = 1 MPG, 60 miles using 30 gallons is 60m/30g = 2 MPG.

The thing is that this is true no matter what time period things are measured over. The shorter the time period the more 'instantaneous' it will be. And, as noted, too 'instantaneous' and the numbers can change too frequently to be useful so a short period is probably better. Most of us aren't really interested in actual instantaneous, when accelerating or braking, but when cruising along at some speed, wanting to know how optimal that is. So it sounds like that's achievable and can reduce the period if we do want it more 'instantaneous'.

So period isn't particularly important. for now. The first challenge is in counting the fuel and distance pulses, second accumulating the fuel used and distance travelled amounts. Then we need to calculate distance travelled divided by fuel used and finally get that out to the display.

Counting should be fairly easy and I'd suggest using two HINT pins and HINT interrupts, choosing a PICAXE which will allow two; 20X2.

Storing accumulated counts is an interesting challenge. These will be sub-integer numbers and, while we can scale those up, those will become quite big numbers. We can however use multiple bytes or words per number, and the X2 has more byte variables and scratchpad which may help with that.

Dividing one big multi-byte value by another isn't going to be easy but may not be too hard. I'm leaving that aside for now and assuming it will be possible.

Getting the result out to a display should be fairly easy once we know the hardware.

Split it into those parts and it's job done when it is all put together. It's going to take some time to do all that, especially the division I'd guess, so that gives us our basic time period, just repeat it as fast as we can and that's 'instantaneous'. If too fast we just need to slow the loop down with some PAUSE.

So first steps are to determine what each pulse represents in miles or gallon units, and how best to hold accumulated values.

I'm off to do some maths and some thinking ...
 

Aries

New Member
Dividing one big multi-byte value by another isn't going to be easy but may not be too hard. I'm leaving that aside for now and assuming it will be possible.
I think we have already met the principle in 32-bit arithmetic (32 bit divided by 32 bit). I recently needed 48-bit divided by 32-bit, which is a straightforward extension of the original. Essentially, it is just long-division (made easier because the quotient at each stage is 1 or 0), and scales up to any number of bytes. You may also need to be able to handle subtraction for multi-byte (>2 bytes) words.
 

neiltechspec

Senior Member
I thought just counting the the speed pulses to 32 (about 17.5 yards) would be adequate then at that point measuring the injector pulse width.
That should give me enough info to go on.

Display would be just 2 CA 7 Seg displays directly driven by the PICAXE.

I do have a spare / unused 28x2 available.
 

hippy

Technical Support
Staff member
I thought just counting the the speed pulses to 32 (about 17.5 yards) would be adequate then at that point measuring the injector pulse width.
That should give me enough info to go on.
Could be, but I know if I were doing it I'd be hankering for knowing the journey MPG rate just for curiosity.

I got into trying to track accurate distance travelled and that may be of some use anyway, even if not necessary here.

If there are 3210 pulses per mile, the distance in miles per pulse is about -

0.00031152647975077883

Assuming we may want a 'journey average' in the future we need a data item able to hold say a 1,000 miles of travel, and just after 1,000 miles we should see -

1000.00031152647975077883

Split into 4-digit chunks we get -

1000 . 0003 1152 6479 7507 7883

We use 4-digit chunks because it means each chunk can be held in a 16-bit word variable, handling carry from adding two chunks together is pretty easy, and they are decimals so easy to print and use without having to convert from binary to decimal.

In fact, our most significant integer part can be 5-digit, allowing up to 65,537 miles to be stored.

The code for updating and reporting distance travelled is, not trivial, but not hard -

Code:
AddDistancePulse:
  ;     5   4    3    2    1    0
  ; Add 0 . 0003 1152 6479 7507 7883
  miles0 =                  miles0 + 7883 
  miles1 = miles0 / 10000 + miles1 + 7507 : miles0 = miles0 // 10000
  miles2 = miles1 / 10000 + miles2 + 6479 : miles1 = miles1 // 10000
  miles3 = miles2 / 10000 + miles3 + 1152 : miles2 = miles2 // 10000
  miles4 = miles3 / 10000 + miles4 + 0003 : miles3 = miles3 // 10000
  miles5 = miles4 / 10000 + miles5 + 0    : miles4 = miles4 // 10000
  Return
Code:
ShowDistanceTravelled:
  SerTxd( #miles5, "." )
  w0 = miles4 : Gosub ShowChunk
  w0 = miles3 : Gosub ShowChunk
  w0 = miles2 : Gosub ShowChunk
  w0 = miles1 : Gosub ShowChunk
  w0 = miles0 : Gosub ShowChunk
  SerTxd( CR, LF )
  Return

ShowChunk:
   BinToAscii w0, d5, d4, d3, d2, d1
   SerTxd( d4, d3, d2, d1 )
   Return
We can do similar for 'gallons' as well as 'miles', though the numbers added will be different.

Here's a test program to simulate distance travelled -
Code:
#Picaxe 20X2
#Terminal 38400
#No_Table
#No_Data

Symbol reserveW0 = w0 ; b1:b0
Symbol reserveW1 = w1 ; b3:b2

Symbol miles0    = w2 ; b5:b4
Symbol miles1    = w3 ; b7:b6
Symbol miles2    = w4 ; b9:b8
Symbol miles3    = w5 ; b11:b10
Symbol miles4    = w6 ; b13:b12
Symbol miles5    = w7 ; b15:b14

Symbol d1        = b21
Symbol d2        = b22
Symbol d3        = b23
Symbol d4        = b24
Symbol d5        = b25

PowerOnReset:
  SetFreq M32
  Pause 8000
  SerTxd( "Started MPG-001.bas", CR, LF )

MainLoop:
  Do
    For w0 = 1 To 3210          ; 3210 pulses is a mile travelled
      Gosub AddDistancePulse
    Next
    Gosub ShowDistanceTravelled ; Report distance travelled
  Loop

AddDistancePulse:
  ;     5   4    3    2    1    0
  ; Add 0 . 0003 1152 6479 7507 7883
  miles0 =                  miles0 + 7883 
  miles1 = miles0 / 10000 + miles1 + 7507 : miles0 = miles0 // 10000
  miles2 = miles1 / 10000 + miles2 + 6479 : miles1 = miles1 // 10000
  miles3 = miles2 / 10000 + miles3 + 1152 : miles2 = miles2 // 10000
  miles4 = miles3 / 10000 + miles4 + 0003 : miles3 = miles3 // 10000
  miles5 = miles4 / 10000 + miles5 + 0    : miles4 = miles4 // 10000
  Return

ShowDistanceTravelled:
  SerTxd( #miles5, "." )
  w0 = miles4 : Gosub ShowChunk
  w0 = miles3 : Gosub ShowChunk
  w0 = miles2 : Gosub ShowChunk
  w0 = miles1 : Gosub ShowChunk
  w0 = miles0 : Gosub ShowChunk
  SerTxd( CR, LF )
  Return

ShowChunk:
   BinToAscii w0, d5, d4, d3, d2, d1
   SerTxd( d4, d3, d2, d1 )
   Return
Code:
Started MPG-001.bas
1.00000000000000004430
2.00000000000000008860
3.00000000000000013290
4.00000000000000017720
5.00000000000000022150
6.00000000000000026580
7.00000000000000031010
8.00000000000000035440
9.00000000000000039870
10.00000000000000044300
As can be seen there's some discrepancy but that can be improved by adding more least significant digits to the data, having a more accurate calculation of 1/3210. But on the other hand it's so insignificant that, even over 100 miles, the data resolution could be reduced, less words used.

I should also add the usual caveats about interfacing with vehicle electronics, the risks and potential insurance issues involved. It's not something we would recommend without appropriate experience and understanding but, with that said, can take it as read that you will make a sensible and informed decision and we don't need to argue those issues here.
 

neiltechspec

Senior Member
Hippy, interesting ideas. I shall digest further.

I am well versed with using the likes of PICAXE in automotive enviroments, my classic has 6 of them in use already (none in safety critical areas).

My home constructed electronic speedo / (PICAXE) odometer writes to FRAM every 10th of a mile, so with lots of switch off / switch on cycles can potentially under read over time but the actual loss isn't that great in reality. On long runs, its accuracy is better than 1 in 500 miles. Compared to the original analogue mechanical speedo, it is more accurate. Back in the 1970's or before, that level of accuracy wasn't of primary concern.
 
Last edited:

hippy

Technical Support
Staff member
So the hard part is converting this into readable info on a 2 or 3 dig 7 seg display.
On that substantive part, I would suggest using an MAX7219 display module. Those are fairly cheap, readily available, can drive up to 8 digits which allows more data to be displayed. There are also some 4-digit modules as well.

The best part is they only need three control lines, DATA, CLOCK and LOAD and there should be plenty of code available. With a word variable holding a scaled value it should be fairly easy to get the digits to the display.

https://www.google.com/search?q=max7219+7-segment+modules&tbm=isch
 

PhilHornby

Senior Member
The full code is also available here : http://mpguino.wiseman.ee/eng/manual
Those two code-bases are not the same. Checking back through the archives, it seems that MPGUINO was a commercial 'branch' of that earlier work. It seems to have been somewhat abandoned and the code placed in the public domain.

I know the injector flow rate - 480cc minute & can take the injector opening pulse X the number of injectors (2)
which should give me the fuel flow rate.
e.g at idle injector timing is 3.5ms approx with 2 pulses per rev per injector (alternating) - it's a V8.

So the hard part is converting this into readable info on a 2 or 3 dig 7 seg display.
I disagree :) the display part's easily doable on Picaxe :-

25550

This is a 20x4 Sainsmart LCD (which only needs two wires). You can PWM the backlight for brightness control. I nicked the 'glyph' code from somewhere and converted it to Picaxe... I can share! :) .

MPGUINO (or its predecessor) did something similar but used a smaller display.

Regarding the measurement of the injector pulse:

These pulses are surely far too short to time with any resolution/repeatability on a Picaxe? [3.5mS @ tickover, so max 20mS at max revs. (ish)?].

Maybe you could do it the other way round: as in, accumulate the total injector opening time, over a set number of VSS pulses?

(Setup PWM so as to feed one of the inbuilt Timer/Counters and gate it with the Injector signal (beware the 75V back-EMF!). After a set number of VSS pulses read and reset the Timer).

I've not done any calculations, as to the resolution this method might achieve. Obviously the PWM frequency and no. of "VSS" pulses are the pertinent variables.
 
Last edited:

neiltechspec

Senior Member
I didn't mean the displaying it. I meant the maths calculations.

Wouldn't entertain using a display like that - no way thats readable when driving. So 2 digit 7 seg is what I would use.
 

oracacle

Senior Member
See HERE

(Wayback Machine to the rescue! 🔐)
Completely forgot about the way back machine.
Any how, the code uses allot of command that are not accepted anymore. From my brief look through it makes use of no longer accepted commands. Interestingly it also has labelled a pins for both injector open and injector shut, I presume for measuring the injector open duration. The other thing is as far as I have read it makes use of 64 bit integer maths with no floating point. There is at least 2 timers used as well

I will try and get a bit more reverse engineering later. I have another 3 projects on the go so it may take a couple of days.
 

oracacle

Senior Member
Not a full reverse engineering but, their system makes use of multple interrupts and a reasonably fast loop.
There are 2 interrupts in relation to the injector, one for opening and one for closing. The background clock is used to measure the time period between each of the events in microseconds. A second timer, timer2, is used to check for events such as button presses as well as incrementing it overflow timer. This is achieved by using the timer 2 interrupt.
A further interrupt is then used to monitor thee entire C port for change, the VSS is captured here. On a pulse the interrupt is terriggered and the timer2 ovefrlow count captured, the next time the VSS changes (I dont know if its just change, or on an edge), the timer2 overflow counter us used to capture the number of milliseconds that have eleapsed between VSS pulses.

This does make use of multiple interrupt service routines, something that isn't currently supported on picaxe, I haven't played enough with timers to know if you can make use of multiple timers without poking/peeking the registers. The maths is all 64 bit interger, using 32bit/long word variables. I haven't gotten as far as finding how it deals with decimals places, I think it maybe burried somewhere in the display routines - that where I would put it anyway.

The code is old. but it very higly optimised for what it is doing, MPG, MPH, Trip counter, average speed, average fuel mpg, and a few other bits.

Code:
ISR( PCINT1_vect ){   
  static byte vsspinstate=0;      
  byte p = PINC;//bypassing digitalRead for interrupt performance
This is the most obvious example of the optimising of the code. I don't know how the underlying PIC of picaxes work, but for atmel and arm microcontrollers, and interrup is normally activated by any pin on a port, then either the compiled code or the bootloader deals with it on a pin by pin level. In this case he deals with the entire port at one time, a simple byte comparison takes just one clock cycle instead of 8 to check each pin.
He also wrote a mths routines to save nearly 4000 byte of space.
 

PhilHornby

Senior Member
I converted it to Picaxe Basic...

Rich (BB code):
symbol MPG = b2
do
      Random W0
      MPG = b0 & %00011111
      sertxd ("MPG=",#MPG,cr,lf)
      pause 2000
loop
The results look comparable to readings from OEM equipment 😛

(Though %00001111 might give better results for a 1972 V8!)
 

hippy

Technical Support
Staff member
I note from this web site that the injector pulse measurements are going to need a fair amount of resolution, to make sense.
That should be possible with the right PICAXE. Using a Gated Timer as a counter it is possible to measure a pulse to 1us resolution and even greater. With a notional idling pulse of 2ms and 1us resolution that would be give 0.05% accuracy and that increases as pulse width does. I am thinking that could be acceptable.

Rather than interrupt at the start of the pulse, one can configure the counter to start counting when the pulse goes high, interrupt at the end of the pulse, read what the counter says, and prepare it for counting the next.

I have never had an MPG readout on any of the cars I have owned so had never thought about what was involved. My original thinking of a fixed amount of fuel per pulse, per revolution, appears to have been naive or at least out-dated so I'm going to accept it is somewhat more complicated than I imagined but should still be doable.

The issue of accuracy and resolution I ran into was in dividing a largish distance travelled by a comparatively smaller amount of fuel used, especially if trying to get a result to one or two decimal places. I'm hoping 32-bit divides will resolve that issue.
 

PhilHornby

Senior Member
I have never had an MPG readout on any of the cars I have owned so had never thought about what was involved.
The OP doesn't say why instantaneous MPG is required (rather than say, average over a tankful), but like @Alleycat, I've never found it useful. I once tried to measure the effect Air Conditioning had on MPG (with the car on cruise control), but I never got a sensible answer. (For some peculiar reason, my motorcycle can display instantaneous mpg - but I would have to stop and put my reading glasses on, to make use of it :unsure: )

I'd be more inclined to decode the analogue output of the Fuel Tank level sensor, for long term MPG measurement (or use a Vacuum Gauge, if I was overcome with a desire to save fuel). The vehicle may have a Manifold Pressure sensor, that can be read by a Picaxe ...

It did strike me, that with a two-digit readout, there are only 100 possible answers - probably 30, in reality! You could take an average answer (say 15), and decrease it, based on how fast you're travelling - at the same increasing it, depending on how short the injector pulses are. The result might be out by a couple of mpg, but hey, big deal!

Or slightly more scientifically, 'calculate' the possible answers using Excel and use the VSS and Injector pulses as a lookup, into an array of possible answers - a 'map' if you will. Add in vacuum readings, ignition advance and the throttle position sensor and you've reinvented the ECU :) )
 

neiltechspec

Senior Member
I wasn't aware I had to justify my reason for wanting it.

I think I'll just end up summing a few engine cycle squirts which will give me the l/min.
That will probably be adequate for what I want.

Anything else is just far to complex, but thanks for the valuable input from some.
 

AllyCat

Senior Member
Hi,

PICaxe is not well-suited to intensive Interrupt operation because the basic (Polled) Interrupt .. RETURN instructions alone take more than 3ms (at 4 MHz) compared with a simple IF ... THEN taking 1 ms, so a well-designed polling loop will probably be more efficient. Also there is no need to detect every Fuel or Odometer pulse, because their period won't be continuously changing rapidly. So a simple "instantaneous" sampling method as described above should work perfectly well for the maximum 1% resolution of a 2 digit display. The most difficult part is probably estimating the passage of time, because PICaxe doesn't have an accurate native RTC capability.

However, experience has told us that instantaneous mpg values are not generally very useful, but conceptually, one could continuously take a "running average" of all the instantaneous values to give something more useful....... In practice, you can't simply average mpg values (as you can't average mph values over fixed time intervals), but it would be easy to accumulate Fuel and Distance values into 32 bit data fields and then divide the 16 most significant (Distance) bits by the corresponding 8 most significant (Fuel) bits (to give a byte result at better than +/- 1%). If my calculations are correct, 32 bits (i.e. 4 * 109 or two Words) can store Cm or Inch units up to around 40,000 km or miles, and microlitres to 4,000 litres or 1,000 gallons! ;)

Cheers, Alan.
 

Buzby

Senior Member
... instantaneous mpg values are not generally very useful, ...
My 10 year old Mercedes has an instantaneous MPG display. The display is a vertical bar graph, and it responds very quickly.

It's informative to see just how much effect a 'light' or 'heavy' foot affects consumption. Even on a steady 'cruise controlled' motorway drive it's possible to see the consumption vary at each slight change in road conditions.

It's not better or worse than an 'average MPG' display, it's different.
 

hippy

Technical Support
Staff member
I think I'll just end up summing a few engine cycle squirts which will give me the l/min.
Just start by reading some pulse widths and reporting what they are, what amount of fuel that represents, check the numbers make sense and seem good enough to move on.

You might want a passenger reading numbers and writing them down, perhaps getting a new reading whenever a button is pushed, or you could log values for later retrieval.

Once a project is underway it's usually easier to see where to go next. Keep a copy of working versions, then it's easy to back-track if some direction doesn't work out as planned.
 

AllyCat

Senior Member
Hi,
... Even on a steady 'cruise controlled' motorway drive it's possible to see the consumption vary at each slight change in road conditions.
That was my point, the display is almost meaningless unless you can maintain an exactly constant speed and have a very precise gradient detector (which could be quite an easy project for a PICaxe with a BMP280 or similar Barometric Pressure (i.e. altitude) sensor). ;)

Cheers, Alan.
 

MartinM57

Moderator
If you want to record the data, it might be worth looking at this: https://picaxeforum.co.uk/threads/serial-data-recorder.32734/ which records sertxd output onto a memory chip for later reading/processing.
....getting a bit off-topic, sorry....

Nice project - well done :)

I had a similar need some time ago and found the (free) "Serial USB Terminal" app for Android phones,

With a cheap TTL to USB converter card and a USB OTG connector into my Samsung S9 phone I found it excellent - all baud rates, essentially infinite capacity, ability to save to files (and then share them out of the phone to OneDrive/Whatsapp/email etc) and very easy to use.

Recommended.

(I was contemplating moving to an iPhone, but I can't find any equivalent app in the Apple ecosystem :()
 

oracacle

Senior Member
To me that looks a little too instantanious. a series of readings of a second or two, average that to get your readings. This will allow a little hysteresis.
I have a modern motorbike with an instantanious MPG and it doesn't update that fast. It does flucuate, but not wildly.
 

AllyCat

Senior Member
Hi,
I ... know the pulses per mile, which is 3210 or 321 for 1/10th of a mile.
I know the injector flow rate - 480cc minute & can take the injector opening pulse
So the hard part is converting this into readable info on a 2 or 3 dig 7 seg display.
The maths really isn't difficult and the units that I guessed at in #26 look almost ideal. The 32 bit variables top out at 40,000 miles (or km) and 1,000 gallons, i.e. 40 mpg (or km) which seems about right for a Classic V8 for a long(er) term average, that might even cover the life of the car. :) But single Words (of 16 bits) will be sufficient for an instantaneous value, i.e. a maximum distance of 65,535 inches represents just over a mile (or centimetres limit at 655 metres). 65,535 microlitres is 65.5 cc or 0.0144 gallon (UK).

Each distance pulse represents 19.74 inches (or 50.1 cms could be more convenient) so you might want to sum several pulses (or simply multiply by a constant) to get a convenient integer value with sufficient resolution. 480cc/min is 8cc/sec, 8mL/sec or 8 uL/ms. PULSIN measures directly in 10us (0.01ms) increments but Phil's link in #22 suggests that you might need to subtract about 0.75 to 1 ms before multiplying by the flow rate. These Distance and Fuel values need to be applied over equivalent time intervals, which can be calculated from the drive-train ratio, or by measuring also the inter-pulse gaps (using PULSIN for the opposite pulse polarity). A possible advantage of this inverted PULSIN measurement method is that it gives a true average for an exact (integer) number of revolutions (crankshaft or transmission) and not over an arbitrary time interval (which might contain an extra or missing pulse).

There are 63.36k inches in a mile and 4,546k microlitres in a gallon so the conversion of uL/inch to mpg is 4546/63.36 = 71.75 . For optimum accuracy using standard PICaxe division, the Distance (numerator) should be approaching (but not exceed) a value of 65,535 and the Fuel (divisor) around 1,000 (e.g. for a result of 65 mpg) so the aim is to introduce the calibration and scaling factors into the calculation sequence as appropriate.

For a longer term average, the instantaneous values can be added to the Low Word of the accumulating registers and if the result word is a smaller number, then a carry must have occurred, therefore increment the High Word (e.g. w2 = w2 + w1 : IF w2 < w1 THEN : INC w3 : ENDIF ) . Then before the division stage, repeatedly scale down (or up) the Distance (e.g. w3 : w2) and Fuel (e.g. w5 : w4) values by 2 , e.g. by a Right (or Left) shift, until the High Word is zero (or > $7FFF), for example :
Code:
symbol carry = w0
DO WHILE w3 > 0          ; Or < $8000 for Left-Shifting
  carry = w3 * $8000     ; All except the LS bit overflow
  w2 = w2 / 2 + carry    ; Shift right
  w3 = w3 / 2
  carry = w5 * $8000
  w4 = w4/ 2 + carry
  w5 = w5 / 2 
LOOP
Or, particularly with M2 PICaxes, Left-Shifting is easier and would be faster for (32-bit) averages above about 100 miles or 4 gallons. ;)

Cheers Alan.
 

neiltechspec

Senior Member
At the moment, for the sake of simplicity, I have gone with just measuring the
injector pulses (4 times a sec). This might tell well tell me all I wanted to know anyway.

Re-purposed a 2 dig ds18b20 temp guage I made a few years ago that is now redundant.
To me it is important that it looks the part, so it's all inside a 2" guage.

Just got to wait for it to warm up a bit in the garage now - temp has gotta be into double digits for
me to be messin about in the footwell to extract & replace the ECU.

Pulse 1.jpgPulse 2.jpg
 
Top