常开MODBUS串行端口的上下文管理

问题描述

我正在学习python,以开发用于MODBUS串行电机控制器的RaspBerry Pi显示/界面。我已经能够将这个项目分解为可管理的部分,但是为了寻找如何共享串行端口I / O而被困了好几天,更不用说最好的方法了-我需要“体系结构”指导。端口需要保持开放状态24/7,否则速度非常慢。我有两个循环和Tkinter命令,它们需要共享串行端口,而不会被后端数据处理中断。对于开发而言,循环是尾递归,我知道我需要某种类型的无限迭代循环,但是我认为这是一个单独的问题。因此,以下每个循环都是独立工作的;

  1. 快速循环”可快速读取多个寄存器,理想情况下,可以优先使用其他循环未使用的所有带宽,也可以在无限时间间隔内以最高优先级定期调用,并允许短暂的中断循环从队列中运行。

  2. “慢循环”读取很少更改的寄存器,例如传感器故障

  3. 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 (将#修改为@)