embedded_science
New member
Good morning everyone!
I am trying to interface two Teensy 4.1 boards with a Raspberry Pi CM4 (with 5.15.61 kernel) via CAN-BUS. I want them to be able to send CAN messages to each other, nothing complex. However, I am having issues. The Teensy boards seem to be working fine when wired up to each other, but when wired only with the RPi, they stop working. I have tried to include as much information about my setting, hopefully, you can spot my mistake.
Topology
The Teensy boards will be the extremities of the BUS (aka they will have a 120-ohm termination resistor), and the RPi will sit in the middle of the BUS.
The Teensy boards are using the embedded CAN1 bus + sn65hvd230 transceiver, while the RPi is using an MCP2515 controller + sn65hvd230 transceiver. I followed this guide to substitute the SMD transceiver IC on the MCP2515 board and interface it with Raspberry Pi OS. They all share Ground.
The topology is as depicted here:

The code
The code I have for both Teensy boards is the same. They listen to the BUS (print on serial what they read) and write a message to the BUS every 100 milliseconds. I am using the Arduino framework + FlexCan_T4 library. On the Raspberry Pi side, can-utils is being used to test reception and transmission on the BUS.
Teensy code (one board has an ID of 0x1, the other 0x2):
The issue
Now, the communication between the Teensy boards seems to be working fine. They both start blinking as soon as their CAN BUS lines are connected to each other, which is a sign of CAN messages being exchanged among each other. They are also printing the messages they get from the BUS on the Serial monitor just fine. The Raspberry Pi, however, seems like it is not able to send data. When I run
I see CAN traffic coming from the Teensy boards, as I expected.

However, if I attempt to send traffic on the BUS like so:
Nothing is received on the Teensy side; it doesn't print that packet on the serial. If I keep trying to send the message, eventually after about 5/10 times I received a buffer error:

Running ifconfig on the RPi yields:

Note how it shows 0 packets on the CAN TX, which I believe is confirmation that the RPi is not sending any messages.
I also tried to reconfigure the CAN-BUS topology to see if 1 Teensy and 1 RPi work as correctly. I removed one Teensy board and added the 120ohm termination jumper on the RPi. Running
on the RPi yields nothing at all, it's like the Teensy stops communicating when it is connecting with the RPi, it only communicates when the other Teensy is also on the network.
Given that when the two Teensy are connected to each other work fine, I have a feeling that when the RPi and the Teensy are connected to each other they stop sending ACK messages, resulting in the communication breaking down. I think this is also supported by the fact that I run into that "No buffer space available" error on the RPi when I keep trying to send a message. From my understanding, that means that the Teensy is not sending the ACK signal to the RPi, resulting in the RPi holding messages in the buffer until it eventually runs out.
Does anyone have any pointers on what I am doing wrong or why does the communication work only between the Teensys and not with the RPi?
Many thanks!
I am trying to interface two Teensy 4.1 boards with a Raspberry Pi CM4 (with 5.15.61 kernel) via CAN-BUS. I want them to be able to send CAN messages to each other, nothing complex. However, I am having issues. The Teensy boards seem to be working fine when wired up to each other, but when wired only with the RPi, they stop working. I have tried to include as much information about my setting, hopefully, you can spot my mistake.
Topology
The Teensy boards will be the extremities of the BUS (aka they will have a 120-ohm termination resistor), and the RPi will sit in the middle of the BUS.
The Teensy boards are using the embedded CAN1 bus + sn65hvd230 transceiver, while the RPi is using an MCP2515 controller + sn65hvd230 transceiver. I followed this guide to substitute the SMD transceiver IC on the MCP2515 board and interface it with Raspberry Pi OS. They all share Ground.
The topology is as depicted here:

The code
The code I have for both Teensy boards is the same. They listen to the BUS (print on serial what they read) and write a message to the BUS every 100 milliseconds. I am using the Arduino framework + FlexCan_T4 library. On the Raspberry Pi side, can-utils is being used to test reception and transmission on the BUS.
Teensy code (one board has an ID of 0x1, the other 0x2):
Code:
#include <Arduino.h>
#include <FlexCAN_T4.h>
FlexCAN_T4<CAN1, RX_SIZE_256, TX_SIZE_16> Can;
void led_animate(){
// Animate LED
digitalWrite(CORE_LED0_PIN, HIGH);
delay(25);
digitalWrite(CORE_LED0_PIN, LOW);
delay(25);
}
// Define callback function.
// This function gets called when there is a message on the CAN BUS
void can_callback(const CAN_message_t &msg) {
Serial.print("MB "); Serial.print(msg.mb);
Serial.print(" OVERRUN: "); Serial.print(msg.flags.overrun);
Serial.print(" LEN: "); Serial.print(msg.len);
Serial.print(" EXT: "); Serial.print(msg.flags.extended);
Serial.print(" TS: "); Serial.print(msg.timestamp);
Serial.print(" ID: "); Serial.print(msg.id, HEX);
Serial.print(" Buffer: ");
for ( uint8_t i = 0; i < msg.len; i++ ) {
Serial.print((char)msg.buf[i]); Serial.print(" ");
} Serial.println();
led_animate();
}
void setup(void) {
// Initialize Serial port
Serial.begin(115200); delay(400);
Serial.println("Initializing Can...");
// Setup in-built LED to display CAN network traffic
pinMode(CORE_LED0_PIN, OUTPUT);
// Initialize CAN BUS
Can.begin();
Can.setBaudRate(500000);
Can.setMaxMB(16);
Can.enableFIFO();
Can.enableFIFOInterrupt();
Can.onReceive(can_callback);
//Can.enableLoopBack(true);
}
void loop() {
//Check for incoming messages and ACK any messages received
Can.events();
// Create message structure
CAN_message_t msg;
// Prepare payload string
String payload = "";
// Generate random number
String num_str = String(random(0, 100));
// Assign message ID
msg.id = 0x1;
// Prepare CAN-BUS payload string
payload = "MSG:" + num_str;
// Create message buffer
for (uint8_t i=0; i<payload.length(); i++){
msg.buf[i] = payload[i];
}
// Send message on CAN-BUS
Can.write(msg);
delay(100);
}
}
The issue
Now, the communication between the Teensy boards seems to be working fine. They both start blinking as soon as their CAN BUS lines are connected to each other, which is a sign of CAN messages being exchanged among each other. They are also printing the messages they get from the BUS on the Serial monitor just fine. The Raspberry Pi, however, seems like it is not able to send data. When I run
Code:
candump any

However, if I attempt to send traffic on the BUS like so:
Code:
cansend can0 01a#11223344AABBCCDD

Running ifconfig on the RPi yields:

Note how it shows 0 packets on the CAN TX, which I believe is confirmation that the RPi is not sending any messages.
I also tried to reconfigure the CAN-BUS topology to see if 1 Teensy and 1 RPi work as correctly. I removed one Teensy board and added the 120ohm termination jumper on the RPi. Running
Code:
candump any
Given that when the two Teensy are connected to each other work fine, I have a feeling that when the RPi and the Teensy are connected to each other they stop sending ACK messages, resulting in the communication breaking down. I think this is also supported by the fact that I run into that "No buffer space available" error on the RPi when I keep trying to send a message. From my understanding, that means that the Teensy is not sending the ACK signal to the RPi, resulting in the RPi holding messages in the buffer until it eventually runs out.
Does anyone have any pointers on what I am doing wrong or why does the communication work only between the Teensys and not with the RPi?
Many thanks!