i have made 2 converters to just simply convert an double to singles to send using any canbus library and then on the other arduino reconvert back
my own can message:
struct can_msg{
__u8 id;
__u8 dlc;
__u16 data[8];
};
the can library message mcp2515 library:
struct can_frame {
__u32 can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
__u8 can_dlc; /* frame payload length in byte (0 .. CAN_MAX_DLEN) */
__u8 data[CAN_MAX_DLEN] __attribute__((aligned(8)));
};
the functions:
can_msg dataParseTo4M(can_frame x){
struct can_msg y;
y.data[0] = y.data[0] | x.data[0];
y.data[0] = y.data[0] << 8;
y.data[0] = y.data[0] | x.data[1];
y.data[1] = y.data[1] | x.data[2];
y.data[1] = y.data[1] << 8;
y.data[1] = y.data[1] | x.data[3];
y.data[2] = y.data[2] | x.data[4];
y.data[2] = y.data[2] << 8;
y.data[2] = y.data[2] | x.data[5];
y.data[3] = y.data[3] | x.data[6];
y.data[3] = y.data[3] << 8;
y.data[3] = y.data[3] | x.data[7];
return y;
}
can_msg dataParseTo8M(can_frame x){
struct can_msg y;
for(__u8 i=0 ; i<8; i++){
y.data[i] = x.data[i];
}
return y;
}
can_frame dataParse4To8M(can_msg y){
struct can_frame x;
x.data[1] = y.data[0];
x.data[0] = y.data[0] >> 8;
x.data[3] = y.data[1];
x.data[2] = y.data[1] >> 8;
x.data[5] = y.data[2];
x.data[4] = y.data[2] >> 8;
x.data[7] = y.data[3];
x.data[6] = y.data[3] >> 8;
return x;
}
can_frame dataParse8To8M(can_msg y ){
struct can_frame x;
for(__u8 i=0 ; i<8; i++){
x.data[i] = y.data[i];
}
return x;
}
can_msg Extract(can_frame x){
struct can_msg y;
switch(x.can_id){
case 0xC0:
case 0xC1:
case 0xC2:
case 0xC3:
y = dataParseTo4M(x);
y.id = x.can_id;
y.dlc = x.can_dlc;
break;
case 0xE0:
case 0xE1:
case 0xE2:
case 0xE3:
y = dataParseTo8M(x);
y.id = x.can_id;
y.dlc = x.can_dlc;
break;
default:
y = dataParseTo8M(x);
y.id = x.can_id;
y.dlc = x.can_dlc;
break;
}
return y;
}
can_frame Convert(__u32 id, __u8 dlc, __u16 d0, __u16 d1,__u16 d2,__u16 d3,__u16 d4,__u16 d5,__u16 d6,__u16 d7){
struct can_msg y;
y.data[0] = d0;y.data[1] = d1;y.data[2] = d2;y.data[3] = d3;
y.data[4] = d4;y.data[5] = d5;y.data[6] = d6;y.data[7] = d7;
struct can_frame x;
switch(id){
case 0xC0:
case 0xC1:
case 0xC2:
case 0xC3:
x = dataParse4To8M(y);
x.can_id = id;
x.can_dlc = dlc;
break;
case 0xE0:
case 0xE1:
case 0xE2:
case 0xE3:
x = dataParse8To8M(y);
x.can_id = id;
x.can_dlc = dlc;
break;
default:
x = dataParse8To8M(y);
x.can_id = id;
x.can_dlc = dlc;
//Serial.println(x.can_id,HEX);
break;
}
return x;
}
edit:
feel like i need to add this :
canframe = Convert(0xC0,6,ID,CellVoltage[0]*0.4882,CellVoltage[1]*0.4882,0,0,0,0,0);
mcp2515.sendMessage(&canframe);
and the other way back
if (mcp2515.readMessage(&canframe) == MCP2515::ERROR_OK) {
canMsg = Extract(canframe);
value_to_send = (short)speed_calculated * 10;
will not save the fractional part. You need parentheses:value_to_send = (short)(speed_calculated * 10);
. \$\endgroup\$double
. Using floating point on 8 bitters like Arduino is a big no-no, since they don't have a FPU but have to resolve these in painfully slow and bloated software floating point libs. \$\endgroup\$