我正在使用
python
和 python-can
发送消息
接收并处理来自我这样创建的 CAN 总线的消息:
from can.interface import Bus
bus = Bus(interface="pcan", channel="EXT_CAN", bitrate=500000, receive_own_messages=True)
总线对象然后被传递到连接到该总线并实现发送/处理的类:
def connect(self, *args, **kwargs):
"""Connects to bus. Expects "bus" as keyword argument."""
self._bus = kwargs.get("bus")
该类还实现了等待特定消息的方法:
def wait_for_message(self, can_id: int, timeout: int):
self.time_start_listen = time.time()
expected_message = None
while time.time() - self.time_start_listen < timeout:
msg = self._bus.recv(timeout=1.0)
if msg.arbitration_id == can_id:
expected_message = msg
break
assert expected_message
在测试此方法时,我注意到有时根本没有收到预期的消息,并且该方法会引发
AsserionError
。
我正在并行使用 PCAN 查看器,我可以在跟踪上看到预期的消息,因此我确信消息确实正在发送。
供参考,这是一条循环消息,循环时间为 1 秒。 总线上还有其他几个循环消息,循环时间为 20ms。
wait_for_message
方法中的超时参数足够大,足以捕获 1s 消息的至少一帧。这还会检查我收到的消息的时间戳。然而,1s 周期时间消息有时会被跳过。
我也尝试更换
while time.time() - self.time_start_listen < timeout:
msg = self._bus.recv(timeout=1.0)
与:
for msg in self._bus:
但是行为是一样的。
有人经历过这种行为吗?可能是什么原因造成的? 任何提示表示赞赏。蒂亚!
可能您有时会检测到它有时不是因为您的收听时间与消息周期时间一样长?你有一个 while 循环,但你的聆听时间仍然交错成多个 1s 聆听时间,这可能就是问题所在......
我敢打赌,如果你将传递给recv的超时时间增加到2秒,你总是会至少检测到一次。但您仍然会错过一些消息,当然,如果您与其他听众共享这辆公共汽车,那么可能不是这样,因为您会占用公共汽车,从而导致其他听众错过消息。
因此您可以尝试的另一件事是创建一个侦听器对象。例如:
import can
listener = can.BufferedReader()
bus = can.Bus(interface="pcan", channel="EXT_CAN", bitrate=500000)
notifier = can.Notifier(bus, [listener])
然后您可以循环浏览缓冲阅读器,直到检测到您的消息:
while time.time() - time_start_listen < timeout:
msg = listener.get_message()
if msg is not None and msg.arbitration_id == can_id:
expected_message = msg
break
使其不交错,不妨碍其他潜在听众。