Tawhiri
Tawhiri

Reputation: 11

Why CAN FD communication not working with two nodes

I'm trying to communicate with an actuator device via CAN FD connection, with the help of a Raspberry 4b and a Waveshare CAN hat.

While they are separated, using a tester I read the correct frames on both devices. But when the Raspberry and the actuator are connected, I receive frames with unexpected ID, data and size on the Raspberry.

The code:

import time
import os
import can
import cantools

def startBus():
    os.system('sudo ip link set can0 up type can bitrate 500000   dbitrate 5000000 restart-ms 1000 berr-reporting on fd on')
    time.sleep(0.1)
    global can0
    can0 = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000, dbitrate=5000000 receive_own_messages=False, local_loopback=True,
                                    fd=True, can_filters=None, ignore_rx_error_frames=False)

def shutDownBus():
    os.system('sudo ifconfig can0 down')
    print('shut down')

def periodicSend():
    print('sendPeriodic')
    messageID1 = 0xC0FFEE 
    data1 = [0, 1, 2, 3, 4, 5, 6, 7]
    msg1 = can.Message(arbitration_id=messageID1,
                            is_fd=True,
                            data=data1,
                            is_extended_id=False)

    messageID2 = 0xC0FFFF  
    data2 = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    msg2 = can.Message(arbitration_id=messageID2,
                            is_fd=True,
                            data=data2,
                            is_extended_id=False)

    task1 = can0.send_periodic(msg1, 0.01)

    if not isinstance(task1, can.ModifiableCyclicTaskABC):
        task1.stop()
        return

    task2 = can0.send_periodic(msg2, 0.01)

    if not isinstance(task2, can.ModifiableCyclicTaskABC):
        task2.stop()
        return

def listen():
    print("listening")
    for message in can0:
        print(message)

# Calling the functions: 
shutDownBus()
time.sleep(1)
startBus()
periodicSend()
listen()

x = False
while not x: time.sleep(0.1)

The contents of the received frames:

Timestamp: 1667826218.955793 ID: 0088 S Rx E DL: 8 00 00 94 00 00 00 00 00 Channel: can0
Timestamp: 1667826218.955... ID: 0088 S Rx E DL: 8 00 00 90 00 00 00 00 00 Channel: can0
Timestamp: 1667826218.955... ID: 0088 S Rx E DL: 8 00 00 04 00 00 00 00 00 Channel: can0
Timestamp: 1667826218.955... ID: 0088 S Rx E DL: 8 00 00 02 00 00 00 00 00 Channel: can0

And so on, the third byte keeps changing. These are different from what I am expecting and what I am seeing on the tester (the tester shows the correct frames).

I tried to change the bitrates (500k and 5000k), though I'm rather sure these are correct.

It does not look like a hardware issue, as when separated, both are sending the expected frames.

Setting the ignore_rx_error_frames to False makes the messages disappear, but obviously it is not the solution.

Changing the local_loopback has no visible effect.

Some seemingly similar issues were related to the ACK bit (Sending messages with different ID on a pcan can bus, using python can), but 1) I don't see where and how I could manipulate this and 2) already the very first frame on the bus is not what I am expecting.

Any ideas would be greatly appreciated.

Upvotes: 0

Views: 911

Answers (1)

Tawhiri
Tawhiri

Reputation: 11

The solution was to adjust the sample-point and the dsample-point parameters when setting up the CAN interface:

sudo ip link set can1 up type can bitrate 500000 dbitrate 5000000 restart-ms 1000 berr-reporting on fd on sample-point .8 dsample-point .8

Apparently CAN FD is more sensitive to these parameters.

Upvotes: 1

Related Questions