python實現串口通訊小程序(GUI界面)
使用python實現串口通訊需要使用python的pyserial庫來實現,這個庫在安裝python的時候沒有自動進行安裝,需要自己進行安裝。
1、安裝pyserial庫:
打開命令行窗口,在命令行中輸入:pip install pyserial 命令進行安裝。
2、程序使用python自帶的GUI庫tkinter來實現GUI窗口,使用pyserial來實現串口通訊模塊。
效果圖如下:
串口號選擇框會自動加載所有可用的串口號,並且顯示在選擇框中。在使用時選擇合適的串口號,然后點擊打開串口按鍵即可。
注:本程序使用的是虛擬串口
3、效果演示:
1)發送數據演示:
注:在發送數據顯示框中顯示字符,則表明發送成功
動態效果演示:
2)接收數據演示:
注:接收數據顯示框顯示字符,則表明發送數據成功
動態演示效果:
4:工程介紹:
本工程由兩個文件組成:分別是GUI文件和串口文件。
文件代碼如下:
GUI文件:
'''
@ author: summer
@ tools: pycharm
@ content: 實現串口通訊主類
@ date: 2020.2.12
'''
import tkinter
from tkinter import ttk
from 串口通訊.SerialClass import SerialAchieve # 導入串口通訊類
class MainSerial:
def __init__(self):
# 定義串口變量
self.port = None
self.band = None
self.check = None
self.data = None
self.stop = None
self.myserial = None
# 初始化窗體
self.mainwin = tkinter.Tk()
self.mainwin.title("串口調試工具")
self.mainwin.geometry("600x400")
# 標簽
self.label1 = tkinter.Label(self.mainwin,text = "串口號:",font = ("宋體",15))
self.label1.place(x = 5,y = 5)
self.label2 = tkinter.Label(self.mainwin, text="波特率:", font=("宋體", 15))
self.label2.place(x=5, y=45)
self.label3 = tkinter.Label(self.mainwin, text="校驗位:", font=("宋體", 15))
self.label3.place(x=5, y=85)
self.label4 = tkinter.Label(self.mainwin, text="數據位:", font=("宋體", 15))
self.label4.place(x=5, y=125)
self.label5 = tkinter.Label(self.mainwin,text = "停止位:",font = ("宋體",15))
self.label5.place(x = 5,y = 165)
# 文本顯示,清除發送數據
self.label6 = tkinter.Label(self.mainwin, text="發送數據:", font=("宋體", 15))
self.label6.place(x=230, y=5)
self.label7 = tkinter.Label(self.mainwin, text="接收數據:", font=("宋體", 15))
self.label7.place(x=230, y=200)
# 串口號
self.com1value = tkinter.StringVar() # 窗體中自帶的文本,創建一個值
self.combobox_port = ttk.Combobox(self.mainwin, textvariable=self.com1value,
width = 10,font = ("宋體",13))
# 輸入選定內容
self.combobox_port["value"] = [""] # 這里先選定
self.combobox_port.place(x = 105,y = 5) # 顯示
# 波特率
self.bandvalue = tkinter.StringVar() # 窗體中自帶的文本,創建一個值
self.combobox_band = ttk.Combobox(self.mainwin, textvariable=self.bandvalue, width=10, font=("宋體", 13))
# 輸入選定內容
self.combobox_band["value"] = ["4800","9600","14400","19200","38400","57600","115200"] # 這里先選定
self.combobox_band.current(6) # 默認選中第0個
self.combobox_band.place(x=105, y=45) # 顯示
# 校驗位
self.checkvalue = tkinter.StringVar() # 窗體中自帶的文本,創建一個值
self.combobox_check = ttk.Combobox(self.mainwin, textvariable=self.checkvalue, width=10, font=("宋體", 13))
# 輸入選定內容
self.combobox_check["value"] = ["無校驗位"] # 這里先選定
self.combobox_check.current(0) # 默認選中第0個
self.combobox_check.place(x=105, y=85) # 顯示
# 數據位
self.datavalue = tkinter.StringVar() # 窗體中自帶的文本,創建一個值
self.combobox_data = ttk.Combobox(self.mainwin, textvariable=self.datavalue, width=10, font=("宋體", 13) )
# 輸入選定內容
self.combobox_data["value"] = ["8", "9", "0"] # 這里先選定
self.combobox_data.current(0) # 默認選中第0個
self.combobox_data.place(x=105, y=125) # 顯示
# 停止位
self.stopvalue = tkinter.StringVar() # 窗體中自帶的文本,創建一個值
self.combobox_stop = ttk.Combobox(self.mainwin, textvariable=self.stopvalue, width=10, font=("宋體", 13))
# 輸入選定內容
self.combobox_stop["value"] = ["1", "0"] # 這里先選定
self.combobox_stop.current(0) # 默認選中第0個
self.combobox_stop.place(x=105, y=165) # 顯示
# 按鍵顯示,打開串口
self.button_OK = tkinter.Button(self.mainwin, text="打開串口",
command=self.button_OK_click, font = ("宋體",13),
width = 10,height = 1)
self.button_OK.place(x = 5,y = 210) # 顯示控件
# 關閉串口
self.button_Cancel = tkinter.Button(self.mainwin, text="關閉串口", # 顯示文本
command=self.button_Cancel_click, font = ("宋體",13),
width=10, height=1)
self.button_Cancel.place(x = 120,y = 210) # 顯示控件
# 清除發送數據
self.button_Cancel = tkinter.Button(self.mainwin, text="清除發送數據", # 顯示文本
command=self.button_clcSend_click, font=("宋體", 13),
width=13, height=1)
self.button_Cancel.place(x=400, y=2) # 顯示控件
# 清除接收數據
self.button_Cancel = tkinter.Button(self.mainwin, text="清除接收數據", # 顯示文本
command=self.button_clcRece_click, font=("宋體", 13),
width=13, height=1)
self.button_Cancel.place(x=400, y=197) # 顯示控件
# 發送按鍵
self.button_Send = tkinter.Button(self.mainwin, text="發送", # 顯示文本
command=self.button_Send_click, font=("宋體", 13),
width=6, height=1)
self.button_Send.place(x=5, y=255) # 顯示控件
# 接收按鍵
self.button_Send = tkinter.Button(self.mainwin, text="接收", # 顯示文本
command=self.button_Rece_click, font=("宋體", 13),
width=6, height=1)
self.button_Send.place(x=5, y=310) # 顯示控件
# 顯示框
# 實現記事本的功能組件
self.SendDataView = tkinter.Text(self.mainwin,width = 40,height = 9,
font = ("宋體",13)) # text實際上是一個文本編輯器
self.SendDataView.place(x = 230,y = 35) # 顯示
self.ReceDataView = tkinter.Text(self.mainwin, width=40, height=9,
font=("宋體", 13)) # text實際上是一個文本編輯器
self.ReceDataView.place(x=230, y=230) # 顯示
# 發送的內容
test_str = tkinter.StringVar(value="Hello")
self.entrySend = tkinter.Entry(self.mainwin, width=13,textvariable = test_str,font = ("宋體",15))
self.entrySend.place(x = 80,y = 260) # 顯示
# 獲取文件路徑
test_str = tkinter.StringVar(value="Hello")
self.entrySend = tkinter.Entry(self.mainwin, width=13, textvariable=test_str, font=("宋體", 15))
self.entrySend.place(x=80, y=260) # 顯示
# 獲取界面的參數
self.band = self.combobox_band.get()
self.check = self.combobox_check.get()
self.data = self.combobox_data.get()
self.stop = self.combobox_stop.get()
print("波特率:"+self.band)
self.myserial = SerialAchieve(int(self.band),self.check,self.data,self.stop)
# 處理串口值
self.port_list = self.myserial.get_port()
port_str_list = [] # 用來存儲切割好的串口號
for i in range(len(self.port_list)):
# 將串口號切割出來
lines = str(self.port_list[i])
str_list = lines.split(" ")
port_str_list.append(str_list[0])
self.combobox_port["value"] = port_str_list
self.combobox_port.current(0) # 默認選中第0個
def show(self):
self.mainwin.mainloop()
def button_OK_click(self):
'''
@ 串口打開函數
:return:
'''
if self.port == None or self.port.isOpen() == False:
self.myserial.open_port(self.combobox_port.get())
print("打開串口成功")
else:
pass
def button_Cancel_click(self):
self.myserial.delete_port()
print("關閉串口成功")
def button_clcSend_click(self):
self.SendDataView.delete("1.0","end")
def button_clcRece_click(self):
self.ReceDataView.delete("1.0", "end")
def button_Send_click(self):
try:
if self.myserial.port.isOpen() == True:
print("開始發送數據")
send_str1 = self.entrySend.get()
self.myserial.Write_data(send_str1)
self.SendDataView.insert(tkinter.INSERT, send_str1+" ")
print("發送數據成功")
else:
print("串口沒有打開")
except:
print("發送失敗")
def button_Rece_click(self):
try:
readstr = self.myserial.Read_data()
self.ReceDataView.insert(tkinter.INSERT, readstr + " ")
except:
print("讀取失敗")
if __name__ == '__main__':
my_ser1 = MainSerial()
my_ser1.show()
串口文件:
'''
@ author: summer
@ tools: pycharm
@ content: 串口通訊實現類
@ date: 2020.2.12
'''
import serial
import serial.tools.list_ports
class SerialAchieve:
def __init__(self,band=115200,check="無校驗位",data=8,stop=1):
self.port = None
# 獲取可用串口
self.port_list = list(serial.tools.list_ports.comports())
assert (len(self.port_list) != 0),"無可用串口"
self.bandRate = band
self.checkbit = check
self.databit = data
self.stopbit = stop
# 讀寫的數據
self.read_data = None
self.write_data = None
pass
def show_port(self):
for i in range(0,len(self.port_list)):
print(self.port_list[i])
def show_other(self):
print("波特率:"+self.bandRate)
print("校驗位:" + self.checkbit)
print("數據位:" + self.databit)
print("停止位:" + self.stopbit)
# 返回串口
def get_port(self):
return self.port_list
# 打開串口
def open_port(self,port):
self.port = serial.Serial(port, self.bandRate,timeout = None)
def delete_port(self):
if self.port != None:
self.port.close()
print("關閉串口完成")
else:
pass
def Read_data(self): # self.port.read(self.port.in_waiting) 表示全部接收串口中的數據
self.read_data = self.port.read(self.port.in_waiting) # 讀取數據
return self.read_data.decode("utf-8")
def Write_data(self,data):
if self.port.isOpen() == False:
print("串口打開錯誤")
else:
self.port.write(data.encode("utf-8")) # 返回的是寫入的字節數
if __name__ == '__main__':
myser = SerialAchieve()
myser.open_port("COM7")
myser.delete_port()
myser.show_port()
由於程序寫的比較匆忙,所以還有很多需要完善的地方,如果你對這個工程感興趣可以一起來完善它。
本工程GitHub地址