Python CAN总线通信异常:消息持续重复发送无法停止
CAN消息持续重复发送问题排查与解决
问题重现
使用python-can库发送单条CAN消息,CSV保存功能正常,但通过示波器观察到消息持续重复发送。代码如下:
#!/usr/bin/env python import time import can import os import csv import pdb os.system('sudo ifconfig can0 down') os.system('sudo ip link set can0 type can bitrate 125000') os.system('sudo ifconfig can0 up') def main(): with can.Bus(interface='socketcan', channel = 'can0',receive_own_messages=True) as bus: # 发送消息并保存到CSV print_listener = can.CSVWriter("in.csv") can.Notifier(bus, [print_listener]) bus.send(can.Message(arbitration_id=0x14,data=[1], is_extended_id=False)) time.sleep(1.0) print_listener.stop() bus.shutdown() if __name__ == "__main__": main() #os.system('sudo ifconfig can0 down')
问题原因
问题出在socketcan接口的自动重传机制:
- CAN物理层要求接收节点返回ACK位确认,当总线上仅存在发送节点(无其他接收设备)时,发送端无法收到ACK。
- python-can的socketcan接口默认开启
auto_retransmit=True,会持续重传消息直到收到ACK。
解决方法
创建can.Bus时显式关闭自动重传,添加auto_retransmit=False参数:
with can.Bus(interface='socketcan', channel='can0', receive_own_messages=True, auto_retransmit=False) as bus:
修改后的完整代码:
#!/usr/bin/env python import time import can import os import csv import pdb os.system('sudo ifconfig can0 down') os.system('sudo ip link set can0 type can bitrate 125000') os.system('sudo ifconfig can0 up') def main(): # 关闭自动重传 with can.Bus(interface='socketcan', channel='can0', receive_own_messages=True, auto_retransmit=False) as bus: # 发送消息并保存到CSV print_listener = can.CSVWriter("in.csv") can.Notifier(bus, [print_listener]) bus.send(can.Message(arbitration_id=0x14,data=[1], is_extended_id=False)) time.sleep(1.0) print_listener.stop() bus.shutdown() if __name__ == "__main__": main() #os.system('sudo ifconfig can0 down')
额外优化建议
可以用python-can内置的配置方法替代os.system命令,避免依赖shell命令:
# 替代原有的os.system配置命令 bus = can.interface.Bus( channel='can0', interface='socketcan', bitrate=125000, receive_own_messages=True, auto_retransmit=False )
内容的提问来源于stack exchange,提问作者Cactus
相关产品推荐
相关产品推荐

