Arduino CanBus message question

Post Reply
TonyV
Posts: 87
Joined: Sat Nov 14, 2020 9:00 pm
Location: Toronto
Has thanked: 1 time
Been thanked: 12 times
Contact:

Arduino CanBus message question

Post by TonyV »

Hi all,
I'm using ISA shunt to give me voltage a current reading.
ID 522 is for the voltage reading.
Len is 8 bits long.
Bits 3,4, and 5 are the actual voltage reading bits.

What I'm trying to do is use the factory fuel gauge as the Battery Voltage gauge.
Factory Gauge works with PWM.

What I'm able to do is, using Bit3 only, I'm able to convert that to a PWM signal and it gives me full control of the fuel gauge.
But the issue is Bit3 goes from 0-256 then "rolls over" and starts from 0 again. When this happens Bit4 goes up by 1.
This will cause the gauge to go from Full to Empty.
This will need to happen 4 times to fully discharge and recharge the battery,

So from a fully charged battery, "Full" to "Empty" on the gauge only represents 25% of the battery capacity.
So when the gauge reads "Empty" there is still 75% of charge in the battery.

What I was hoping for is someone to explain how to i combine BITs 3,4 and 5 HEX to a 1 DECIMAL number.
This why i can MAP this in the arduino.

Hope all this maks sense.
I'll figure this out sooner or later
User avatar
muehlpower
Posts: 642
Joined: Fri Oct 11, 2019 10:51 am
Location: Germany Fürstenfeldbruck
Has thanked: 12 times
Been thanked: 120 times

Re: Arduino CanBus message question

Post by muehlpower »

TonyV wrote: Thu Jun 15, 2023 6:00 pm Hi all,
I'm using ISA shunt to give me voltage a current reading.
ID 522 is for the voltage reading.
Len is 8 bits long.
Bits 3,4, and 5 are the actual voltage reading bits.

What I'm trying to do is use the factory fuel gauge as the Battery Voltage gauge.
Factory Gauge works with PWM.

What I'm able to do is, using Bit3 only, I'm able to convert that to a PWM signal and it gives me full control of the fuel gauge.
But the issue is Bit3 goes from 0-256 then "rolls over" and starts from 0 again. When this happens Bit4 goes up by 1.
This will cause the gauge to go from Full to Empty.
This will need to happen 4 times to fully discharge and recharge the battery,

So from a fully charged battery, "Full" to "Empty" on the gauge only represents 25% of the battery capacity.
So when the gauge reads "Empty" there is still 75% of charge in the battery.

What I was hoping for is someone to explain how to i combine BITs 3,4 and 5 HEX to a 1 DECIMAL number.
This why i can MAP this in the arduino.

Hope all this maks sense.
take byte 4, multiply it by 256 and add byte 3. Divide by 4
TonyV
Posts: 87
Joined: Sat Nov 14, 2020 9:00 pm
Location: Toronto
Has thanked: 1 time
Been thanked: 12 times
Contact:

Re: Arduino CanBus message question

Post by TonyV »

Something like this?

#include <SPI.h>
#include <mcp2515.h>
MCP2515 mcp2515(10);
struct can_frame canMsg;
int fuelLevelPin1 = 3;
int fuelLevelPin2 = 6;
int y;
int x;

void setup() {
pinMode (fuelLevelPin1, OUTPUT);
pinMode (fuelLevelPin2, OUTPUT);

while (!Serial);
Serial.begin(9600);

mcp2515.reset();
mcp2515.setBitrate(CAN_500KBPS, MCP_8MHZ);
mcp2515.setNormalMode();
}

void loop() {

if (mcp2515.readMessage(&canMsg) == MCP2515::ERROR_OK)
{
if (canMsg.can_id == 0x522)// ISA Voltage ID
{
y = (canMsg.data[4]*256)+(canMsg.data[3])/4;
x = map(y, 500, 1322, 39, 140);

Serial.println(y);
Serial.println(x);
Serial.println(" ");
analogWrite(fuelLevelPin1,x);
analogWrite(fuelLevelPin2,x);
}
}

delay(10);
I'll figure this out sooner or later
User avatar
muehlpower
Posts: 642
Joined: Fri Oct 11, 2019 10:51 am
Location: Germany Fürstenfeldbruck
Has thanked: 12 times
Been thanked: 120 times

Re: Arduino CanBus message question

Post by muehlpower »

or "y = (canMsg.data[5]*256*256)+(canMsg.data[4]*256)+(canMsg.data[3]);" if you want to include Byte5. "y" must then be "long". You can omit "/4" when customizing your mapping.
TonyV
Posts: 87
Joined: Sat Nov 14, 2020 9:00 pm
Location: Toronto
Has thanked: 1 time
Been thanked: 12 times
Contact:

Re: Arduino CanBus message question

Post by TonyV »

ok,
I tried y = (canMsg.data[4]*256)+(canMsg.data[3])/4; (5th byte isn't necessary) but I'm still have the same issue.
When Discharging, byte 3 rolls over from 00 (0) to FF (255) it changes the math equation results dramatically which then messes with analogWrite.

I did a quick video to illustrate what I'm trying say
Picture is the result in the Arduino Serial Monitor.
I'm i missing something?
Thanks

Attachments
20230616_092633crop.jpg
20230616_092633.jpg
I'll figure this out sooner or later
royhen99
Posts: 250
Joined: Sun Feb 20, 2022 4:23 am
Location: N. Wiltshire. UK
Has thanked: 21 times
Been thanked: 121 times

Re: Arduino CanBus message question

Post by royhen99 »

It looks like the data is little endian so it's just going from 0x500 to 0x4FF, 1280 to 1279 dec, not sure where 1087 ( 0x43F ) came from. If you want 1200 to be the minmum you need if (x < 1200) x = 1200; as map will just produce a negative number. Without the /4 in your calculation 1200 is about 307V and 1330 340.5V, is this the range you are looking for? The voltage reading from the IVT-S is bytes 2 - 5, if you included byte 2 in the calculation the range to map would be the voltage in mV.
Pete9008
Posts: 1801
Joined: Sun Apr 03, 2022 1:57 pm
Has thanked: 102 times
Been thanked: 349 times

Re: Arduino CanBus message question

Post by Pete9008 »

Should it be this?

y = ((canMsg.data[4]*256) + canMsg.data[3])/4;

If canMsg.data is an unsigned char you may need the following cast too (the 256 should be an int anyway so probably not needed but good practise in any case) :

y = ((((unsigned int)canMsg.data[4])*256) + canMsg.data[3])/4;

As mentioned above you can lose the /4 and change the map input range to suit instead.
User avatar
muehlpower
Posts: 642
Joined: Fri Oct 11, 2019 10:51 am
Location: Germany Fürstenfeldbruck
Has thanked: 12 times
Been thanked: 120 times

Re: Arduino CanBus message question

Post by muehlpower »

you must of course put the sum in parentheses so that everything together is divided by 4, and not just the one byte
Post Reply