Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 2 of 2

Thread: Calculating fuel consumption averages from can bus data

  1. #1
    Member
    Join Date
    Sep 2019
    Location
    UK
    Posts
    22

    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;
          }  
        }
      }

  2. #2
    Senior Member
    Join Date
    Dec 2016
    Location
    Montreal, Canada
    Posts
    3,133
    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

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •