我正在做项目。这个想法是读取 CAN 总线车辆数据并将其在屏幕上可视化。 选择 Rasperry Pi 4 作为平台、Python 及其 GUI Kivy、Python Can 库。 can 读卡器是 Pcan Canable 适配器。
在装有 Windows 的 PC 上一切正常,但切换到 RPI4 时我遇到了困难。 应用程序运行了一段时间,按预期描述数据,但在出现错误后不久:
文件“/home/admin/.local/lib/python3.11/site-packages/can/notifier.py”,第 124 行,在 _rx_thread 中 if msg := bus.recv(self.timeout): ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 文件“/home/admin/.local/lib/python3.11/site-packages/can/bus.py”,第 126 行,recv 中 消息,已经过滤= self._recv_internal(超时= time_left) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ 文件“/home/admin/.local/lib/python3.11/site-packages/can/interfaces/pcan/pcan.py”,第 558 行,位于 _recv_internal 引发 PcanCanOperationError(self._get_formatted_error(结果)) can.interfaces.pcan.pcan.PcanCanOperationError:CAN 控制器读取得太晚
我的代码的部分在这里:
import can
** and so on **
''' other classes over here '''
class Can_data(can.Listener):
print("reading can messages")
def on_message_received(self, msg):
# print(f"data: {msg}")
if msg.arbitration_id == 0x316 and msg is not None:
Dash_Board.rpm = msg.data[3] * 7000 / 110
Dash_Board.arrow_rpm = Dash_Board.rpm
print("rpm: ", Dash_Board.rpm)
Dash_Board.rpm = round(Dash_Board.rpm / 50) * 50
elif msg.arbitration_id == 0x1F1 and msg is not None:
Dash_Board.speed = int(msg.data[4] * 220 / 110)
Dash_Board.arrow_speed = Dash_Board.speed * 260 / 220
print("t: ", Dash_Board.speed)
# uncoment to filter data
elif msg.arbitration_id == 0x0A0 and msg is not None:
Dash_Board.t = msg.data[1] - 40
print("t: ", Dash_Board.t)
elif msg.arbitration_id == 0x0A1 and msg is not None:
Dash_Board.boost = msg.data[4]
print("boost: ", Dash_Board.boost)
elif msg.arbitration_id == 0x0350 and msg is not None:
Dash_Board.fuel = msg.data[3] * 0.75
print("tank: ", Dash_Board.fuel)
else:
print("no message recieved")
def stop(self):
print("stoped")
class Read_bus_data():
def __init__(self, **kwargs):
super().__init__(**kwargs)
print("reading bus data")
self.filter = [
{"can_id": 0x316, "can_mask": 0x7FF, "extended": False},
{"can_id": 0x1F1, "can_mask": 0x7FF, "extended": False},
{"can_id": 0x0A0, "can_mask": 0x7FF, "extended": False},
{"can_id": 0x0A1, "can_mask": 0x7FF, "extended": False},
{"can_id": 0x350, "can_mask": 0x7FF, "extended": False}
]
self.bus = None
self.notifier = None
self.start_bus()
def start_bus(self):
try:
self.bus = can.Bus(interface='pcan', channel='PCAN_USBBUS1', can_filters=self.filter, timeout=2)
listen = Can_data()
self.notifier = can.Notifier(self.bus, [listen], timeout=2)
# with self.bus as bus:
# msg = self.bus.recv(0.1)
# for msg in bus:
# if msg.arbitration_id == 0x316 and msg is not None:
# Dash_Board.rpm = msg.data[3]*7000/110
# Dash_Board.arrow_rpm = Dash_Board.rpm
# print("rpm: ", Dash_Board.rpm)
# Dash_Board.rpm = round(Dash_Board.rpm/50)*50
# elif msg.arbitration_id == 0x1F1 and msg is not None:
# Dash_Board.speed = int(msg.data[4]*220/110)
# Dash_Board.arrow_speed = Dash_Board.speed*260/220
# print("t: ", Dash_Board.speed)
# # #uncoment to filter data
# if msg.arbitration_id == 0x0A0 and msg is not None:
# Dash_Board.t = msg.data[1] - 40
# print("t: ", Dash_Board.t)
# elif msg.arbitration_id == 0x0A1 and msg is not None:
# Dash_Board.boost = msg.data[4]
# print("boost: ", Dash_Board.boost)
# elif msg.arbitration_id == 0x0350 and msg is not None:
# Dash_Board.fuel = msg.data[3]*0.75
# print("tank: ", Dash_Board.fuel)
# else:
# print("no message recieved")
except Exception as e:
print("error", e)
# self.cleanup()
class Dashboard_project(MDApp):
def build(self):
sm = MDScreenManager()
sm.add_widget(Classic_style_dash_board())
sm.add_widget(Sport_style_dash_board())
sm.add_widget(Engine())
Read_bus_data()
return sm
if __name__ == '__main__':
Dashboard_project().run()
我的应用程序运行了一段时间,在注意消息的痕迹后,可以看到它有一些延迟,并且在 CAN Bus 收到上面的错误后
我尝试了很多事情。
我有一个可用的 USB V2.0 nano。它通过 can0 接口看到 CAN 消息,但不是全部。在扩展标识符中设置高位的消息似乎被忽略或过滤掉。我的CANFD模块使用STM32G431和Microchip MCP2515和PIC18可以 所有人都能看到这些消息,但 CANABLE USB 记忆棒看不到!
来自 linux MCP2515 rpi buildroot linux:
# ./can_rx | egrep "F1DF"
10:27:08.995 8F1DF000 7 bytes : 00 0d 63 2d 2a 00 34 U2U class=0(READ), UNKNOWN13 = 0.000000
10:27:09.249 8F1DF001 7 bytes : 00 11 9b 2d 2a 00 34 UNKNOWN
10:27:09.489 8F1DF000 7 bytes : 00 0d 63 2d 2a 00 34 U2U class=0(READ), UNKNOWN13 = 0.000000
10:27:09.744 8F1DF001 7 bytes : 00 11 86 2d 2a 00 34 UNKNOWN
10:27:09.983 8F1DF000 7 bytes : 00 0d 63 2d 2a 00 34 U2U class=0(READ), UNKNOWN13 = 0.000000
10:27:10.237 8F1DF001 7 bytes : 00 11 6e 2d 2a 00 34 UNKNOWN
但是同一个can总线上的CANABLE看不到这些 0x0F1DF000 消息。
$ candump can0 | more
can0 00001038 [8] 30 1E 00 5C 00 0A 04 04
can0 000AA010 [8] 0D 86 00 00 00 00 00 00
can0 00011010 [8] 04 25 00 00 00 00 C0 7F
can0 00001000 [8] 84 25 00 00 20 00 00 00
can0 00011010 [8] 04 26 00 00 00 00 C0 7F
can0 00011010 [8] 04 23 00 00 00 00 C0 7F
can0 00001000 [8] 84 26 00 00 20 00 00 00
can0 00011010 [8] 04 27 00 00 00 00 C0 7F
can0 00011010 [8] 04 0C 00 00 00 00 C0 7F
can0 00001000 [8] 84 27 00 00 11 00 80 3F
can0 00001000 [8] 84 0C 00 00 08 44 1C 46
can0 0000000E [5] FF 02 41 1C 00
can0 0000A7E5 [8] EF 01 13 24 54 00 20 01
can0 00011010 [8] 04 07 00 00 00 00 C0 7F
can0 00011010 [8] 04 08 00 00 00 00 C0 7F
can0 00011010 [8] 04 0F 00 00 00 00 C0 7F
can0 00011010 [8] 04 0D 00 00 00 00 C0 7F
can0 00001000 [8] 84 0D 00 00 00 00 00 00
can0 00011010 [8] 04 16 00 00 00 00 C0 7F
can0 00011010 [8] 04 0E 00 00 00 00 C0 7F
can0 0000100E [5] FF 02 0B 1C 00
can0 000AA010 [8] 0D 87 00 00 00 00 00 00
can0 00011010 [8] 04 10 00 00 00 00 C0 7F
can0 000017E4 [8] 00 29 00 00 00 00 20 30
can0 0000103A [7] 31 FF F5 FF E6 53 B2
can0 00001038 [8] 31 1E 00 5C 00 0B 04 04
can0 00011010 [8] 04 14 00 00 00 00 C0 7F