【发布时间】:2016-05-07 16:02:40
【问题描述】:
我正在使用 python (Pcan basic api) 中的 canbus,并希望使其更易于使用。
通过总线连接了许多设备/模块。他们都被允许发送数据,如果发生冲突,最低 ID 将获胜。
数据被组织在具有 ID、SubID、十六进制值的框架中
为了说明我试图解决的问题,想象一下信号的幅度。
读取帧发送到的值
- QuestionID QuestionSUBID QuestionData
如果没有更高优先级(=lowerID)的消息,则将答案写入总线:
- AnswerID AnswerSubID AnswerData
由于允许任何模块/设备写入总线,因此您事先不知道接下来会得到哪个答案。设置值的方式相同,只是使用不同的 ID。所以对于上面的例子,幅度将是:
- 4 个 ID 和 SubId 与读/写问题/答案关联
- 此外,必须指定 /stored 的数据长度 (0-8)。
- 由于数据都是十六进制值,因此必须指定解析器才能获得人类可读的值(例如十进制表示的电压)
为了存储这些信息,我使用嵌套字典:
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': ... }}
有很多工具可以显示何时设置了哪个值,但对于硬件控制,只要参数是最新的,读取参数的顺序就无关紧要。因此,一种可能的解决方案的一部分是将整个流量存储在一个字典中:
busdata = {'firstID' : {'first_subID': {'data': data,
'timestamp': timestamp},
'second_subID': {'data': data,
'timestamp': timestamp},
},
secondID': ...}
由于总线的性质,我得到了很多其他设备询问的答案 - 总线已满 - 这些不应该被忽略,因为它们可能是我接下来需要的值,并且不需要创建额外的流量- 我可能会使用带有到期日期的时间戳,但到目前为止我并没有考虑太多。
这可行,但使用起来很糟糕。一般来说,我想我将有大约 300 个参数。最终目标是通过 (pyqt) Gui 控制设备,读取序列号等一些值,同时运行测量任务。
所以最大的问题是如何定义更好的易于访问和理解的数据结构?我期待任何关于简洁设计的建议。
主要目标是摆脱基于整个消息的方法。
编辑:我的目标是摆脱整个基于 CAN 特定消息的方法:
我假设我需要一个线程进行通信,它应该:
- 读取缓冲区并更新我的变量
- 发送请求(消息)以获取其他值/变量
- 定期发送一些值
所以从 gui 我希望能够:
- 按名称获取参数 --> 发送带有参数名称的字符串
- 设置参数信号 --> str(name), value(在 gui 中显示)
- 定期获取值 --> 名称、间隔、持续时间(10 秒或无限)
线程必须:
- 记录总线上的所有数据以供内部存储
- 通过从名称、值和读取中生成消息来处理请求,直到获得结果
- 发送周期性信号
我希望这个设计独立于实际硬件:
- 我想到的解决办法,就是上面的parameters_dict
对于内部存储,我考虑了 bus_data_dict
我还是不知道该怎么做:
- 将数据从总线线程传递到 gui(所有值与新值/请求值)
- 如何在pyqt中用信号和槽来实现
- 在内部存储数据(dict 的dict 或一些新的更好的想法)
- 如果这个设计是一个不错的选择
【问题讨论】:
-
创建一个抽象出来的类...canbus完全基于消息包所以我不认为你可以消除它......但你当然可以抽象它......
-
是的,当然。也许我确实已经足够清楚地说明了这一点。问题是如何实现这一点。我考虑了具有适当 getter 和 setter 的属性 - 我仍然需要数据的内部表示。
标签: python python-3.x hardware can-bus