问题描述
我正在学习python,以开发用于MODBUS串行电机控制器的RaspBerry Pi显示/界面。我已经能够将这个项目分解为可管理的部分,但是为了寻找如何共享串行端口I / O而被困了好几天,更不用说最好的方法了-我需要“体系结构”指导。端口需要保持开放状态24/7,否则速度非常慢。我有两个循环和Tkinter命令,它们需要共享串行端口,而不会被后端数据处理中断。对于开发而言,循环是尾递归,我知道我需要某种类型的无限迭代循环,但是我认为这是一个单独的问题。因此,以下每个循环都是独立工作的;
-
“快速循环”可快速读取多个寄存器,理想情况下,可以优先使用其他循环未使用的所有带宽,也可以在无限时间间隔内以最高优先级定期调用,并允许短暂的中断循环从队列中运行。
-
“慢循环”读取很少更改的寄存器,例如传感器故障
-
Tkinter功能命令,可能需要大量的寄存器写操作,而这些操作不需要及时
如果在快速循环在单独的线程中运行时调用写函数,则会收到“ minimalmodbus.InvalidResponseError:rtu模式下的校验和错误:”,然后是每个串行数据包的十六进制位对,因为正在尝试多个功能同时读取或写入串行数据。我什至不能肯定我需要使用线程,但是我想在后端运行计算然后更新显示时不间断地运行串行I / O命令。因此,我尝试使用threading.Lock进行上下文管理,以简化的以下结构将函数放入类中。实际上,有多种读/写方法。
instr = minimalmodbus.Instrument(port,slave_ID) # Opens the port
instr.(modbus configs)
class modbus:
def __init__(self):
self.lock = threading.Lock()
def __enter__(self):
self.lock.acquire()
def __exit__(self):
self.lock.release()
def read(self,address):
value = instr.read_registers(address)
return value
def write(self,address,value):
instr.write_register(address,value)
controller = modbus()
def fastloop()
Tk.Intvar.set(controller.read(address1))
Tk.Intvar.set(controller.read(address2))
...
root.update() #
time.sleep(0.005)
fastloop()
这似乎并没有满足我的要求-而不是写函数仅偶尔与快速循环发生冲突,它们根本无法与端口进行交互,而我得到的是'minimalmodbus.noresponseError:与在fastloop运行时,只要我尝试写入一个地址,仪器就可以使用。
因此,我根据一个类中上下文管理的其他示例尝试了此操作:
class modbus:
def __init__(self):
self.open = False
def __enter__(self):
self.open = True
def __exit__(self):
self.open = False
def read(self,address):
return value
def write(self,value):
(serial commands)
while controller.open == False:
fastloop() # as defined above.
除了它的行为与我的未分类代码完全一样-有时我可以在快速循环运行时编写代码,有时会得到无用的串行数据。无论我在哪里打印(controller.open)-在 enter 的末尾,即读/写方法的开始或结束,它始终是错误的。
我发疯了,因为我知道这不是一个独特的问题,但是我找不到一个可以工作的示例-除这些方法外,我还尝试了其他六种方法以上。万一需要,这里是我的完整代码:https://pastebin.com/M2SncdyC
预先感谢您的任何建议。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)