用Python GUI面板读取MODBUSTCP Server
意图
无线网为家里的无线网,DHCP使能。一个ESP32连接到比如:SSID=“B59B74”。个人计算机编辑GUI界面,读取ESP32中的保持寄存器40001~40010的内容。为实验目的,不断更新4000x中的内容。用GUI连接服务器,当连接了服务器,发送读取40001 ~ 40010,读取并显示。
Python GUI代码
其实Python代码比较简单,但几个需要注意的地方在这里说一下:
Canvas动态变化颜色
Canvas在tkinter中是画布,有许多特性,但在网上很难找到如何让Canvas改变背景颜色。设置一个背景颜色简单,但希望在运行过程中改变背景颜色需要怎末办哪?代码:
c2 = Canvas(width=80, height=30, bg='red')
c2.grid(row=1, column=1)
有这段代码,在画面上就可以显示一个颜色方框。如果想改变这个Canvas的颜色,需要:
if bConnect:
tcp_client.connect(dest_addr)
tcp_client.setblocking(False)
bConnect = True
c2.config(background='green')
th.setDaemon(True) # 守护线程
th.start()
else:
tcp_client.close()
c2.config(background='red')
有这一段代码就可以改变Canvas的颜色了,我用这个颜色来表示是不是连接了ModbusTCP的服务器。
2字节整数
ModbusTCP读取的是2个字节的整数,但Python的整数,int是4个字节。当我要读比如-30000时,在GUI中会显示60000,为了正确显示,需要GUI在程序中进行转换。最好的办法是用Python中的ctypes库。代码:
from ctypes import *
g_num0 = c_short()
g_str0.set(g_num0.value)
lStr0 = Entry(root, textvariable=g_str0, font=('Arial 12 bold'),justify=CENTER)
在动态程序中只要更改g_str0的内容就可以了。mainloop()会自动更新这些内容。
无阻塞读取TCP
在编写GUI的过程中发现自己编写的应用可以发送读取ModbusTCP的命令,但在读取发送回来的命令时一定会碰到读取失败并停止在读取的命令中,看到无阻塞的代码实现:
def count(para='hi', sleep=0.5):
while True:
g_lTime.set(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()))
if bConnect:
send_byte()
time.sleep(0.5)
read_byte()
time.sleep(sleep)
这样在发送了读取的命令后当经过0.5s读取。这里需要在设置连接时将连接设置成非阻塞的形式。读取的代码:
def read_byte():
b = bytes()
try:
b = tcp_client.recv(1024)
g_num0.value = (b[9] << 8) + b[10]
except BlockingIOError as e:
print('The data not received')
b = None
总结
还在学习使用Python,在这里总结一下碰到的问题。结果如图: