Skip to content

Instantly share code, notes, and snippets.

@mwrouse
Last active July 23, 2021 15:39
Show Gist options
  • Save mwrouse/7fad4bd487c619e11bdd8907686cd847 to your computer and use it in GitHub Desktop.
Save mwrouse/7fad4bd487c619e11bdd8907686cd847 to your computer and use it in GitHub Desktop.
Arduino CAN Serial Relay
/**
* This project is an Arduino that serves as a CAN relay to a Raspberry Pi.
* It was created because of this issue https://github.com/linux-can/can-utils/issues/133
* The Arduino is responsible for sending/receiving CAN messages and passes it along over Serial.
*
* We used a custom library for this, that is where the CAN class comes from, but you can replace it with whatever CAN library
* you want to use.
*/
#include "config.h"
#include "pins.h"
CAN can(10);
can_message rx;
can_message tx;
uint8_t buffer[13];
int checksum;
int i;
void transmitOverSerial(can_message msg);
void setup()
{
pinMode(CAN_LED, OUTPUT);
digitalWrite(CAN_LED, LOW);
Serial.begin(115200);
can.setup();
}
void loop()
{
// Receive actual CAN Messages
if (can.receive(&rx)) {
transmitOverSerial(rx);
digitalWrite(CAN_LED, !digitalRead(CAN_LED));
}
// Read serial data to tx CAN Messages
while (Serial.available() >= 13) {
Serial.readBytes(buffer, 13);
if (buffer[0] != START_OF_TRANSMISSION || buffer[12] != END_OF_TRANSMISSION) {
Serial.readStringUntil(END_OF_TRANSMISSION);
Serial.flush();
continue;
}
checksum = 0;
for (i = 1; i < 11; i++)
checksum = checksum ^ buffer[i];
if (checksum != buffer[11]) {
//Serial.println("Invalid checksum");
continue;
}
// Form the ID
tx.id = (buffer[1] << 4) | (buffer[2]);
// Form the data
for (i = 3; i < 11; i++)
tx.data.u8[i-3] = buffer[i];
can.transmit(&tx);
}
}
void transmitOverSerial(can_message msg)
{
#ifndef DEBUG
buffer[0] = START_OF_TRANSMISSION;
buffer[12] = END_OF_TRANSMISSION;
// Put the ID into the buffer
buffer[1] = msg.id >> 4; // Only the upper most byte
buffer[2] = msg.id & 0x00F; // Lower most nibbles
// Put data into the buffer
for (i = 0; i < 8; i++)
buffer[i+3] = msg.data.u8[i];
checksum = 0;
for (i = 1; i < 11; i++)
checksum = checksum ^ buffer[i];
buffer[11] = checksum;
Serial.write(buffer, sizeof(buffer));
#endif
}
#ifndef _CAN_RELAY_CONFIG_H_
#define _CAN_RELAY_CONFIG_H_
#define START_OF_TRANSMISSION '\t'
#define END_OF_TRANSMISSION '\n'
#endif
#ifndef _CAN_RELAY_PINS_H_
#define _CAN_RELAY_PINS_H_
#define CAN_LED 3
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment