You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何树莓派4B与执行器的CAN FD连接后通信异常?

树莓派4B+Waveshare CAN HAT的CAN FD通信异常问题

我用Raspberry Pi 4B搭配Waveshare CAN HAT和一台执行器做CAN FD通信。分开测试时,用测试器能读到两台设备发出的正确帧,但把树莓派和执行器连起来后,树莓派收到的帧ID、数据、长度全是异常的。

运行代码

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)

接收的异常帧内容

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

这类帧会不断重复,其中第三个字节持续变化,和测试器显示的正确帧完全不符。

已尝试的操作

  • 调整过比特率(500kbit/s和5000kbit/s),确认当前设置正确
  • 排除硬件问题,分开测试两台设备都能发送正常帧
  • 把ignore_rx_error_frames设为False会让消息消失,但这不是根本解决办法
  • 修改local_loopback参数没有明显效果
  • 查到类似问题可能和ACK位有关,但不知道怎么操作,而且总线上第一帧就不符合预期

排查方向与解决建议

  1. 检查CAN总线终端电阻
    CAN总线两端必须接120Ω终端电阻,否则会出现信号反射导致帧异常。确认树莓派的CAN HAT和执行器是否都接了终端电阻,或者总线上是否有多余的终端电阻(总线上只能保留两个)。

  2. 修正代码参数错误
    你的startBus函数中,创建can.interface.Bus时dbitrate=5000000后面少了逗号,导致参数传递混乱,同时local_loopback建议关闭:

    can0 = can.interface.Bus(bustype='socketcan', channel='can0', bitrate=500000, dbitrate=5000000, receive_own_messages=False, local_loopback=False,
                             fd=True, can_filters=None, ignore_rx_error_frames=False)
    
  3. 验证CAN FD配置一致性
    确认执行器的CAN FD配置和树莓派完全匹配:包括仲裁比特率、数据比特率、FD模式开关,以及帧格式(标准/扩展ID)。你发送的帧用了is_extended_id=False,如果执行器用的是扩展ID,会直接导致解析异常。

  4. 用系统命令抓包排查
    用candump直接抓取总线数据,排除Python库的问题:

    candump can0,0:0,#FFFFFFFF
    

    如果candump抓到的也是异常帧,问题出在总线配置或硬件连接;如果candump能抓到正确帧,那就是Python代码或python-can库的配置问题。

  5. 降低总线负载测试
    你当前以100Hz发送两个帧,总线负载可能过高。先暂停发送逻辑,只监听执行器的帧,看是否能正常接收,排除发送导致的总线冲突。

内容的提问来源于stack exchange,提问作者Tawhiri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 00:50:28