Python中的高级/抽象CAN总线接口
我正在使用python中的canbus(Pcan基本api),并希望使其更易于使用 许多设备/模块通过总线连接。他们都被允许发送数据,如果发生碰撞,最低ID将获胜 数据以具有ID、SubID和hexvalues的帧组织 为了说明我试图解决的问题,想象一个信号的振幅 读取帧发送到的值的步骤Python中的高级/抽象CAN总线接口,python,python-3.x,hardware,can-bus,Python,Python 3.x,Hardware,Can Bus,我正在使用python中的canbus(Pcan基本api),并希望使其更易于使用 许多设备/模块通过总线连接。他们都被允许发送数据,如果发生碰撞,最低ID将获胜 数据以具有ID、SubID和hexvalues的帧组织 为了说明我试图解决的问题,想象一个信号的振幅 读取帧发送到的值的步骤 QuestionID QuestionSUBID QuestionData 如果没有具有更高优先级(=lowerID)的消息,则答案将写入总线: AnswerID AnswerSubID AnswerDa
- QuestionID QuestionSUBID QuestionData
- AnswerID AnswerSubID AnswerData
parameters = {'Parameter_1': {'Read': {'question_ID': ID,
'question_SUBID': SubID,
'question_Data': hex_value_list,
'answer_ID': ...,
'answer_subID': ...,
'answer_parser': function},
'Write': {'ID': ...,
'SubID': ...,
'parser' ...,
'answer_ID': ...,
'answer_subID': ...}},
'Parameter_2': ... }}
有很多工具可以显示何时设置了哪个值,但对于硬件控制,参数的读取顺序并不相关,只要它们是最新的。因此,可能的解决方案的一部分是将整个流量存储在一个dict of dict中:
busdata = {'firstID' : {'first_subID': {'data': data,
'timestamp': timestamp},
'second_subID': {'data': data,
'timestamp': timestamp},
},
secondID': ...}
由于总线的性质,我得到了很多其他设备询问的答案-总线已经满了-这些不应该被忽略,因为它们可能是我接下来需要的值,并且没有必要创建额外的流量-我可能会使用带有到期日期的时间戳,但到目前为止我没有考虑太多
这是可行的,但使用起来很糟糕。一般来说,我想我会有大约300个参数。最终的目标是通过(pyqt)Gui控制设备,读取一些值,如序列号,同时运行测量任务
因此,最大的问题是如何定义一个更易于访问和理解的数据结构?我期待着任何关于清洁设计的建议
主要目标是摆脱整个基于消息的aproach
编辑:我的目标是摆脱整个基于CAN特定消息的方法:
我假设我需要一个线程进行通信,它应该:
- 我想到的解决方案是上述参数
can.Message
类型转换并路由为pyqt信号。将其视为事件/信号的一对多来源
我会使用另一个控制器来负责向总线发送消息。它可以执行诸如从总线请求定期测量以及由gui驱动的按需请求等任务
关于在内部存储数据,这实际上取决于您的编程风格和复杂性。我见过这样的项目,每个CAN消息都有自己的类
最后,排队是你的朋友 同意@Hardbyte的使用。太棒了 至于应用层之间的消息传递,我很幸运——您可以将模块设置为基于事件的,从canbus消息事件一直到更新UI或其他任何内容
对于数据存储/持久化,我将消息放入SQLite,并并行(使用模式)将数据传递到IoT中心(via)。创建一个类,将其抽象出来。。。canbus完全基于消息包,所以我认为您无法消除它。。。但你当然可以把它抽象出来……是的,当然。也许我说得够清楚了。问题是如何实现这一点。我考虑了使用适当的getter和setter的属性,但我仍然需要数据的内部表示。谢谢。我采取了一种非常类似的方法,仍然试图将其抽象为mvc模式。Python只能使用,与peak systems示例相同。我通过将Unicode转换成字节字符串修复了他们的代码。你说的“Python只能与之一起工作”是什么意思?在任何系统中,都必须确保向总线发送字节。
class MySimpleCanBus:
def parse_message(self,raw_message):
return MyMessageClass._create(*struct.unpack(FRAME_FORMAT,msg))
def recieve_message(self,filter_data):
#code to recieve and parse a message(filtered by id)
raw = canbus.recv(FRAME_SIZE)
return self.parse_message(raw)
def send_message(msg_data):
# code to make sure the message can be sent and send the message
return self.recieve_message()
class MySpecificCanBus(MySimpleCanBus):
def get_measurement_reading():
msg_data = {} #code to request a measurement
return self.send_message(msg_data)
def get_device_id():
msg_data = {} # code to get device_id
return self.send_message(msg_data)