Using Arduino to read CAN Bus of my vehicle. I have this setup to monitor fuel usage however it seems to still operate when the no CAN signal is sent.
The IF Statement says if CAN message has specific "ID". ( I am 99% this ID is only sent when the vehicle is on and running.)
However when I turn the vehicle off and come back a few minutes later my Variable TotalFuelUsed is much higher. I leave the Arduino powered 24/7 during testing as to not have to use EEPROM.
It seems to still be adding to itself even when the IF statement is not true (no CAN message coming in, vehicle is off). I know the Millis function keeps incrementing 24/7 as the arduino is always on but my timer should not update unless the correct CAN message ID is sent I believe.
Anyway it seems TotalFuelUsed keeps incrementing upwards when the IF statement is false. I need it to hold at the value it was when the last message was received and not update again until a new message is received. (Next time the vehicle is started)
Side note: Anyone have a better way of storing the time between messages received?
if(msg.id == 929){ //If Can Message ID is Fuel Info
FuelUsedTime = CurrentMillis - StoredTime; //FuelUsedTime=Time between readings
StoredTime=CurrentMillis; //StoredTime equals current Time
FuelSignal = (msg.buf[4] << 8) | msg.buf[5]; //Fuel Signal is value in CAN Message.
MlSec=(FuelSignal/3600)*((Rpm/2)/60); //Fuel Burned in Ml per Second
MlUsed=MlSec*(FuelUsedTime/1000); //Fuel Burned in Time Interval ML
TotalFuelUsed=(TotalFuelUsed+MlUsed); //Total Amount of Fuel Used
}
Post all the code or a small example that compiles, runs and illustrates the problem.
You could do some printing within the block you think isn’t running, that might surprise you and demonstrate that it is. Being execute. Even if you think it can’t be doing.
I figured out what the problem is, and the IF statement is working properly.
The Variable FuelUsedTime is supposed to represent the time between readings of a message. At vehicle idle the signal comes every 1.6 seconds at 70 Mph it comes ever 0.5 seconds. So each time I get a reading I store the current mills and then subtract it from the "Stored Time" the millis value of the previous reading. This works great as long as vehicle and arduino are both on at the same time.
When the vehicle is Off the adrunio clock keeps running, the next time I turn the vehicle on the Millis time is much much higher while the stored time is from the last reading when I turned the vehicle off before. That means the Time interval on the first reading is HUGE, the longer the vehicle sits off the bigger it is. I turned it off for a few seconds and my first reading interval was 25 seconds (should be 1.6),
I use the Time interval in my calculation, so its multiples the first huge time interval by the last signal reading and adding a large amount of my var TotalFuelUsed on the first reading of startup.
I need a better way to determine time between signal readings when the vehicle is on, and to not get variation when the vehicle is off but arduino clock is still running.
I have it set to read a CAN message for Key Off which puts my display to sleep.
I just had a thought that I could add an IF Key=ACC then reinitialize the "Stored Time" to the current Mills. I could also initialize an Engine Run Timer to 0 here.
If I did it when Key=ON it would always be reinitializing because it would see a Key ON signal every 1-2 seconds. But if it only runs when Key=ACC then it would be reset properly right before each engine start and if you leave the Key in ACC say to listen to the radio, it would keep resetting its self until start which should be fine.
I just did a quick remap of the Key signal on the CAN Bus. It slightly changes the byte value for Key Off, Acc, On, and Start.
I reset my IF statement to wake the display on the ACC signal, and put it to sleep on the OFF signal.
I put in an additional statement to reinitialize my "Stored Time" to the current millis on the start signal. It only happens briefly and resets my stored value once starter engages. Then the loop takes care of the rest as fuel signals are read from the CAN bus.
I went ahead and also reset the Stored Time on ACC also incase we miss the Start byte change. Its more of a backup. So now as you turn the key to start the vehicle the time is reset at ACC position and then again on Start position. So far in testing it has caught every start signal reset, if it misses the ACC would have still reset it but its about a second bigger than when the Start signal resets it. Takes time to get from ACC position to full running.
If I did it off the RPM signal it would have to know to reset within the first second of time, (I would have to assign a time range) then ignore the reset command as the RPM signal comes continually as the engine is running.