以下为源码,有问题请留言:
#coding=utf-8
from tkinter import *
import serial
import serial.tools.list_ports
from tkinter import messagebox
import threading
from decimal import *
import struct
from pynput.keyboard import Controller,Key,Listener
order={
'sendData': 0x01,
'requestData': 0x02,
'dataOk': 0x03,
'dataFailed': 0x04,
'controlData': 0x05,
}
class Application(Frame):
serialReadBuf = [] #串口读取数据
serialReadCnt=0
serialPort=None #串口号
keyDowmFlag=0
def __init__(self,master):
super().__init__(master)
self._serial=None
self.comIsCon=False
self.create_widget()
self.pack()
def create_widget(self):
#加载主画布
self.canvas = Canvas(width=1200,height=800,)
self.canvas.place(x=0,y=0)
global mainImage
mainImage = PhotoImage(file="../Image/界面.png")
self.canvas.create_image(465, 0, anchor='n', image=mainImage)
#加载输入框
global addImageButton
global minusImageButton
addImageButton = PhotoImage(file="../Image/加.png") #85x30
minusImageButton = PhotoImage(file="../Image/减.png") #85x30
#角度P输入加载
self.angleP = StringVar()
self.angleP.set("0.00")
self.anglePEntry = Entry(textvariable=self.angleP, font=('Asial', 25), highlightcolor='green', highlightthickness=2,
insertbackground='black',bg='white',width=9)
self.anglePEntry.place(x=160, y=130)
Button(image=minusImageButton, command=self.angle_p_minus_click).place(x=330, y=128)
Button(image=addImageButton, command=self.angle_p_add_click).place(x=390, y=128)
#角度I输入加载
self.angleI = StringVar()
self.angleI.set("0.00")
self.angleIEntry = Entry(textvariable=self.angleI, font=('Asial', 25), highlightcolor='green', highlightthickness=2,
insertbackground='black',bg='white',width=9)
self.angleIEntry.place(x=160, y=256)
Button(image=minusImageButton, command=self.angle_I_minus_click).place(x=330, y=256)
Button(image=addImageButton, command=self.angle_I_add_click).place(x=390, y=256)
#角度D输入加载
self.angleD = StringVar()
self.angleD.set("0.00")
self.angleDEntry = Entry(textvariable=self.angleD, font=('Asial', 25), highlightcolor='green', highlightthickness=2,
insertbackground='black',bg='white',width=9)
self.angleDEntry.place(x=160, y=381)
Button(image=minusImageButton, command=self.angle_D_minus_click).place(x=330, y=381)
Button(image=addImageButton, command=self.angle_D_add_click).place(x=390, y=381)
#速度P输入加载
self.speedP = StringVar()
self.speedP.set("0.00")
self.speedPEntry = Entry(textvariable=self.speedP, font=('Asial', 25), highlightcolor='green', highlightthickness=2,
insertbackground='black',bg='white',width=9)
self.speedPEntry.place(x=550, y=130)
Button(image=minusImageButton, command=self.speed_p_minus_click).place(x=720, y=128)
Button(image=addImageButton, command=self.speed_p_add_click).place(x=780, y=128)
#速度I输入加载
self.speedI = StringVar()
self.speedI.set("0.00")
self.speedIEntry = Entry(textvariable=self.speedI, font=('Asial', 25), highlightcolor='green', highlightthickness=2,
insertbackground='black',bg='white',width=9)
self.speedIEntry.place(x=550, y=256)
Button(image=minusImageButton, command=self.speed_I_minus_click).place(x=720, y=256)
Button(image=addImageButton, command=self.speed_I_add_click).place(x=780, y=256)
#速度D输入加载
self.speedD = StringVar()
self.speedD.set("0.00")
self.speedDEntry = Entry(textvariable=self.speedD, font=('Asial', 25), highlightcolor='green', highlightthickness=2,
insertbackground='black',bg='white',width=9)
self.speedDEntry.place(x=550, y=381)
Button(image=minusImageButton, command=self.speed_D_minus_click).place(x=720, y=381)
Button(image=addImageButton, command=self.speed_D_add_click).place(x=780, y=381)
#发送按钮加载
global sendImageButton
sendImageButton = PhotoImage(file="../Image/发送.png") #85x30
Button(image=sendImageButton, command=self.send_click).place(x=720, y=440)
#读取按钮加载
global readImageButton
readImageButton = PhotoImage(file="../Image/读取.png") #85x30
Button(image=readImageButton, command=self.read_click).place(x=550, y=440)
#串口打开按钮加载
global openImageButton
openImageButton = PhotoImage(file="../Image/打开.png") #85x30
self.openReadButton=Button(image=openImageButton, command=self.open_click)
self.openReadButton.place(x=380, y=440)
#刷新按钮加载
global updateImageButton
updateImageButton = PhotoImage(file="../Image/刷新.png") #85x30
self.updateserialButton=Button(image=updateImageButton, command=self.update_click)
self.updateserialButton.place(x=210, y=440)
self.update_click()
#发送成功失败显示加载
global buttonOkImage
global buttonFailedImage
global buttonStateImage
buttonOkImage = PhotoImage(file="../Image/成功.png") #85x30
buttonFailedImage = PhotoImage(file="../Image/失败.png") #85x30
buttonStateImage = PhotoImage(file="../Image/状态.png") # 85x30
self.state = Canvas(width=39, height=39)
self.state.place(x=880, y=440)
self.state.create_image(2, 2, anchor='nw', image=buttonOkImage)
#控制按钮加载
global upImage,dowmImage,leftImage,rightImage,clickImage
upImage = PhotoImage(file="../Image/上.png") #85x30
dowmImage = PhotoImage(file="../Image/下.png") #85x30
leftImage = PhotoImage(file="../Image/左.png") # 85x30
rightImage = PhotoImage(file="../Image/右.png") # 85x30
clickImage = PhotoImage(file="../Image/点击.png")
self.upButton = Canvas(width=50, height=50)
self.upButton.place(x=1000, y=370)
self.upButton.create_image(2, 2, anchor='nw', image=upImage)
self.downButton = Canvas(width=50, height=50)
self.downButton.place(x=1000, y=470)
self.downButton.create_image(2, 2, anchor='nw', image=dowmImage)
self.leftButton = Canvas(width=50, height=50)
self.leftButton.place(x=940, y=420)
self.leftButton.create_image(2, 2, anchor='nw', image=leftImage)
self.rightButton = Canvas(width=50, height=50)
self.rightButton.place(x=1060, y=420)
self.rightButton.create_image(2, 2, anchor='nw', image=rightImage)
def move_state_update(self,dir):
global upButton
if dir == 'U':
self.upButton.create_image(2, 2, anchor='nw', image=clickImage)
elif dir == "D":
self.downButton.create_image(2, 2, anchor='nw', image=clickImage)
elif dir == "L":
self.leftButton.create_image(2, 2, anchor='nw', image=clickImage)
elif dir == "R":
self.rightButton.create_image(2, 2, anchor='nw', image=clickImage)
else:
self.upButton.create_image(2, 2, anchor='nw', image=upImage)
self.downButton.create_image(2, 2, anchor='nw', image=dowmImage)
self.leftButton.create_image(2, 2, anchor='nw', image=leftImage)
self.rightButton.create_image(2, 2, anchor='nw', image=rightImage)
def angle_p_add_click(self):
self.angleP.set(Decimal(self.angleP.get())+Decimal("0.01"))
def angle_p_minus_click(self):
if self.angleP.get() not in "0.00":
self.angleP.set(Decimal(self.angleP.get())-Decimal("0.01"))
def angle_I_add_click(self):
self.angleI.set(Decimal(self.angleI.get())+Decimal("0.01"))
def angle_I_minus_click(self):
if self.angleI.get() not in "0.00":
self.angleI.set(Decimal(self.angleI.get())-Decimal("0.01"))
def angle_D_add_click(self):
self.angleD.set(Decimal(self.angleD.get())+Decimal("0.01"))
def angle_D_minus_click(self):
if self.angleD.get() not in "0.00":
self.angleD.set(Decimal(self.angleD.get())-Decimal("0.01"))
def speed_p_add_click(self):
self.speedP.set(Decimal(self.speedP.get())+Decimal("0.01"))
def speed_p_minus_click(self):
if self.speedP.get() not in "0.00":
self.speedP.set(Decimal(self.speedP.get()) - Decimal("0.01"))
def speed_I_add_click(self):
self.speedI.set(Decimal(self.speedI.get())+Decimal("0.01"))
def speed_I_minus_click(self):
if self.speedI.get() not in "0.00":
self.speedI.set(Decimal(self.speedI.get()) - Decimal("0.01"))
def speed_D_add_click(self):
self.speedD.set(Decimal(self.speedD.get())+Decimal("0.01"))
def speed_D_minus_click(self):
if self.speedD.get() not in "0.00":
self.speedD.set(Decimal(self.speedD.get()) - Decimal("0.01"))
def send_click(self):
sendBuf=[]
angleP = self.float_to_hex(float(self.angleP.get()))
angleI = self.float_to_hex(float(self.angleI.get()))
angleD = self.float_to_hex(float(self.angleD.get()))
speedP = self.float_to_hex(float(self.speedP.get()))
speedI = self.float_to_hex(float(self.speedI.get()))
speedD = self.float_to_hex(float(self.speedD.get()))
sendBuf.append(0xFF)
sendBuf.append(order['sendData'])
sendBuf.append(angleP >> 24 & 0xFF)
sendBuf.append(angleP >> 16 & 0xFF)
sendBuf.append(angleP >> 8 & 0xFF)
sendBuf.append(angleP & 0xFF)
sendBuf.append(angleI >> 24 & 0xFF)
sendBuf.append(angleI >> 16 & 0xFF)
sendBuf.append(angleI >> 8 & 0xFF)
sendBuf.append(angleI & 0xFF)
sendBuf.append(angleD >> 24 & 0xFF)
sendBuf.append(angleD >> 16 & 0xFF)
sendBuf.append(angleD >> 8 & 0xFF)
sendBuf.append(angleD & 0xFF)
sendBuf.append(speedP >> 24 & 0xFF)
sendBuf.append(speedP >> 16 & 0xFF)
sendBuf.append(speedP >> 8 & 0xFF)
sendBuf.append(speedP & 0xFF)
sendBuf.append(speedI >> 24 & 0xFF)
sendBuf.append(speedI >> 16 & 0xFF)
sendBuf.append(speedI >> 8 & 0xFF)
sendBuf.append(speedI & 0xFF)
sendBuf.append(speedD >> 24 & 0xFF)
sendBuf.append(speedD >> 16 & 0xFF)
sendBuf.append(speedD >> 8 & 0xFF)
sendBuf.append(speedD & 0xFF)
crc=0
for i in range(1,len(sendBuf)):
crc+=sendBuf[i]
sendBuf.append(crc>>8&0xFF)
sendBuf.append(crc& 0xFF)
sendBuf.append(0xFF)
if not self.comIsCon:
messagebox.showerror(title='串口错误', message='请先打开串口')
return
self._serial.write(sendBuf)
self.state.create_image(2, 2, anchor='nw', image=buttonStateImage)
def read_click(self):
if not self.comIsCon:
messagebox.showerror(title='串口错误', message='请先打开串口')
return
sendBuf=[]
sendBuf.append(0xFF)
sendBuf.append(order['requestData'])
for i in range(24):
sendBuf.append(0x00)
crc=0
for i in range(1,len(sendBuf)):
crc+=sendBuf[i]
sendBuf.append(crc>>8&0xFF)
sendBuf.append(crc& 0xFF)
sendBuf.append(0xFF)
self._serial.write(sendBuf)
def open_click(self):
if self.serialPort.get() == None:
messagebox.showerror(title='串口错误',message='串口号为空,请先插入设备')
return
else:
serialPort = self.serialPort.get()
charPos = serialPort.find('-')
Application.serialPort = serialPort[0:int(charPos-1)]
# 打开串口
try:
self._serial = serial.Serial(port=Application.serialPort,baudrate='115200')
except Exception as e:
print(e)
messagebox.showerror(title='串口错误', message='串口号错误,请检查设备')
return
self.comIsCon=True
self.serialPortMenu["state"]=DISABLED
self.openReadButton["state"]=DISABLED
self.updateserialButton['state']=DISABLED
#启动接收线程
tDataReceived = threading.Thread(target=self.__serial_read)
tDataReceived.setDaemon(True)
tDataReceived.start()
def update_click(self):
#串口号选择
self.serialPort = StringVar()
port_list = list(serial.tools.list_ports.comports())
print(port_list)
self.serialPort.set(port_list[0])
self.serialPortMenu=OptionMenu(self.master,self.serialPort,*port_list)
self.serialPortMenu['width'] = 23
self.serialPortMenu.place(x=0,y=470)
def __serial_read(self):
while self.comIsCon:
try:
self.serialReadData = self._serial.read() # 串口读取数据
except: #串口有异常退出
self.comIsCon=False
self.serialPortMenu["state"] = NORMAL
self.openReadButton["state"] = NORMAL
self.updateserialButton['state'] = NORMAL
break
Application.serialReadBuf.insert(Application.serialReadCnt, self.serialReadData) # 将读取到的数据放入缓冲区中
if Application.serialReadBuf[0] == b'\xff': # 判断包头是不是0xFF
Application.serialReadCnt += 1
if Application.serialReadCnt > 1:
if (Application.serialReadBuf[Application.serialReadCnt - 1] == b'\xff'): # 接受到了包尾
if Application.serialReadBuf[1]== b'\x01':
a=self.hex_to_str(Application.serialReadBuf[2],Application.serialReadBuf[3],Application.serialReadBuf[4],Application.serialReadBuf[5])
data=struct.unpack('<f', bytes.fromhex(a))[0]#小端
self.angleP.set(str(Decimal(data)+Decimal(0.001))[0:4])
a=self.hex_to_str(Application.serialReadBuf[6],Application.serialReadBuf[7],Application.serialReadBuf[8],Application.serialReadBuf[9])
data=struct.unpack('<f', bytes.fromhex(a))[0]#小端
self.angleI.set(str(Decimal(data)+Decimal(0.001))[0:4])
a=self.hex_to_str(Application.serialReadBuf[10],Application.serialReadBuf[11],Application.serialReadBuf[12],Application.serialReadBuf[13])
data=struct.unpack('<f', bytes.fromhex(a))[0]#小端
self.angleD.set(str(Decimal(data)+Decimal(0.001))[0:4])
a=self.hex_to_str(Application.serialReadBuf[14],Application.serialReadBuf[15],Application.serialReadBuf[16],Application.serialReadBuf[17])
data=struct.unpack('<f', bytes.fromhex(a))[0]#小端
self.speedP.set(str(Decimal(data)+Decimal(0.001))[0:4])
a=self.hex_to_str(Application.serialReadBuf[18],Application.serialReadBuf[19],Application.serialReadBuf[20],Application.serialReadBuf[21])
data=struct.unpack('<f', bytes.fromhex(a))[0]#小端
self.speedI.set(str(Decimal(data)+Decimal(0.001))[0:4])
a=self.hex_to_str(Application.serialReadBuf[22],Application.serialReadBuf[23],Application.serialReadBuf[24],Application.serialReadBuf[25])
data=struct.unpack('<f', bytes.fromhex(a))[0]#小端
self.speedD.set(str(Decimal(data)+Decimal(0.001))[0:4])
Application.serialReadCnt=0
Application.serialReadBuf.clear()
elif Application.serialReadBuf[1]== b'\x03': #成功
self.state.create_image(2, 2, anchor='nw', image=buttonOkImage)
Application.serialReadCnt=0
Application.serialReadBuf.clear()
elif Application.serialReadBuf[1]== b'\x04': #失败
self.state.create_image(2, 2, anchor='nw', image=buttonFailedImage)
Application.serialReadCnt=0
Application.serialReadBuf.clear()
else:
self.serialReadCnt = 0
print ("read thread over")
def float_to_hex(self,s):
return struct.unpack('<I', struct.pack('>f', s))[0]
def hex_to_str(self,a,b,c,d):
e=str(hex(a[0]))[2:]
if len(e)==1:
e='00'
f=str(hex(b[0]))[2:]
if len(f)==1:
f='00'
g=str(hex(c[0]))[2:]
if len(g)==1:
g='00'
h=str(hex(d[0]))[2:]
if len(h)==1:
h='00'
return e+f+g+h
def key_press(self,key):
if Application.keyDowmFlag != 1:
Application.keyDowmFlag = 1
else:
return
sendBuf = []
sendBuf.append(0xFF)
sendBuf.append(order['controlData'])
if not self.comIsCon:
messagebox.showerror(title='串口错误', message='请先打开串口')
return
try:
print("正在按压:", format(key.char))
except AttributeError:
if key == Key.up:
self.move_state_update("U")
sendBuf.append(0x01)
elif key == Key.down:
self.move_state_update("D")
sendBuf.append(0x02)
elif key == Key.left:
self.move_state_update("L")
sendBuf.append(0x03)
elif key == Key.right:
self.move_state_update("R")
sendBuf.append(0x04)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
crc=0
for i in range(1,len(sendBuf)):
crc+=sendBuf[i]
sendBuf.append(crc>>8&0xFF)
sendBuf.append(crc& 0xFF)
sendBuf.append(0xFF)
self._serial.write(sendBuf)
def key_release(self,key):
if Application.keyDowmFlag == 0:
return
if not self.comIsCon:
messagebox.showerror(title='串口错误', message='请先打开串口')
return
Application.keyDowmFlag = 0
self.move_state_update("A")
sendBuf = []
sendBuf.append(0xFF)
sendBuf.append(order['controlData'])
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
sendBuf.append(0x00)
crc=0
for i in range(1,len(sendBuf)):
crc+=sendBuf[i]
sendBuf.append(crc>>8&0xFF)
sendBuf.append(crc& 0xFF)
sendBuf.append(0xFF)
self._serial.write(sendBuf)
def start_listen(self):
with Listener(on_press=self.key_press,on_release=self.key_release) as listener:
listener.join()
if __name__ == '__main__':
root = Tk()
root.geometry("1500x530")
root.title("PID调试上位机")
root.resizable(0,0)
app = Application(root)
keyListion = threading.Thread(target=app.start_listen)
keyListion.setDaemon(True)
keyListion.start()
root.mainloop()
主界面:
还在更新中,有问题及时联系
转载:https://blog.csdn.net/qq_15181569/article/details/102554957
查看评论