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.
Arduino CanBus message question
- 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
take byte 4, multiply it by 256 and add byte 3. Divide by 4TonyV 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.
-
- 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
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);
#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
- 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
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.
-
- 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
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
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
I'll figure this out sooner or later
-
- 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
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.
-
- Posts: 1801
- Joined: Sun Apr 03, 2022 1:57 pm
- Has thanked: 102 times
- Been thanked: 349 times
Re: Arduino CanBus message question
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.
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.
- 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
you must of course put the sum in parentheses so that everything together is divided by 4, and not just the one byte