The intention of this tutorial is to provide an example on how to intercept, modify and re-transmit a specific CAN message while “passing through” all other messages untouched using the CANFDuino . This could be used for “spoofing”, new systems integration, or sharing data between 2 buses with differing baud rates.
Step #1: Build and test CANFDuino
Before we get started, lets make sure everything works. Follow our building and testing your first sketch tutorial here.
Step #2: Wire up the two CAN ports
In this example, We will be intercepting the CAN lines from one “black box” to another with the CANFDuino int the middle acting as a “modifier-repeater”. We are receiving a message on CAN ID 0x64 on CAN 0 modifying it’s contents and re-transmitting it on CAN 1, and doing the same for message 0x200 on CAN 1 re-transmitting on CAN 0. We will also “pass-thru” all other messages bidirectionally between CAN 0 and CAN 1 as “untouched”. The CAN bus should be physically broken (not spliced) with the upstream device wired to CAN H and CAN L signals on the CANFDuino shield port 0, and the downstream devices wired to CAN H and CAN L on CAN 1.
Step #3: Program it
Open the IDE and go to File->Examples->CANFduino and select “CANFDuino_PassThruGateway.ino”. Make sure you have selected the proper board and port selected from Tools->Board->CANFDuino and Port->COMxx. Now click upload button, it will verify and upload the code to the CANFDuino. The board should be communicating as a gateway at this point. You could add “print” statements as you like for debug messages to the serial terminal. If you happen to be the proud owner of another CANFDuino unit you can flash the CANTerm sniffing program to monitor your gateway code in action as shown below.
Step #4: Modify it
See the example code below (and on github here) to modify for your message types, baud rates etc. Thank you to all of our backers, we wish you success!
void loop()
{
//note this code is just a polling example, not optimized for interrupt driven performance
//poll for messages on ports
CanPort0.RxMsgs();
CanPort1.RxMsgs();
//retransmit port 0 rx Messages on Port 1
for (i=0;i<CanPort0.numRxMsgs;i++)
{
//intercept message 0x64 and modify byte 0 if it equals 55 before re-transmitting on port 1
if(CanPort0.rxMsgs[i].rxMsgInfo.id == 0x64)
{
if(CanPort0.rxMsgs[i].rxMsgInfo.data[0] == 0x55)
{
CanPort0.rxMsgs[i].rxMsgInfo.data[0] = 0x88;
}
}
//send all messages RX on CAN 0, and including moodified message
CanPort1.TxMsg(&CanPort0.rxMsgs[i]);
}
//retransmit port 1 rx Messages on Port 0
for (i=0;i<CanPort1.numRxMsgs;i++)
{
//intercept message 0x200 and modify byte 0 if it equals 55 before re-transmitting on port 1
if(CanPort1.rxMsgs[i].rxMsgInfo.id == 0x200)
{
CanPort1.rxMsgs[i].rxMsgInfo.data[0] = 0xFF;
}
//send all messages RX on CAN 1, and including moodified message
CanPort0.TxMsg(&CanPort1.rxMsgs[i]);
}
}