1. 程式人生 > >用PySimpleGUI和pyserial輕鬆組建微控制器的上位機控制系統

用PySimpleGUI和pyserial輕鬆組建微控制器的上位機控制系統

PySimpleGUI是能輕鬆簡單地建立視覺化應用程式

pyserial串列埠開發模組

PySimpleGUI簡單示例:

import PySimpleGUI as sg
import serial 

layout=[
[sg.Text('第一行')],
[sg.Button('第二行')]
]

window=sg.Window('這是個標題').Layout(layout)

button,value=window.Read()

print('button:',button)

print('value:',value)



執行結果如下:

其中layout是個二維陣列,layout[0][0]代表第一行第一列,layout[1][0]代表第二行第一列,以此類推,組成一個佈局。

而且其中的window.Read()會阻塞程式的進行,直到Button('第二行')被點選才退出。

常用的元件:

sg.InputText('Default text')                                                                                                                                    文字輸入框 sg.InputCombo(['choice 1', 'choice 2'])                                                                                                                 下拉列表 sg.Listbox(values=['Listbox 1', 'Listbox 2', 'Listbox 3'], size=(30, 6))                                                                     列表框元素 sg.Slider(range=(1,500), default_value=222, size=(20,15), orientation='horizontal', font=('Helvetica', 12))         滑塊元素 sg.Radio('My first Radio!', "RADIO1", default=True)                                                                                             單選按鈕 sg.Checkbox('My first Checkbox!', default=True)                                                                                                  複選框

框架元件:

sg.Frame('title','layout')-----title=框架標題,layout=元件的佈局

import PySimpleGUI as sg
import serial

child_layout=[[sg.Text('第一行')],[sg.Text('第二行')]]

layout=[
[sg.Text('第一行'),sg.Frame('標題',child_layout)]
]


window=sg.Window('這是個標題').Layout(layout)

button,value=window.Read()

print('button:',button)

print('value:',value)

執行結果如下:

配置pyserial:

import serial

ser = serial.Serial()
ser.baudrate = 115200    #波特率
ser.port = 'COM1'        #com口
ser.stopbits=1           #停止位 1 1.5 2
ser.bytesize=8           #資料位
ser.parity='N'           #奇偶位  N沒有  E偶校驗  O奇校驗
ser.timeout=5            #超時時間

ser.open()     #連線失敗會丟擲錯誤

ser.write('hello\n'.encode())    #傳送資訊

result=ser.readline().decode()  #接收資訊

print(result)

把PySimpleGUI和pyserial組合起來就可以實現自己定義功能的上位機控制程式了

示例(搭建簡單的ESP8266串列埠除錯助手):

程式碼如下:

import PySimpleGUI as sg
from serial import Serial
from threading import Thread


com=('COM1','COM2','COM3','COM4','COM5','COM6','COM7','COM8','COM9','COM10')
baud_rate=('115200','9600','38400')
Stop_bit=('1','1.5','2')
data_bit=('8','7','6','5')
verify=('無','奇校驗','偶校驗')


layout1 =  [[sg.Text('COM口:'),sg.InputCombo(com,size=(15, 1))],
          [sg.Text('波特率:'),sg.InputCombo(baud_rate,size=(15, 1))],
          [sg.Text('停止位:'),sg.InputCombo(Stop_bit,size=(15, 1))],
          [sg.Text('資料位:'),sg.InputCombo(data_bit,size=(15, 1))],
          [sg.Text('奇偶位:'),sg.InputCombo(verify,size=(15, 1))],
          [sg.RButton('連線串列埠',size=(20,1))]]

button_size=(15,1)

Configure_button=[[sg.T('   '),sg.Text('響應測試',size=(15,1)),sg.T('   '),sg.Text('復位',size=(13,1)),sg.Text('設定模式',size=(15,1))],
        [sg.RButton('AT',size=button_size),sg.RButton('AT+RST',size=button_size),sg.RButton('AT+CWMODE=2',size=button_size)],
        [sg.T('   '),sg.Text('設定wifi名稱 密碼 通道 安全性'),sg.T(' '*15),sg.Text('開啟多連線')],
        [sg.RButton('AT+CWSAP="esp8266","0123456789",11,3',size=(35,1)),sg.RButton('AT+CIPMUX=1')],
        [sg.T(' '),sg.Text('設定埠號')],
        [sg.RButton('AT+CIPSERVER=1,8080')]]

send_configure=[[sg.InputText('',key='input',size=(41,1)),sg.Checkbox('自動換行',default=True),sg.RButton('傳送')]]

layout=[[sg.Multiline('',key='message',size=(29,5)),sg.Frame('',layout1)],
        [sg.Frame('命令配置',Configure_button)],
        [sg.Frame('傳送區',send_configure)]
]



window=sg.Window('糖醋鹹魚ESP8266配置助手').Layout(layout)

ser=None
text=''

isRun=True
def readData():
    global isRun
    global text
    while isRun:
        if ser != None and ser.is_open:
            if text.count('\n')>5:
                text=text[text.index('\n')+1:]
            text+=ser.read().decode()


while True:
    button, value = window.ReadNonBlocking()
    window.FindElement('message').Update(text)
    if button==None and value==None:
        print('結束程式')
        isRun=False
        break

    if button=='連線串列埠':
        ser = Serial()
        ser.baudrate = int(value[1])  #波特率
        ser.port = value[0]    #com口
        ser.stopbits=int(value[2])     #停止位 1 1.5 2
        ser.bytesize=int(value[3])       #資料位

        if value[5]=='無':     #奇偶位  N沒有  E偶數  O奇數
            ser.parity='N'
        elif value[5]=='奇校驗':
            ser.parity = 'O'
        elif value[5] == '偶校驗':
            ser.parity = 'E'

        ser.timeout=5       #超時時間
        try:
            ser.open()
            sg.Popup('連線成功')
            t = Thread(target=readData, name='read_data')
            t.start()   #開始執行緒
        except Exception as e:
            sg.Popup('連線失敗')

    elif button=='傳送':

        if ser!=None and ser.is_open:
            if value['input']!='':
                if value[5]==True:
                    ser.write((value['input']+'\n').encode())
                    ser.flush()
                else:
                    ser.write(value['input'].encode())
                    ser.flush()
                
            else:
                sg.Popup('請輸入內容')
        else:
            sg.Popup('沒有連線')
    else:
        window.FindElement('input').Update(button)    #修改傳送框的內容