Python:简易的串口收发程序

2023-11-18

Python:简易的串口收发程序

更新历史
20201204:

  1. 首次发布

最近需要搞一个基于Python的串口程序,要求:

  • 能够将字符串形式的十六进制数(例如:‘12 34 CD EF’)转化成对应的二进制数据后发送给一个串口设备
  • 能够从串口设备接收二进制数据,转化成字符串形式的十六进制数后进行保存。

网上找了找,发现有现成可供参考的代码。于是拿来做了点修改,变成了我所需要的代码。感谢提供代码的网友,同时,我也将自己的代码贡献出来,以供参考:

#######################
#程序功能:串口通信的简易程序,基于Python3开发。
#by:永恒的止水(CSDN),https://blog.csdn.net/qq_38791897/article/details/110670718
#######################


import serial 
import serial.tools.list_ports
from binascii import b2a_hex, a2b_hex
import threading



#全局变量
GLOBAL_DATA_LIST = []
GLOBAL_NOTEND = True # 是否读取结束




#查找可用的串口设备
#输入:无
#输出:
#   port_list:列表,每个元素都是一个字符串,字符串为串口的名称
def get_serial_port_list():
    port_list = []

    port_list_temp = list(serial.tools.list_ports.comports())
    if len(port_list_temp) == 0:
        print("[Warning] 无可用串口!")
    else:
        print("[Successful] 存在可用的串口,如下:")
        for my_port in port_list_temp:
            print(my_port)
            port_list.append(str(my_port))

    return port_list







#打开一个串口,并为其创建一个读数据的线程
#输入:
#   portx:串口名称,例如,"COM5"
#   bps:波特率。标准值有:50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
#                        9600, 19200, 38400, 57600, 115200, 230400, 460800, 500000,
#                        576000, 921600, 1000000, 1152000, 1500000, 2000000, 2500000,
#                        3000000, 3500000, 4000000
#   timeout:超时设置,None:永远等待操作;0:立即返回请求结果;其他:等待超时时间(单位为秒)
#   stopbits:停止位的长度,标准值有:1, 1.5, 2。
#   bytesize:有效载荷数据的位宽,标准值有:5, 6, 7, 8
#   parity:校验方式。可选的有:'None', 'Even', 'Odd', 'Mark', 'Space'
#输出:
#   ser:串口对象
#   successful:若为True,表示串口打开成功,ser有效;若为False,表示串口打开失败,ser无效。
def open_serial_port(portx, bps, timeout, stopbits, bytesize, parity):
    successful = False

    if parity == 'Even':
        my_parity = 'E'
    elif parity == 'Odd':
        my_parity = 'O'
    elif parity == 'Mark':
        my_parity = 'M'
    elif parity == 'Space':
        my_parity = 'S'
    else: #default: 'None'
        my_parity = 'N'

    try:
        # 打开串口,并得到串口对象
        ser = serial.Serial(portx, bps, timeout=timeout, stopbits=stopbits, bytesize=bytesize, parity=my_parity)
 
        # 判断是否成功打开
        if(ser.is_open):
            successful = True
            th = threading.Thread(target=read_from_serial_port, args=(ser,)) # 创建一个子线程去等待读数据
            th.start()
    except Exception as e:
        print("open_serial_port error!", e)
 
    return ser, successful



 
#从串口读数据的线程的本体,将读到的数据添加到一个global列表中
#输入:
#   ser:串口对象
#输出:无
def read_from_serial_port(ser):
    global GLOBAL_DATA_LIST, GLOBAL_NOTEND
 
    # 循环接收数据(此为死循环,可用线程实现)
    while GLOBAL_NOTEND:
        if ser.in_waiting:
            data = b2a_hex(ser.read(ser.in_waiting)).decode('utf-8') #16进制的字符串,例如:'4141','FF'
            print("\n[received] " + data)
            GLOBAL_DATA_LIST.append(data)



#关闭串口
#输入:
#   ser:串口对象
#输出:无
def close_serial_port(ser):
    global GLOBAL_NOTEND
    GLOBAL_NOTEND = False
    ser.close()
    print('串口已关闭!')




 
#向串口写数据
#输入:
#   ser:串口对象
#   text:16进制的字符串,必须要是偶数个字符,不能含有空格。例如:'4141','FF','12345678ABCDEF'
#输出:
#   byte_num_sent:向串口写入的字节数

def write_to_serial_port(ser, text):
    byte_num_sent = ser.write(a2b_hex(text))
    print("[Successful] 向串口写入了" + str(byte_num_sent) + '个字节。')
    return byte_num_sent
 




 
if __name__ == "__main__":
    #获取可用的串口的列表
    port_list = get_serial_port_list()

    #打开列表中的某个串口,进行数据收发
    if port_list:
        #选择串口
        while True:
            portx_in_port_list = False
            portx = input("请输入要打开的串口的名称(例如:COM5):")
            for my_port in port_list:
                if portx == my_port[:4]:
                    portx_in_port_list = True
                    break
            if portx_in_port_list:
                break
        #设置其余参数
        bps = 9600
        timeout = 1
        stopbits = 1
        bytesize = 8
        parity = 'Odd'

        #打开串口
        ser, successful = open_serial_port(portx, bps, timeout, stopbits, bytesize, parity)

        #数据收发(数据接收是通过打开串口时启动的线程完成的,因而,此处的代码只需要进行数据的发送就可以了)
        if successful == True:
            while True:
                text = input("请输入'quit'或待发送的16进制字符串:\n>>")
                if text == "quit":
                    close_serial_port(ser)
                    break
                else:
                    #去除text中的空格,例如,将'12 12  3456'变成'12123456'
                    while ' ' in text:
                        text = text.replace(' ', '')
                    #将去除了空格的字符串发往串口
                    write_to_serial_port(ser, text)

            #程序结束,输出串口在程序运行过程中接收到的所有数据
            print('串口接收到的数据:')
            print(GLOBAL_DATA_LIST)
            
 
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python:简易的串口收发程序 的相关文章

  • 与区域指示符字符类匹配的 python 正则表达式

    我在 Mac 上使用 python 2 7 10 表情符号中的标志由一对表示区域指示符号 https en wikipedia org wiki Regional Indicator Symbol 我想编写一个 python 正则表达式来在
  • 如何用python脚本控制TP LINK路由器

    我想知道是否有一个工具可以让我连接到路由器并关闭它 然后从 python 脚本重新启动它 我知道如果我写 import os os system ssh l root 192 168 2 1 我可以通过 python 连接到我的路由器 但是
  • Python 中的舍入浮点问题

    我遇到了 np round np around 的问题 它没有正确舍入 我无法包含代码 因为当我手动设置值 而不是使用我的数据 时 返回有效 但这是输出 In 177 a Out 177 0 0099999998 In 178 np rou
  • 处理 Python 行为测试框架中的异常

    我一直在考虑从鼻子转向行为测试 摩卡 柴等已经宠坏了我 到目前为止一切都很好 但除了以下之外 我似乎无法找出任何测试异常的方法 then It throws a KeyError exception def step impl contex
  • Pandas 日期时间格式

    是否可以用零后缀表示 pd to datetime 似乎零被删除了 print pd to datetime 2000 07 26 14 21 00 00000 format Y m d H M S f 结果是 2000 07 26 14
  • 使用 kivy textinput 的 'input_type' 属性的问题

    您好 我在使用 kivy 的文本输入小部件的 input type 属性时遇到问题 问题是我制作了两个自定义文本输入 其中一个称为 StrText 其中设置了 input type text 然后是第二个文本输入 名为 NumText 其
  • 立体太阳图 matplotlib 极坐标图 python

    我正在尝试创建一个与以下类似的简单的立体太阳路径图 http wiki naturalfrequent com wiki Sun Path Diagram http wiki naturalfrequency com wiki Sun Pa
  • 如何使用 Pandas、Numpy 加速 Python 中的嵌套 for 循环逻辑?

    我想检查一下表的字段是否TestProject包含了Client端传入的参数 嵌套for循环很丑陋 有什么高效简单的方法来实现吗 非常感谢您的任何建议 def test parameter a list parameter b list g
  • Pandas Merge (pd.merge) 如何设置索引和连接

    我有两个 pandas 数据框 dfLeft 和 dfRight 以日期作为索引 dfLeft cusip factorL date 2012 01 03 XXXX 4 5 2012 01 03 YYYY 6 2 2012 01 04 XX
  • 为什么 PyYAML 花费这么多时间来解析 YAML 文件?

    我正在解析一个大约 6500 行的 YAML 文件 格式如下 foo1 bar1 blah name john age 123 metadata whatever1 whatever whatever2 whatever stuff thi
  • 在Python中检索PostgreSQL数据库的新记录

    在数据库表中 第二列和第三列有数字 将会不断添加新行 每次 每当数据库表中添加新行时 python 都需要不断检查它们 当 sql 表中收到的新行数低于 105 时 python 应打印一条通知消息 警告 数量已降至 105 以下 另一方面
  • 加快网络抓取速度

    我正在使用一个非常简单的网络抓取工具抓取 23770 个网页scrapy 我对 scrapy 甚至 python 都很陌生 但设法编写了一个可以完成这项工作的蜘蛛 然而 它确实很慢 爬行 23770 个页面大约需要 28 小时 我看过scr
  • Jupyter Notebook 找不到 Python 模块

    不知道发生了什么 但每当我使用 ipython 氢 原子 或 jupyter 笔记本时都找不到任何已安装的模块 我知道我安装了 pandas 但笔记本说找不到 我应该补充一点 当我正常运行脚本时 python script py 它确实导入
  • 如何断言 Unittest 上的可迭代对象不为空?

    向服务提交查询后 我会收到一本字典或一个列表 我想确保它不为空 我使用Python 2 7 我很惊讶没有任何assertEmpty方法为unittest TestCase类实例 现有的替代方案看起来并不正确 self assertTrue
  • 如何在 Windows 命令行中使用参数运行 Python 脚本

    这是我的蟒蛇hello py script def hello a b print hello and that s your sum sum a b print sum import sys if name main hello sys
  • 如何在 pygtk 中创建新信号

    我创建了一个 python 对象 但我想在它上面发送信号 我让它继承自 gobject GObject 但似乎没有任何方法可以在我的对象上创建新信号 您还可以在类定义中定义信号 class MyGObjectClass gobject GO
  • python import inside函数隐藏现有变量

    我在我正在处理的多子模块项目中遇到了一个奇怪的 UnboundLocalError 分配之前引用的局部变量 问题 并将其精简为这个片段 使用标准库中的日志记录模块 import logging def foo logging info fo
  • 在 JavaScript 函数的 Django 模板中转义字符串参数

    我有一个 JavaScript 函数 它返回一组对象 return Func id name 例如 我在传递包含引号的字符串时遇到问题 Dr Seuss ABC BOOk 是无效语法 I tried name safe 但无济于事 有什么解
  • 使用 z = f(x, y) 形式的 B 样条方法来拟合 z = f(x)

    作为一个潜在的解决方案这个问题 https stackoverflow com questions 76476327 how to avoid creating many binary switching variables in gekk
  • Kivy - 单击按钮时编辑标签

    我希望 Button1 在单击时编辑标签 etykietka 但我不知道如何操作 你有什么想法吗 class Zastepstwa App def build self lista WebOps getList layout BoxLayo

随机推荐

  • JSX/TSX的知识介绍

    JSX TSX 基本介绍 JSX和TSX是一种基于JavaScript的语法扩展 用于在React和Vue js等框架中编写可复用的UI组件和控制逻辑 JSX TSX可以帮助开发者更加直观和高效地编写UI组件和交互逻辑 同时也可以提高代码的
  • 深度优先搜索之素数环

    1 问题描述 输入正整数n 对1 n进行排列 使得相邻两个数之和均为素数 输出时从整数1开始 逆时针排列 同一个环应恰好输出一次 n lt 16 如输入 6 输出 1 4 3 2 5 6 1 6 5 2 3 4 2 我们这里使用dfs来进行
  • [人工智能-深度学习-31]:卷积神经网络CNN - 常见卷积神经网络综合比较大全

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 120835303 目录 第1章 人工智
  • Linux文件权限

    Linux用户分为 拥有者 组群 Group 其他 other linux中的 文件属性过分四段 如 rwzrwz 第一段 是指文件类型 表示这是个普通文件 文件类型部分 为 表示文件 d为 表示文件夹 l为 表示链接文件 可以理解为 wi
  • 百度安全联盟砸场360的中国互联网安全大会说明啥(现场图)

    360承办的 具有官方背景的2013中国互联网安全大会22日召开 然而突发了 百度安全联盟大闹中国互联网安全大会 事件 据说各种闹场方式如百度安全联盟扩音喇叭 安全套等 传闻中的 百度安全联盟大闹中国互联网安全大会 到底真相如何 确实是安全
  • 【python爬虫】爬取豆瓣电影TOP250数据

    这次以豆瓣电影TOP250网为例编写一个爬虫程序 并将爬取到的数据 排名 电影名和电影海报网址 存入MySQL数据库中 下面是完整代码 Ps 在执行程序前 先在MySQL中创建一个数据库 pachong import pymysql imp
  • 需求:vue定时器随机显示冒泡

    html代码 div class tips div class item item1 div class txt item content div div div js代码 在data中定义indexNum生成随机数 mounted中开启定
  • 初学者如何学好Java,过来人的经验之谈

    多看书 多下载一些java相关的资料 多看多打代码 然后思考总结 书读百遍 其义自现 如果找不到合适的资料 可以上北网论坛找下适合自己的免费视频学习资料 都是一些大神买来共享的本来收费的内容 比如 由简入深绝版Java系列课程 t cn 8
  • 网站分布式技术有哪些?

    分布式软件系统 Distributed Software Systems 是支持 分布式处理的软件系统 是在由 通信网络互联的多处理机体系结构上执行任务的系统 它包括分布式操作系统 分布式程序设计语言及其编译 解释 系统 分布式文件系统和
  • 不要再循环里抛出异常

    今天遇到一个bug 是因为循环中抛出了异常 导致之后的代码都没有执行 所以哇 这种抛出有可能中断程序执行的 运行中异常 不要在循环中抛出 只记录异常就可以了 举个栗子 反面示例 try throw new Exception 我发生异常啦
  • 2019 SIGGRAPH paper

    20190704 Image Science 1 Hyperparameter Optimization in Black box Image Processing using Differentiable Proxies 基于可微代理的黑
  • Linux部署项目

    一 Linux介绍 背景 Java项目通常基于windows系统进行开发 服务器部署则是基于Linux 1 1 Linux系统概述 Linux是一套免费使用 自由传播的类unix操作系统 支持多用户 多任何 支持多线程和多CPU的操作系统
  • idea技巧之同时编辑多行代码

    如何同时编辑多行代码 eclipse好像没有这种功能 有一次看到老师用eclipse写代码 10多行 每一行添加一个单引号 一个一个添加 慢的想死 想起做前端项目使用的 webstone可以同时编辑多行代码 现在看到idea 功能如此强大
  • Window10屏幕亮度无法调节尝试解决方法

    换成win10后突然屏幕亮度调节不了 尝试几种方法 失败方法一 注册表修改 1 首先 请大家在桌面上按下Windows徽标键 R键 打开运行菜单窗口 在窗口中输入 regedit 关键字 按下回车键之后打开注册表编辑器 2 打开注册表编辑器
  • vue中使用高德地图,只加载出地图logo,地图没有加载出来

    在使用vue开发的过程中 需要使用到高德地图 但按照高德地图的官方文档配置后 只显示高德地图的logo 但是始终加载不到地图 如下图所示 解决办法 将全局引用的的mockjs注释掉就可以解决这个冲突问题
  • Elaticsearch安装越南语分词器

    1 目标 实现支持英 德 法 葡萄牙 西班牙 俄 印尼 泰 繁中 简中 日 韩 越南 意大利 阿拉伯 土耳其 乌克兰 荷兰 波兰 19种文字的分词器 2 自带的分词器 英 english 德 german 法 french 葡萄牙 port
  • 用spss进行主成分分析

    此次同样通过一道例题讲解如何运用spss进行对数据的主成分分析 下表是我国2005年第1 2季度各地区城镇居民家庭收支基本情况的统计数据 根据这些数据进行主成分分析 并依据分析结果对地区城镇居民家庭收支情况进行排序和分类 地区 平均每户人口
  • 买《Kotlin从小白到大牛》专题视频课程,送配套纸质图书

    经过一年多时间的呕心沥血 Kotlin立体化图书 Kotlin从小白到大牛 即将与大家见面了 所谓立体化图书包括 电子图书 视频 课件和服务等内容 Kotlin从小白到大牛 纸质图书已经上市 为了答谢广大学员对智捷课堂以及关老师的支持 现购
  • python x=[random.randint(0,100) for i in range(50)]什么意思?列表解析

    如有错误欢迎指正 在写python的时候遇到一个问题 其中一段代码是x random randint 0 100 for i in range 50 这个用法叫 列表解析 这句代码的功能是生成一个具有50个0 100之间的整数 具体可以看下
  • Python:简易的串口收发程序

    Python 简易的串口收发程序 更新历史 20201204 首次发布 最近需要搞一个基于Python的串口程序 要求 能够将字符串形式的十六进制数 例如 12 34 CD EF 转化成对应的二进制数据后发送给一个串口设备 能够从串口设备接