python学习之串口通信

因项目需要,简单写了一个python的串口通信demo

效果图:

简单实现了打开后自动搜索存在的串口,也可以点击扫描端口进行扫描,默认9600波特率,8数据位,偶校验,1停止位。大家可以自行修改,或者通过载入json文件修改(只做了入口没实现)。

发送数据的话调用以下语句即可

python 复制代码
data_to_send = bytes.fromhex('AA BB CC 00 0A D0 1F')

ser.write(data_to_send)

关于数据接收,demo用的serial库需要自己主动去读取,不想主动读取的话可以用python的多线程,或者改用异步的串口库。

检验,停止位,数据位参考:自己安装目录下的python\Lib\site-packages\serial\serialutil.py

源代码如下:

python 复制代码
import warnings
import PySimpleGUI as sg
import json
import serial
import serial.tools.list_ports

warnings.simplefilter(action='ignore', category=FutureWarning)

sg.theme('DarkAmber') # Keep things interesting for your users
sg.SetOptions(font=('微软雅黑Light', 10))

default_port_droplist=['--']
default_baudrate_droplist=['9600','115200']
default_bytesize_droplist=['7','8','9']
default_parity_droplist=['奇','偶','无']
default_stopbits_droplist=['0','1']


layout = [[sg.Text('-----------------------test------------------------')],
	#载入配置文件
	[sg.Text('载入配置文件:')],[sg.InputText(key='-OPEN_FILE-')],
	[sg.FileBrowse('浏览',target='-OPEN_FILE-',size=(8, 1)),sg.Button('确定',size=(8, 1))],
    [sg.Text('-----------------------------------------------------')],
    [sg.Button('扫描端口',size=(8,1)),sg.Button('恢复默认',size=(8,1))],
    [sg.Drop(default_port_droplist, default_value='--',size=(8,6),key='-drop_port-',readonly=True),sg.Text('端口号')],
	[sg.Drop(default_baudrate_droplist, default_value='9600',size=(8,6),key='-drop_baudrate-',readonly=True),sg.Text('波特率')],
	[sg.Drop(default_bytesize_droplist, default_value='8',size=(8,6),key='-drop_bytesize-',readonly=True),sg.Text('数据位')],
    [sg.Drop(default_parity_droplist, default_value='偶',size=(8,6),key='-drop_parity-',readonly=True),sg.Text('校验位')],
    [sg.Drop(default_stopbits_droplist, default_value='1',size=(8,6),key='-drop_stopbits-',readonly=True),sg.Text('停止位')],
    [sg.Button('打开端口',size=(8,1)),sg.Button('关闭端口',size=(8,1))],
	#退出
	[sg.Exit()]]
window = sg.Window('window title', layout)

#更新UI内容
drop_list_port = window['-drop_port-']
drop_list_baudrate = window['-drop_baudrate-']
drop_list_bytesize = window['-drop_bytesize-']
drop_list_parity = window['-drop_parity-']
drop_list_stopbits = window['-drop_stopbits-']

sg.Print('-------------log output-------------', do_not_reroute_stdout=False)

#读取json文件
def read_json_file(file_path):
    with open(file_path, 'r',encoding='utf-8') as file:
        data = json.load(file)
        return data

def main():
    global default_port_droplist
    global flg_read
    global ser

    flg_read = 0
    ports = list(serial.tools.list_ports.comports())
    if len(ports) != 0:
        print('自动搜索到以下端口')
        for port in ports:
            print(f"设备名: {port.device}, 描述: {port.description}")#设备名: COM4, 描述: USB Serial Port (COM4) 
    else:
         print(f"未找到端口")

    while True:
        event, values = window.read()
        
        if event == sg.WIN_CLOSED or event == 'Exit':
            if event == 'Exit':
                print('您点击了Exit')
            break
        
        if event == '扫描端口':
            print('您点击了扫描端口')
            ports = list(serial.tools.list_ports.comports())
            if len(ports) != 0:
                default_port_droplist=[]
                for port in ports:
                    print(f"发现设备! 设备名: {port.device}, 描述: {port.description}") #设备名: COM4, 描述: USB Serial Port (COM4) 
                    default_port_droplist.append(port.device)
                    print(f"default_port_droplist:{default_port_droplist}")
                drop_list_port.update(values = default_port_droplist)
                drop_list_port.update(value  = default_port_droplist[0])
            else:
                print(f"未找到端口")

        if event == '恢复默认':
            print('您点击了恢复默认')
            if len(default_port_droplist)!= 0:
                drop_list_port.update(value=default_port_droplist[0])
            else:
                drop_list_port.update(value='--')
            drop_list_baudrate.update(value='9600')
            drop_list_bytesize.update(value='8')
            drop_list_parity.update(value='偶')
            drop_list_stopbits.update(value='1')

        if event == '确定':
            #打印选择的json文件内容
            print(read_json_file(values['-OPEN_FILE-']))

        if event == '打开端口':
            print('您点击了打开端口')
            if flg_read == 0:
                if len(default_port_droplist) and (default_port_droplist[0]!='--'):
                    ser = serial.Serial(
                        port = values['-drop_port-'],        # 串口号(需要选择)
                        baudrate=values['-drop_baudrate-'],  # 波特率(需要选择)
                        bytesize=serial.EIGHTBITS,           # 数据位:8 位
                        parity=serial.PARITY_EVEN,           # 校验位:偶校验
                        stopbits=serial.STOPBITS_ONE,        # 停止位:1 位
                        timeout=0.5                          # 读取超时时间(秒)
                    )
                    print(ser)
                    if ser.is_open:
                        flg_read = 1
                        print(f"串口 {ser.port} 已成功打开")
                    else:
                        flg_read = 0
                        print(f"无法打开串口 {ser.port}")
                else:
                    flg_read = 0
                    print('请先扫描端口')
            else:
                print('请先关闭串口')

        if event == '关闭端口':
            print('您点击了关闭端口')
            if flg_read == 1:
                if ser.is_open:
                    ser.close()
                    flg_read = 0
                    print(f"串口{ser.port}已成功关闭")
                else:
                    print("串口未打开,不需要关闭")
            else:
                 print("串口未打开,不需要关闭")

if __name__ == '__main__':
    main()
相关推荐
3824278272 小时前
python:输出JSON
前端·python·json
BullSmall3 小时前
普罗米修斯 的学习路径及建议
学习·prometheus
happyjoey2173 小时前
28天立创实力派开发板学习记录part1——DAY1-DAY8
学习
也许是_3 小时前
大模型应用技术之 详解 MCP 原理
人工智能·python
沙漠豪3 小时前
提取PDF发票信息的Python脚本
开发语言·python·pdf
非凡ghost4 小时前
CoolUtils PDF Combine(PDF合并工具)
windows·学习·pdf·软件需求
阿W呀4 小时前
【光的偏振与光功率 / 能量测量学习笔记】
学习
F_D_Z5 小时前
【Python】家庭用电数据的时序分析
python·数据分析·时序分析·序列分解