应变片信号采集--串口程序--借助python和tkinter
生活随笔
收集整理的這篇文章主要介紹了
应变片信号采集--串口程序--借助python和tkinter
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
?應(yīng)變片信號(hào)采集--串口程序
- 解決方案
利用python中的serial串口通信工具包實(shí)現(xiàn)與下位機(jī)通信,利用tkinter工具包編寫(xiě)GUI界面用于實(shí)時(shí)顯示采集到的信號(hào)和傳輸指令。
界面設(shè)計(jì):
?最終效果:
?
?參考代碼:
#應(yīng)變信號(hào)采集(為保證測(cè)量精確度,可將砝碼及物體的質(zhì)量擴(kuò)大100000倍,代入計(jì)算) #! /usr/bin/env python # -*- coding: utf-8 -*-import threading import tkinter as tk import serial.tools.list_ports from tkinter import ttk from tkinter import scrolledtext#創(chuàng)建存檔文件 file=open('data.csv', 'w+') #定義父容器 SerialPort = serial.Serial() GUI = tk.Tk() # 父容器 GUI.title("Serial Tool") # 父容器標(biāo)題 GUI.geometry("440x600") # 父容器大小#顯示操作信息的框圖 Information = tk.LabelFrame(GUI, text="操作信息", padx=10, pady=10) # 創(chuàng)建一個(gè)框架 Information.place(x=20, y=20) #將該框架放在x=20,y=20的地方 Information_Window = scrolledtext.ScrolledText(Information, width=20, height=5, padx=10, pady=10, wrap=tk.WORD) #創(chuàng)建一個(gè)有滾動(dòng)條的文本框 Information_Window.grid()#創(chuàng)建發(fā)送指令框架 Send = tk.LabelFrame(GUI, text="發(fā)送指令", padx=10, pady=5) # 水平,垂直方向上的邊距均為 10 Send.place(x=240, y=20) # 定義保存文本框內(nèi)容的字符串 DataSend = tk.StringVar() #輸出窗的內(nèi)容 EntrySend = tk.StringVar() #輸入窗的內(nèi)容 #創(chuàng)建輸入窗口 Send_Window = ttk.Entry(Send, textvariable=EntrySend, width=23) #窗口的指令為 textvariable, Send_Window.grid()#將輸入的指令輸出到輸出窗口,并執(zhí)行指令 def WriteData():global DataSendDataSend = EntrySend.get()Information_Window.insert("end", '發(fā)送指令為:' + str(DataSend) + '\n') # 在操作信息窗口顯示發(fā)送的指令并換行,end為在窗口末尾處顯示Information_Window.see("end") # 此處為顯示操作信息窗口進(jìn)度條末尾內(nèi)容,以上兩行可實(shí)現(xiàn)窗口內(nèi)容滿時(shí),進(jìn)度條自動(dòng)下滾并在最下方顯示新的內(nèi)容SerialPort.write(bytes(DataSend, encoding='utf8'))#將指定的字符串寫(xiě)入串行端口。發(fā)送命令,編碼成utf8格式#設(shè)置一個(gè)激活以上操作的按鈕 tk.Button(Send, text="發(fā)送", command=WriteData).grid(pady=5, sticky=tk.E) #放在最東面#接收文本框(帶滾動(dòng)條) Receive = tk.LabelFrame(GUI, text="接收區(qū)", padx=10, pady=10) # 水平,垂直方向上的邊距均為 10 Receive.place(x=240, y=124) Receive_Window = scrolledtext.ScrolledText(Receive, width=18, height=9, padx=8, pady=10, wrap=tk.WORD) Receive_Window.grid()#建立系數(shù) #設(shè)定初始值 k=1.0 b=0.0 text1=tk.Label(GUI, text="k:",padx=10, pady=10) #Label組件用于顯示文本和圖像 text1.place(x=220, y=350) text2=tk.Label(GUI, text="b:",padx=10, pady=10) text2.place(x=220, y=380) v1 = tk.StringVar() v2 = tk.StringVar() e1 = tk.Entry(GUI,textvariable=v1) e2 = tk.Entry(GUI,textvariable=v2) e1.place(x=290, y=360) e2.place(x=290, y=390) def insert_1():global k,bk = v1.get()k=float(k)b = v2.get()b = float(b) b2=tk.Button(GUI,text='輸入?yún)?shù)',width=8,height=1,command=insert_1) b2.place(x=290, y=420)#建立物品質(zhì)量框圖 result = tk.LabelFrame(GUI, text='物品質(zhì)量 /g', padx=10, pady=10) # 水平,垂直方向上的邊距均為 10 result.place(x=20, y=350) result_Window = scrolledtext.ScrolledText(result, width=18, height=9, padx=8, pady=10, wrap=tk.WORD) result_Window.grid()#傳輸數(shù)據(jù)選項(xiàng)框圖 option = tk.LabelFrame(GUI, text="選項(xiàng)", padx=10, pady=10) # 水平,垂直方向上的邊距均為10 option.place(x=20, y=150, width=203) # 坐標(biāo)位置 # 創(chuàng)建下拉列表 ttk.Label(option, text="串口號(hào):").grid(column=0, row=0) # 添加串口號(hào)標(biāo)簽,第0行第0列 ttk.Label(option, text="波特率:").grid(column=0, row=1) # 添加波特率標(biāo)簽 #建立端口號(hào)列表 Port = tk.StringVar() # 端口號(hào)字符串 Port_list = ttk.Combobox(option, width=12, textvariable=Port, state='readonly')#創(chuàng)建下拉菜單欄 ListPorts = list(serial.tools.list_ports.comports())#掃描當(dāng)前可用串口保存到表ListPorts Port_list['values'] = [i[0] for i in ListPorts]## 下拉列表的值為L(zhǎng)istPorts的所有值 Port_list.current()# 初始顯示表中第一個(gè)值 Port_list.grid(column=1, row=0) # 設(shè)置其在界面中出現(xiàn)的位置 #建立波特率列表 BaudRate = tk.StringVar() # 波特率字符串 BaudRate_list = ttk.Combobox(option, width=12, textvariable=BaudRate, state='readonly') BaudRate_list['values'] = (1200, 2400, 4800, 9600, 14400, 19200, 38400, 43000, 57600, 76800, 115200) BaudRate_list.current(5)# 初始顯示19200 BaudRate_list.grid(column=1, row=1) # 設(shè)置其在界面中出現(xiàn)的位置 column代表列 row 代表行#開(kāi)關(guān)框圖 switch = tk.LabelFrame(GUI, text="開(kāi)關(guān)", padx=10, pady=10) # 水平,垂直方向上的邊距均為 10 switch.place(x=20, y=250, width=203) # 定位坐標(biāo)#不斷讀取串口數(shù)據(jù),并計(jì)算 def ReceiveData():while SerialPort.isOpen():Receive_Window.insert("end", str(SerialPort.readline()) + '\n') #在接收窗口不斷顯示接受的數(shù)據(jù),一行一行地讀數(shù)據(jù)Receive_Window.see("end")#number = int.from_bytes(str(SerialPort.readline()), byteorder='big') #全部讀取的方式,一般不用# 轉(zhuǎn)換字符串為16進(jìn)制,再轉(zhuǎn)換為10進(jìn)制。data = SerialPort.readline()#讀取的數(shù)據(jù)類(lèi)型為字節(jié)類(lèi)型str1 = data.hex() # 轉(zhuǎn)換為16進(jìn)制,解碼num0 = str1[6:] # 截取需要的數(shù)據(jù)部分num1 = int(num0, 16) # 轉(zhuǎn)換為10進(jìn)制print(num1)file = open('data.csv', 'a')file.write(str(num1) + '\n')file.close()num1=float(num1)result_Window.insert("end", str(b+k*num1) + '\n')#將字節(jié)串轉(zhuǎn)換為數(shù)字并求出方程result_Window.see("end") #關(guān)閉數(shù)據(jù)的讀取 def Close_Serial():SerialPort.close() #打開(kāi)數(shù)據(jù)讀取 def Open_Serial():if not SerialPort.isOpen():SerialPort.port = Port_list.get()# 讀取端口下拉菜單欄的選擇,將其設(shè)為串口的端口SerialPort.baudrate = BaudRate_list.get()# 讀取波特率下拉菜單欄的選擇,將其設(shè)為串口的波特率SerialPort.timeout = 0.1SerialPort.open() # 打開(kāi)串口if SerialPort.isOpen():t = threading.Thread(target=ReceiveData) # 新建線程用來(lái)不斷接收數(shù)據(jù)并顯示,與主線程并行t.setDaemon(True)# 守護(hù)線程t.start()# 開(kāi)始線程else:SerialPort.close() #設(shè)置開(kāi)始和結(jié)束按鈕,并執(zhí)行指令 tk.Button(switch, text="開(kāi)始采集", command=Open_Serial).pack(side="left", padx=13) tk.Button(switch, text="停止采集", command=Close_Serial).pack(side="right", padx=13)GUI.mainloop()#程序還是有點(diǎn)小問(wèn)題,敬請(qǐng)改正#
總結(jié)
以上是生活随笔為你收集整理的应变片信号采集--串口程序--借助python和tkinter的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: IDEA java编译中出现了Excep
- 下一篇: php大学生创意礼品电商平台的设计与实现