python串列埠助手
最近專案中要使用模擬資料來源通過向外傳送資料,以前都是用C#編寫,最近在研究python,所以就用python寫了一個串列埠助手,方便以後的測試。
在電腦上通過虛擬串列埠助手產生兩個虛擬串列埠,執行編寫的串列埠助手
另外,開啟一個串列埠除錯助手,輔助測試
兩者互發資料,可以看到編寫的串列埠助手能夠正常接收發送,並且在後臺我們也把接收到的資料列印了出來
下面先講解關於介面的程式碼,這裡只是簡單的使用tkinter做介面,如果想要更好的介面效果,可以嘗試一下QT。
首先是介面中串列埠設定區域的程式碼,介面佈局統一用grid來佈局,當然也有其他的佈局方法
1 #------------------------------------------------------------------------- 2 #面板佈局區 3 root = Tk() 4 root.title('xutopia 公眾號:洛水梅家') 5 6 #------------------------------------------------------------------------- 7 #串列埠設定區 8 label_com = Label(root, text="串列埠號", height=2).grid(row=0, column=0) 9 label_bps = Label(root, text="波特率", height=2).grid(column=0, row=1) 10 label_datBit = Label(root, text="資料位", height=2).grid(column=0, row=2) 11 label_parity = Label(root, text="校驗位", height=2).grid(column=0, row=3) 12 label_stop_bit = Label(root, text="停止位", height=2).grid(column=0, row=4)
接下來是串列埠號的combobox的設定,其中serialPortFile.GetCom()是獲取所有串列埠號的函式,接下來會講解
#串列埠號 varPort = StringVar() combo_com = ttk.Combobox(root, textvariable=varPort, width=8, height=2, justify=CENTER) serial_com = serialPortFile.GetCom() combo_com['values'] = serial_com #combo_com.bind("<<ComboboxSelected>>", lambda event: combo1_handler(var=varPort.get())) combo_com.current(0) combo_com.grid(column=1, row=0)
1 #波特率 2 varBitrate = StringVar() 3 combo_bps = ttk.Combobox(root, textvariable=varBitrate, width=8, height=2, justify=CENTER) 4 combo_bps['values'] = ("9600", "19200", "38400", "115200") 5 #combo_bps.bind("<<ComboboxSelected>>", lambda event: combo2_handler(var=varBitrate.get())) 6 combo_bps.current(0) 7 combo_bps.grid(column=1, row=1) 8 #資料位 9 combo_byteBit = ttk.Combobox(root, width=8, height=2, justify=CENTER) 10 combo_byteBit['values'] = ("5", "6", "7", "8") 11 combo_byteBit.current(3) 12 combo_byteBit.grid(column=1, row=2) 13 #奇偶校驗 14 combo_parity = ttk.Combobox(root, width=8, height=2, justify=CENTER) 15 combo_parity['values'] = ("N", "O", "E") 16 combo_parity.current(0) 17 combo_parity.grid(column=1, row=3) 18 #停止位 19 combo_stopBit = ttk.Combobox(root, width=8, height=2, justify=CENTER) 20 combo_stopBit['values'] = ("1", "1.5", "2") 21 combo_stopBit.current(0) 22 combo_stopBit.grid(column=1, row=4) 23 serialPortFile.text_rx = Text(root,width=70,height=20) 24 serialPortFile.text_rx.grid(row=0,column=3,rowspan=5) 25 serialPortFile.text_rx.insert(END,'這是一個xutopia用python編寫的串列埠助手,公眾號:洛水梅家\n') 26 text_tx = Text(root,width=70,height=10) 27 text_tx.grid(row=5,column=3,rowspan=2) 28 text_tx.insert(END,'xutopia 公眾號:洛水梅家,傳送資料12345,上山打老虎') 29 button_send = Button(root, text='send', width=18, height=1) 30 button_send.bind("<Button-1>", lambda event: serialPortFile.usart_sent(var=text_tx.get("0.0", "end"))) 31 button_send.grid(column=1, row=6) 32 #串列埠開關按鈕 33 serialPortFile.button_var = StringVar() 34 serialPortFile.button_var.set("開啟串列埠") 35 buttonOpenCom = Button(root, textvariable=serialPortFile.button_var, width=18, height=1) 36 buttonOpenCom.bind("<Button-1>", lambda event: serialPortFile.usart_ctrl(combo_com.get(), combo_bps.get(),combo_parity.get(),combo_stopBit.get(),combo_byteBit.get())) 37 buttonOpenCom.grid(column=1, row=5)
以上就是介面相關的程式碼,最終效果也就是上圖顯示的效果,很簡單。接下來介紹python串列埠的邏輯程式碼部分。在另外一個模組中serialPortFile.py
獲取電腦中所有的串列埠號的函式,注意這裡通過serial.tools.list_ports.comports()獲取所有的串列埠號之後進行了一步轉換,存在一個數組中,這樣,傳入serial中才能被識別。
1 # 獲取並存儲串列埠號到陣列 2 def GetCom(): 3 port_list = list(serial.tools.list_ports.comports()) 4 print(len(port_list)) 5 portcnt = len(port_list) 6 serial_com = [] 7 for m in range(portcnt): 8 port_list_1 = list(port_list[m]) 9 serial_com.append(port_list_1[0]) 10 return serial_com
串列埠開啟關閉函式,串列埠開啟之後建立了一個執行緒threading,執行緒中一直監視串列埠的狀態,一旦接受到資料,就把資料顯示到接受資料顯示框中。有關python執行緒threading的內容可以在我的公眾號,洛水梅家中檢視。
注意在程式碼中加了一個if ser.is_open:的條件判斷,不加入這個條件的話,很有可能重複開啟串列埠而報錯誤。
同時在按鍵Button的狀態也隨著串列埠的開關狀態而變化。
def usart_ctrl(com, bps,parity_,stopbits_,bytesize_): #print(__file__, sys._getframe().f_lineno, port_, bitrate_, var.get()) global ser, button_var if button_var.get() == "開啟串列埠": button_var.set("關閉串列埠") ser = serial.Serial( port=com, baudrate=int(bps), parity=parity_, timeout=0.2, stopbits=float(stopbits_), bytesize=int(bytesize_)) if ser.is_open: pass else: ser.open() recv_data = threading.Thread(target=thread_recv) recv_data.start() else: button_var.set("開啟串列埠") if ser.is_open: ser.close() else: pass
def usart_sent(var): #print(__file__, sys._getframe().f_lineno, "-->", var) print(var) if ser.is_open: ser.write(var.encode("gb2312")) def thread_recv(): global text_rx while True: try: read = ser.readall() if len(read) > 0: print(bytes(read).decode('gb2312')) # print(__file__, sys._getframe().f_lineno, "<--", bytes(read).decode('ascii')) text_rx.insert(END,bytes(read).decode('gb2312')) except Exception as e: print(e) time.sleep(1) pass
上面就是關於串列埠助手的所有程式碼介紹,更多詳細內容,關注公眾號 洛水梅家 免費獲取原始碼
後臺回覆python_com,免費獲取原始碼
&n