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()
相关推荐
苦逼IT运维7 分钟前
从 0 到 1 理解 Kubernetes:一次“破坏式”学习实践(一)
linux·学习·docker·容器·kubernetes
52Hz1188 分钟前
力扣230.二叉搜索树中第k小的元素、199.二叉树的右视图、114.二叉树展开为链表
python·算法·leetcode
喵手9 分钟前
Python爬虫实战:网页截图归档完全指南 - 构建生产级页面存证与历史回溯系统!
爬虫·python·爬虫实战·零基础python爬虫教学·网页截图归档·历史回溯·生产级方案
张3蜂26 分钟前
Python 四大 Web 框架对比解析:FastAPI、Django、Flask 与 Tornado
前端·python·fastapi
2601_9483745735 分钟前
商用电子秤怎么选
大数据·python
野犬寒鸦37 分钟前
从零起步学习并发编程 || 第五章:悲观锁与乐观锁的思想与实现及实战应用与问题
java·服务器·数据库·学习·语言模型
Volunteer Technology41 分钟前
Sentinel的限流算法
java·python·算法
阿蒙Amon1 小时前
TypeScript学习-第13章:实战与最佳实践
javascript·学习·typescript
七夜zippoe1 小时前
Python统计分析实战:从描述统计到假设检验的完整指南
开发语言·python·统计分析·置信区间·概率分布
2601_949146531 小时前
Python语音通知API示例代码汇总:基于Requests库的语音接口调用实战
开发语言·python