Issues in CAN-BUS communication between Teensy 4.1 and RPi

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:
BUS.jpg

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
I see CAN traffic coming from the Teensy boards, as I expected.
dump.png

However, if I attempt to send traffic on the BUS like so:
Code:
cansend can0 01a#11223344AABBCCDD
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:
buffer.png

Running ifconfig on the RPi yields:
ifconfig.png

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
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!
 
If you can see the CAN frames with candump that means the Rx is working and configured correctly.

If you can't send data that sound like the Tx line is not working correctly.

Check the TxCAN pin on the MCP2515 is connected correctly to the sn65hvd230. Use a scope to check there are data on this line when using cansend.
 
Many thanks skpang for pointing me in the right direction!

I did not have an oscilloscope at hand, however, my USB CAN BUS Analyzer had just arrived. With it, I confirmed that the Teensy boards were correctly sending and receiving data. I then decided to try to use another MCP2515 module, this time modifying it as per this guide. It worked perfectly straight away! So it seems that the SMD desoldering of the TJA1050 transceiver and substituting it with the sn65hvd230 must have done something. Perhaps the sn65hvd230 got damaged in the process, or it is not making proper contact with the Tx line.

Out of curiosity, I used a third MCP2515 module completely unmodified with the TJA1050 transceiver provided. I connected it to the Raspberry Pi and powered it from 3.3v. To my surprise, it worked just as fine! After all, it seems like powering the TJA1050 from the 3.3v line is ok and no modification is actually required?

Many thanks again for pointing me in the right direction!

Update: I did check the TJA1050 datasheet, and it does technically say that the min Vcc is 4.75V. So it is a bit odd that it is working off of the 3.3v from the RPi.
 
Last edited:
If you read the data sheet on the TJA1050 it says the Vcc supply voltage is 4.75 to 5.25v
If you got it to work at 3.3v does not mean it will work in all conditions or at all data rate.
 
That's the conclusion I came to as well. I guess it will do for now until for a prototype but will have to substitute it with a different transceiver with a 3.3v Vcc for stability's sake.

Many thanks for helping me get to the bottom of this!
 
Back
Top