Problems with sending can bus message using arduino DUE

hi there,

to make it short....

project:
i want to install another gauge cluster in my car. due to some can bus messages comming from the cluster causing the cars transmission control unit to go into emergency mode, and also the fact, that several messages (speed, tachometer, water temp, nearly all warning indicators are based on different can bus messages, i decided to go for 2x separate can bus and "translate" the datas from CAN0 and send them to CAN1. so my thought.

441b1cd52560ed6c05a3cf24e1d557cca1da3fcb_2_690x339

the picture differs a bid cause i´m not using the MCP2515.

what i have:

  1. i have an arduino DUE and 2x SN65HVD230.
    i connected them as described here: CAN bus with Arduino Due - openinverter.org wiki

  2. i have also an arduino uno with can bus shield, using to send can bus messages.

my code (based on Can-SendingTest sample code):
//Reads all traffic on CAN0 and forwards it to CAN1 (and in the reverse direction) but modifies some frames first.
// Required libraries
#include "variant.h"
#include <due_can.h>

//Leave defined if you use native port, comment if using programming port
#define Serial SerialUSB

void setup()
{

Serial.begin(115200);

// Initialize CAN0 and CAN1, Set the proper baud rates here
Can0.begin(CAN_BPS_500K);
Can1.begin(CAN_BPS_500K);

Can0.watchFor();
}

void loop(){
CAN_FRAME incoming;

CAN_FRAME outgoing;
outgoing.id = 0x60D;
outgoing.extended = false;
outgoing.priority = 4; //0-15 lower is higher priority
outgoing.data.byte[0] = 00;
outgoing.data.byte[1] = 0x46;
outgoing.data.byte[2] = 00;
outgoing.data.byte[3] = 00;
outgoing.data.byte[4] = 00;
outgoing.data.byte[5] = 00;
outgoing.data.byte[6] = 00;
outgoing.data.byte[7] = 00;

if (Can0.available() > 0) {
Can0.read(incoming);
Can1.sendFrame(outgoing);
}

}

problem:
when there is a code reading on CAN0 it should trigger CAN1 to send the "outgoing CAN_frame), but it did not.
if i change "Can1.sendFrame(outgoing);" to "Can1.sendFrame(incoming);", it send the can message from CAN0 to CAN1.
so there is an error in my section with the outgoing frame.

i have modified the code to display received and send can bus messages and this is what is shown in serial monitor:

here is the modified code:
//Reads all traffic on CAN0 and forwards it to CAN1 (and in the reverse direction) but modifies some frames first.
// Required libraries
#include "variant.h"
#include <due_can.h>

//Leave defined if you use native port, comment if using programming port
#define Serial SerialUSB

void setup()
{

Serial.begin(115200);

// Initialize CAN0 and CAN1, Set the proper baud rates here
Can0.begin(CAN_BPS_500K);
Can1.begin(CAN_BPS_500K);

Can0.watchFor();
}

void sendData()
{
CAN_FRAME outgoing;
outgoing.id = 0x60D;
outgoing.extended = false;
outgoing.priority = 4; //0-15 lower is higher priority
outgoing.data.byte[0] = 00;
outgoing.data.byte[1] = 0x66;
outgoing.data.byte[2] = 00;
outgoing.data.byte[3] = 00;
outgoing.data.byte[4] = 00;
outgoing.data.byte[5] = 00;
outgoing.data.byte[6] = 00;
outgoing.data.byte[7] = 00;
Serial.print("send: ");
printFrame(outgoing);

Can1.sendFrame(outgoing);

}

void printFrame(CAN_FRAME &frame) {
Serial.print("ID: 0x");
Serial.print(frame.id, HEX);
Serial.print(" Len: ");
Serial.print(frame.length);
Serial.print(" Data: 0x");
for (int count = 0; count < frame.length; count++) {
Serial.print(frame.data.bytes[count], HEX);
Serial.print(" ");
}
Serial.print("\r\n");
}

void loop(){
CAN_FRAME incoming;
static unsigned long lastTime = 0;

if (Can0.available() > 0) {
Can0.read(incoming);

Serial.print("received: ");
printFrame(incoming);
sendData();

}

}

what is my problem, that it did send out an empty can message?

currently testing a bid, using my arduino uno with can bus shield for sniffing and trying to just send can bus messages through my arduino DUE.

turns out, that there is difference between these librarys which are for arduino uno
#include <Canbus.h>
#include <defaults.h>
#include <global.h>
#include <mcp2515.h>
#include <mcp2515_defs.h>

and the librarys which is for arduino DUE...

#include "variant.h"
#include <due_can.h>

... in view to writing the can bus message. while writing this
message.id = 0x60D; //formatted in HEX
message.header.rtr = 0;
message.header.length = 8; //formatted in DEC
message.data[0] = 00;
message.data[1] = 0x66;
message.data[2] = 00;
message.data[3] = 00;
message.data[4] = 00;
message.data[5] = 00;
message.data[6] = 00;
message.data[7] = 00;

for arduino uno, it sends directly the message i want...

ardunio Due library with this message...

outgoing.id = 0x60D;
outgoing.extended = false;
outgoing.priority = 4; //0-15 lower is higher priority
outgoing.data.byte[0] = 00;
outgoing.data.byte[1] = 0x66;
outgoing.data.byte[2] = 00;
outgoing.data.byte[3] = 00;
outgoing.data.byte[4] = 00;
outgoing.data.byte[5] = 00;
outgoing.data.byte[6] = 00;
outgoing.data.byte[7] = 00;

did send an empty can bus message.

once adding outgoing.data.high = 0xDEADBEEF; it throws out this can bus message on the serial monitor...
ID: 60D, Data: 80 66 0 0 EF BE AD DE

so... what i see is that the DEADBEAF comment throws out the reverse readed bits 5, 6, 7 and 8, which are "EF BE AD DE".
so i googled it and try to understand what "hexspeak" is and what its used for, but i don´t understand to be honest.
another point is, that is throws out "80" instead of "00" for the first bit.

if there is someone who could explain me this, it would be awesome.

changed the code to this

void loop(){

CAN_FRAME outgoing;
outgoing.id = 0x60D;
outgoing.length = 8;
outgoing.priority = 4; //0-15 lower is higher priority
outgoing.data.byte[0] = 00;
outgoing.data.byte[1] = 0x66;
outgoing.data.byte[2] = 00;
outgoing.data.byte[3] = 00;
outgoing.data.byte[4] = 00;
outgoing.data.byte[5] = 00;
outgoing.data.byte[6] = 00;
outgoing.data.byte[7] = 00;

Can1.sendFrame(outgoing);

delay(500);

now the last 4x bytes did show correctly, but i do still not understand what causes the first byte to show "80" instead of "00".

any idea?

so i played around and note following.

the first byte seams to have 128 decimal and output this as hex 80. if i write
" outgoing.data.byte[0] = 11;" for example, it throws out hex 8B, which is in decimal 139.
so 139-11=128

any idea where the 128 in first byte comes from?

Hi,
To add code please click this link;

Your code will then be in a scrolling frame that will make it easier to read,

A circuit diagram of your project would be good, a pen(cil) and paper will be fine, unless you have a CAD that will do component symbols.

Tom.... :smiley: :+1: :coffee: :australia:

thanks. i will read how to add the code correctly.

i solved the problem now. unbelievable stupid mistake :rofl:

there was an error in the sample sketch of the arduino uno spark fun library, for reading codes..., called CAN_Read_Demo.

someone forgot to let space between data lenght and first byte. so the showed "80" which i read as 80 for the first byte, but in fact it was "8" byte lenght and "0" for first byte. testing the "11" decimal on first byte did not causes to display "8B" (which would be 139), but "B", which is 11 in decimal. so 80 which is 128decimal and 8B which is 139decimal (=128-11), was just a stupid coincidence. found out the problem once send the 11 as 0x11, which caused to display "811" in serial monitor, which brought me the idea of this stpid mistake.

:sweat_smile:

so now i stand in front of another problem.

once adding a second to send frame, the ID of the first frame gets lost.

here is the code:

void loop(){
  
  CAN_FRAME outgoing;
  outgoing.id = 0x60D;
  outgoing.length = 8;
  outgoing.priority = 4; //0-15 lower is higher priority
  

        outgoing.data.byte[0] = 0x00;
        outgoing.data.byte[1] = 0x66;
        outgoing.data.byte[2] = 0x00;
        outgoing.data.byte[3] = 0x00;
        outgoing.data.byte[4] = 0x00;
        outgoing.data.byte[5] = 0x00;
        outgoing.data.byte[6] = 0x00;
        outgoing.data.byte[7] = 0x00;

  Can1.sendFrame(outgoing);

  delay(500);

  CAN_FRAME outgoing2;
  outgoing2.id = 0x25D;
  outgoing2.length = 8;
  outgoing2.priority = 4; //0-15 lower is higher priority
  

        outgoing2.data.byte[0] = 0x00;
        outgoing2.data.byte[1] = 0x00;
        outgoing2.data.byte[2] = 0x42;
        outgoing2.data.byte[3] = 0x00;
        outgoing2.data.byte[4] = 0x00;
        outgoing2.data.byte[5] = 0x00;
        outgoing2.data.byte[6] = 0x00;
        outgoing2.data.byte[7] = 0x00;

  Can1.sendFrame(outgoing2);

  delay(500);
}

which causes this in serial monitor:
...
ID: 0, Length: 8 Data: 0 66 0 0 0 0 0 0
ID: 25D, Length: 8 Data: 0 0 42 0 0 0 0 0
ID: 0, Length: 8 Data: 0 66 0 0 0 0 0 0
ID: 25D, Length: 8 Data: 0 0 42 0 0 0 0 0
ID: 0, Length: 8 Data: 0 66 0 0 0 0 0 0
ID: 25D, Length: 8 Data: 0 0 42 0 0 0 0 0
ID: 0, Length: 8 Data: 0 66 0 0 0 0 0 0
ID: 25D, Length: 8 Data: 0 0 42 0 0 0 0 0
...

i had to put { before each "CAN_FRAME" and } after "Can1.sendFrame(outgoing);" and "Can1.sendFrame(outgoing2);" , now it works.