# Calculating fuel consumption averages from can bus data

• 11-15-2019, 09:02 AM
keith-i
Calculating fuel consumption averages from can bus data
The challenge:
To take consecutive readings from bytes 2 and 3 of frame 0x480 of can bus and calculate average fuel consumption. Bytes 2 & 3 give a continuous incremental reading of fuel consumed in microlitres. (Note: the first bit of data is just a marker bit so the data is only 15 bits long).

Requirements:
To get accurate timestamp of data
To keep a rolling average to smooth out data
To deal with rollover of time and fuel data. e.g. as fuel consumption data is 15 bit it reaches hex 7FFFFFF (dec 32767 ) before rolling back to zero

Managed so far:
To obtain continuous output from 0x480 with flexcan timestamp

Sample data:
Timestamp-- bin-- dec
31910-- 111111111101111-- 32751
41943-- 111111111110100-- 32756
51976-- 111111111111001-- 32761
62008-- 111111111111110-- 32766
6506-- 11-- 3
16537-- 1000-- 8
26569-- 1101-- 13
36602-- 10010-- 18
46636-- 10111-- 23
56668-- 11100-- 28

Code theory:
Code:

```        fuel = ((( inMsg.buf[3]&0b01111111)<<8)+inMsg.buf[2]);         if fuel2>fuel1         fuelused = fuel2-fuel1         else fuelused=((fuel2+32767)-fuel1)             if time2>time1         timediff = time2-time1         else timediff=((time2+65535)-time1)         fuelrate = (360/timediff)*fuelused```
Question:
How do I get sequential readings from 0x480 so that I can obtain fuel1, fuel2, time1 & time 2 to then perform my calculation?

How do I keep a rolling average of the readings to smooth the data?

Main code for reference:
Code:

```void PollEngineCAN(){ //function to poll engine data   CAN_message_t inMsg;     if (Can1.available()>0){       Can1.read(inMsg); //read message into inMsg       switch ( inMsg.id ) { //a type of if process that can check for multiple conditions         case 0x280:           torque = ( inMsg.buf[1]*0.39 );           rpm = ((( inMsg.buf[3]<<8)+inMsg.buf[2])/4);           LastRPM=millis(); //timestamp the last rpm reading           break;         case 0x288:           coolant = (( inMsg.buf[1]*0.75)+225.15); //convert from C to K (-48 + 273.15 = 225.15)           break; //        case 0x480: //        if/else required here //        e.g. if fuel2>fuel1 then fuelused = fuel2-fuel1 else fuelused=((fuel2+32767)-fuel1) //        fuel = ((( inMsg.buf[3]&0b01111111)<<8)+inMsg.buf[2]); //factor into l/h //        break;         case 0x588:           boost = ( inMsg.buf[4]*1000 ); //convert from bar to Pa (*0.01 x 100,000 = 1000)           break;       }      }   }```
• 11-15-2019, 10:22 AM
tonton81
Check out the circular buffer example for average() usages

https://github.com/tonton81/Circular...cal_Values.ino

Just keep pushing the value in the buffer, and the averages will adjust. The oldest value in the list is rolled over, so no need to purge older values