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()
相关推荐
ScilogyHunter2 分钟前
SCons:Python驱动的智能构建系统
python·构建系统·scons
luoluoal9 分钟前
基于python的基于深度学习的车俩特征分析系(源码+文档)
python·mysql·django·毕业设计·源码
航Hang*13 分钟前
Photoshop 图形与图像处理技术——第9章:实践训练1——绘制禁烟标志和奥运五环
图像处理·笔记·学习·ui·photoshop
轻竹办公PPT17 分钟前
2026 年 AI 办公趋势:AI 生成 PPT 工具谁在领先
人工智能·python
saoys28 分钟前
Opencv 学习笔记:图像金字塔实现上采样(pyrUp)与降采样(pyrDown)
笔记·opencv·学习
大志若愚YYZ35 分钟前
ROS2学习 C++中的this指针
c++·学习·算法
Kingairy39 分钟前
Python面试高频题
java·python·面试
黎雁·泠崖39 分钟前
Java数组入门:定义+静态/动态初始化全解析(隐式转换+案例+避坑指南)
java·开发语言·python
梅羽落41 分钟前
fastapi速成2
python·github·fastapi
hhcccchh1 小时前
学习vue第十三天 Vue3组件深入指南:组件的艺术与科学
javascript·vue.js·学习