pythontkinterpymodbus

Live Tkinter Labels


I have a question regarding tkinter labels and pymodbus. The scenario is, I'm attempting to build a GUI whereby the program connects to a "serial client" or "slave" device and essentially polls the serial clients registers. I am attempting to read these registers and display them on a tkinter label which I have been able to do! However, I would like to take the concept further and have the labels update every second. The registers in question are sensors so I'd like to capture them as they vary, and display them on the GUI. So far this is a simplified version of what's been completed so far.

from tkinter import *
from tkinter import ttk
from tkinter import messagebox
from pymodbus.client.sync import ModbusSerialClient

client = ModbusSerialClient(
    port="COM14",
    startbit=1,
    databits=8,
    parity="N",
    stopbits=2,
    errorcheck="crc",
    baudrate=38400,
    method="RTU",
    timeout=3)

root = Tk()
root.geometry("500x350")

res = client.read_holding_registers(address=50, count=1, unit=1)

value_1 = DoubleVar()
value_1.set(res.registers)

value_label = ttk.Label(root, textvariable = value_1, font = ("Arial", 25, "bold"))
value_label.place(x = 50, y = 50)

root.mainloop()

At the moment, the program connects to the sensor in question and takes the value from the register when program is loaded, is there a way where it polls for the value every second, and updates?

Thanks in advance.


Solution

  • You can use .after() to execute a function to poll the register every second:

    ...
    value_1 = DoubleVar()
    value_label = ttk.Label(root, textvariable=value_1, font=("Arial", 25, "bold"))
    value_label.place(x=50, y=50)
    
    def poll_register():
        res = client.read_holding_registers(address=50, count=1, unit=1)
        value_1.set(res.registers)
        # call poll_register() again one second later
        root.after(1000, poll_register) 
    
    poll_register() # start polling register
    ...