Multiple Interrupts - Fuel Consumption

My new project is the design and implementation of a fuel consumption measuring and logging system for a race car. I can work out the overall consumption via litres to fill up vs kms travelled but this only shows the average. I need to know how much is used whilst driving around town and how much is used whilst competing.

I have bought a quality fuel flow meter that works via a hall effect sensor. I have another hall effect sensor measuring the wheel rotation.

Using distance travelled and fuel litres consumed I will get the L/km figure. This will be displayed on a TFT touch display and the data logged to an SD card via stop/start button.

I have approximated that the wheel will see 150 pulses per second and the fuel sensor will see 60 pulses per second.

The Loop() will probably just have a basic L/km calculation, writing to the TFT, saving to the SD card.

My question:

My initial plan is to use interrupts for the 2 hall effect sensors. My concern is that there is a risk that I may miss pulses from one or the other hall sensors but I need accurate values. What happens when both sensors pulse at the same time (which will naturally regularly occur)? How slow will the SD write be (maybe 20 bytes of info)? Am I likely to have enough time between the pulses to get the data processed?

I have also considered using one Arduino Nano for the wheel sensor, one Nano for the fuel sensor then a third Nano to pull the figures together, do the calcs and log the data. Sounds overkill?

Just after some guidance before I spend hours on this......

Mk1_Oz:
...My concern is that there is a risk that I may miss pulses from one or the other hall sensors but I need accurate values. What happens when both sensors pulse at the same time (which will naturally regularly occur)...

Hi,

What do you mean by "the same time"?

Regards.

vffgaston:
Hi,

What do you mean by "the same time"?

Regards.

Well exactly that. There will be times when both hall effect sensors send out a pulse at the same physical time to their respective Arduino pins.

Hi,

It is just impossible that two events occur "at the same time", unless you deem the event takes the time that the signal takes to go from 1->0 (or viceversa). Even in this case, one can discuss if "the same time" means things happening perfectly sincronous (in which case it is impossible again).

Perhaps what you want is to know what happens if the second event happens while the processor is executing the code for the first event. Guidelines:

1.- Make the interrupt service routines as short as possible, so that if a second event happens while they are being executed errors would be minimized.

2.- The processor will attend the second routine on leaving the first one, there wouldn't be missing events if you follow "1".

(I don't know if there's the possibility to store the time the interrupt happens while servicing another ISR. Any case, for normal applications -yours is normal- the error would be minimum).

Best regards.

If you use the two external interrupt pins to capture the pulses from the hall sensors then you won't miss anything. Just make sure that the code in the ISRs is a short as possible - perhaps something like

void wheelPulseISR() {
   wheelPulseCount ++;
   newWheelPulse = true;
}

void fuelPulseISR() {
   fuelPulseCount ++;
   newFuelPulse = true;
}

then your code in loop() can check for the new pulses and read the pulse count

...R

Thanks for the replies.

I assume the frequencies that I am dealing with are not all that high in Arduinoland?

Mk1_Oz:
I assume the frequencies that I am dealing with are not all that high in Arduinoland?

Even on a basic 16MHz Arduino, at 150 pulses per second, the Arduino can execute up to 100,000 basic machine instructions between each pulse.

What type fuel system are you using? Carbureted or injected? Is it a dead ended fuel system? I would think the flow meter might give erroneous data with a dead ended carb setup as very little fuel is moving in such a big line. If it's injected, most I know of are loop systems where there is a return line to the tank, so again- inaccurate data on flow. For accuracy there, injector pulse width is used to get accurate metering, which is what the computer uses.

As for the wheels, it might be beneficial to have all the wheels monitored, which would allow for seeing uneven locked brakes and wheelspin. You didn't specify what type of racing you are dealing with.

I do stage rallying.

The car is carburreted with a single fuel line (no return) but my calculations show there is plenty of fuel flow through the sensor so accuracy should not be an issue. At idle it might be inaccurate but I can work around that (sensor operates from 5 to 150LPH and is something like 0.6ml/pulse).

The wheel sensor is on the front wheel so no wheel spin and I don't lock brakes :wink: I did consider using a GPS for either distance or time logging but I think it unnecessary.

It sounds like a single UNO board will do the job and that the should be no issue with speed/ missing pulses.

I guess I can check the speed of the Loop() section using mills() just to be certain.

Mk1_Oz:
I do stage rallying.

The car is carburreted with a single fuel line (no return) but my calculations show there is plenty of fuel flow through the sensor so accuracy should not be an issue. At idle it might be inaccurate but I can work around that (sensor operates from 5 to 150LPH and is something like 0.6ml/pulse).

The wheel sensor is on the front wheel so no wheel spin and I don't lock brakes :wink: I did consider using a GPS for either distance or time logging but I think it unnecessary.

It sounds like a single UNO board will do the job and that the should be no issue with speed/ missing pulses.

I guess I can check the speed of the Loop() section using mills() just to be certain.

I am sure you already know the fuel flows when the float valve opens in the carburetor, not when the engine needs fuel. So you will never get an even flow of fuel.

Paul

Yes know that. Doesn't need to be even. Just need to capture the flow as it happens. The float valve is effectively always open anyway when the engine is running as the float bowl is constantly being drained albeit at uneven rates throughout the rpm/load range.

To set your mind at ease on the performance of an Uno I have an 8MHz Atmega 328 (i.e. half the speed of an Uno) controlling the speed of a small DC motor at up to 18,000 RPM (i.e. 300 pulses per second - and could probably work much faster) and the Atmega 328 also receives wireless commands for the speed setting.

...R

Those pulse speeds are indeed nothing for an Arduino. My water flow sensors put out 500-1000 pulses a second, no problem. May not even need interrupts for that as it has a 50% duty cycle, but with all the other stuff going on it makes it a lot easier.

I've timed pulses of 3-4 microseconds in length on a 20 MHz ATtiny (to get a bit better resolution than on 16 MHz).

I've counted up to 1.4 MHz worth of pulses on a 12 MHz ATtiny, albeit not using interrupts but using a counter. That way you should be able to get to 1/2 the clock speed, so up to 8 MHz on a 16 MHz Arduino.

With interrupts you don't even have to worry about loop() taking too long to go around for every single pulse. You just need your code to take into account that there may have been multiple pulses. The newWheelPulse flag is also not strictly necessary as you can check for a change in pulse count instead.

Wow these are amazing little devices. Mind at rest. Cheers

Yes they are :slight_smile: and while 16 MHz doesn't sound like much compared to modern-day computers (well, my parents' first PC was running at half that when in "turbo" mode), you can do a lot of work with it.

BTW, ignore the first reply.
In the real world - two or more events can occur ‘simultaneously’ - well within the sub-millisecond domain.
.
The trick as already mentioned by Robin2 - is to return from the ISR before another event occurs on the same interrupt you are responding to… no problem in this case.

Once you have incremented the count or ‘event’ captured, you have plenty of time to handle those states at your own time within loop().

Just remember avoid blocking code, and be aware of any function ’latency’ - like updating the LCD (a couple of mS). Usually these won’t be a problem because the interrupts are still firing and counting, but the loop() response may take a moment longer if it’s doing something else when the ISR returns.

Once you have this all working in principle, you could implement a millis() timer to check the buttons, and refresh the display - perhaps every 10mS so it appears consistent (still a lot faster than your eye will spot it!)

Sounds like a fun project.