Programmiertechnisch braucht man zu CAN nicht wirklich viel wissen, es funktioniert auf dem Arduino ähnlich wie Serial. Man kann senden und empfangen, allerdings keine einzelnen Bytes, sondern Botschaften.
Die sehen auf dem Teensy z.B. so aus
typedef struct CAN_message_t {
uint32_t id; // can identifier
uint8_t ext; // identifier is extended
uint8_t len; // length of data
uint16_t timeout; // milliseconds, zero will disable waiting
uint8_t buf[8];
} CAN_message_t;
Wichtig sind dabei hauptsächlich die ID und die Daten (in len steht die Anzahl der Bytes und in buf deren Inhalte).
In diesem Beispiel aus der Arduino IDE spricht ein Teensy 3.6 mit sich selbst
// -------------------------------------------------------------
// CANtest for Teensy 3.6 dual CAN bus
// by Collin Kidder, Based on CANTest by Pawelsky (based on CANtest by teachop)
//
// Both buses are left at default 250k speed and the second bus sends frames to the first
// to do this properly you should have the two buses linked together. This sketch
// also assumes that you need to set enable pins active. Comment out if not using
// enable pins or set them to your correct pins.
//
// This sketch tests both buses as well as interrupt driven Rx and Tx. There are only
// two Tx buffers by default so sending 5 at a time forces the interrupt driven system
// to buffer the final three and send them via interrupts. All the while all Rx frames
// are internally saved to a software buffer by the interrupt handler.
//
#include <FlexCAN.h>
#ifndef __MK66FX1M0__
#error "Teensy 3.6 with dual CAN bus is required to run this example"
#endif
static CAN_message_t msg;
static uint8_t hex[17] = "0123456789abcdef";
// -------------------------------------------------------------
static void hexDump(uint8_t dumpLen, uint8_t *bytePtr)
{
uint8_t working;
while( dumpLen-- ) {
working = *bytePtr++;
Serial.write( hex[ working>>4 ] );
Serial.write( hex[ working&15 ] );
}
Serial.write('\r');
Serial.write('\n');
}
// -------------------------------------------------------------
void setup(void)
{
delay(1000);
Serial.println(F("Hello Teensy 3.6 dual CAN Test."));
Can0.begin();
Can1.begin();
//if using enable pins on a transceiver they need to be set on
pinMode(2, OUTPUT);
pinMode(35, OUTPUT);
digitalWrite(2, HIGH);
digitalWrite(35, HIGH);
msg.ext = 0;
msg.id = 0x100;
msg.len = 8;
msg.buf[0] = 10;
msg.buf[1] = 20;
msg.buf[2] = 0;
msg.buf[3] = 100;
msg.buf[4] = 128;
msg.buf[5] = 64;
msg.buf[6] = 32;
msg.buf[7] = 16;
}
// -------------------------------------------------------------
void loop(void)
{
CAN_message_t inMsg;
while (Can0.available())
{
Can0.read(inMsg);
Serial.print("CAN bus 0: "); hexDump(8, inMsg.buf);
}
msg.buf[0]++;
Can1.write(msg);
msg.buf[0]++;
Can1.write(msg);
msg.buf[0]++;
Can1.write(msg);
msg.buf[0]++;
Can1.write(msg);
msg.buf[0]++;
Can1.write(msg);
delay(20);
}
Man kann also auf unterster Ebene mit der Lib Messages senden und empfangen. Das sollte für deine Anwendung eigentlich reichen. Wenn der Windows Code so ähnlich arbeitet, kann man den entsprechend anpassen.
Den Teensy kriegt man in die Arduino IDE in dem man das hier installiert
https://www.pjrc.com/teensy/td_download.html
Das Installationsprogramm fragt auch, ob allerlei Libraries mit installiert werden sollen. Wenn man da "Alle" wählt, hat man die CAN Library für den Teensy mit dabei. Sonst muss man an der Stelle sehen, dass "FlexCAN" mit ausgewählt ist.
Wichtiger Hinweis: Teensy 3.2 und 3.5 sind an vielen Pins 5 V tolerant, d.h. sie gehen nicht kaput, wenn man an einen Eingang ein 5 V Signal anschliesst. Den 3.6 kann man danach wegschmeissen, der ist nur für 3.3 V Anwendungen, also ähnlich wie die IOs beim Raspi.