python可以利用serial模块来和串口设备进行485或者232通讯。

当然,网上这类串口调试助手的小程序有很多,不过这些程序要么是要收费,只能试用30天,要么是不好用。

况且,别人写的程序,你只能使用,无法取出其中的数据来进行处理,所以,如果可以自己写一个程序,既方便使用,又可以随时随地使用其中的数据。

软件:python3.10
pycharm2021
硬件:window10电脑
串口485设备(国产流量计)
串口转usb线(电脑不带串口,只能转接)

准备好了后,就可以开始写程序了。

串口通讯程序首先要对串口进行设置,如波特率、数据位、停止位、校验位等。可以称之为初始化:

初始化:

    def serial_init(self):   #初始化self.port = self.port_set.currentText()self.bps = int(self.baud_set.currentText())self.timeout = float(self.timeout_set.text())try:self.ser = serial.Serial(port=self.port,baudrate=self.bps,bytesize=8,parity='N',stopbits=1)print(self.ser)if self.ser.is_open:print('串口正常')except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)print('异常:', e)

初始化完成后,需要将串口打开,只有串口成功打开,才可以进行后面的数据传输。python中的serial模块,提供serial.isopen来进行检查。当然,此处需要注意的是,在串口serial实例化的时候,实际上已经同时打开串口了。所以,如果在初始化程序里建立了实例化:

 self.ser = serial.Serial(port=self.port,baudrate=self.bps,bytesize=8,parity='N',stopbits=1)

那么也可以不用在重复打开串口了。

串口打开:

 def open_serial(self):   #打开串口try:self.ser.open()except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)print('异常:', e)

串口关闭:

 def close_serial(self):  #关闭串口try:self.ser.close()except Exception as e:QMessageBox.warning(self,'tips!',str(e),QMessageBox.Ok|QMessageBox.Cancel,QMessageBox.Ok)print('异常:', e)

调试完成后,最好关闭串口,有始有终。

在完成上面的初始化和打开步骤后,就可以进行数据的读、写了,本例中使用了与流量计进行通讯,读取流量计实时流量。该流量计读、写数据时有专门的格式:

所以,从电脑端发送指令时,需要按照流量计的格式发送,才能得到正确的反馈。485是半双工传输,即同一时间只能进行读或者写,读、写不能同时进行。

本例中,读取流量指令格式为:
01 03 00 10 00 02 C5 CE
实际操作中,我将流量计设备地址修改为2,即
02 03 00 10 00 02 C5 CE

发送数据:

    def send_data(self):ct = datetime.datetime.now()                       #获取当前系统时间ct_str = ct.strftime("%Y-%m-%d %H:%M:%S")          #格式化当前系统时间(字符形式)try:self.senddata_s=self.le_senddata.text()self.senddata=bytes.fromhex(self.senddata_s)  #字符转成字节self.ser.write(self.senddata)#self.senddata_str=self.senddata.hex()self.senddata_str_fg=self.str_fenge(self.senddata_s)#self.le_senddata.setText(self.senddata.hex())self.le_recdata.append('\n' + '[' + ct_str+ ']' + ' ' + self.senddata_str_fg + '\n')#print(self.senddata)time.sleep(0.1)self.read_data_size()except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)

读取数据:

    def read_data_size(self):ct=datetime.datetime.now()ct_str=ct.strftime("%Y-%m-%d %H:%M:%S")try:#self.size=10self.read_data=self.ser.read_all()#print(self.read_data)self.read_data_str=self.read_data.hex()   #字节转成16进制字符显示#re.findall(r'.{3}',self.read_data_str)self.read_data_str_fg=self.str_fenge(self.read_data_str)#print(self.read_data_str)self.le_recdata.append('\n'+'['+ct_str+']'+' '+self.read_data_str_fg+'\n')except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)#return self.read_data

serial的读取数据时,有几种方式,read()、read_all()、readline(),read()就是按照字节数size大小读取缓存区字节,read_all()即读取所有数据,readline()读取缓存区最新一行数据。

完整程序:

from numpy.lib.function_base import place
import serial
import serial.tools.list_ports
import sys
import re
import os
import time
import datetime
import threading
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *class Serialwindow(QWidget):def __init__(self) -> None:super().__init__()self.initUI()def initUI(self):#self.stylefile = 'E:\\100proworld2021\opencvtestpro01\爬虫程序\爬虫-style.qss'#self.qssstyle = CommonHelper.readQSS(self.stylefile)self.port = ''self.bps = 0self.timeout = 0.0self.senddata=bytes()self.read_data=''self.btn_plist=QPushButton('获取可用串口',self)self.btn_plist.setGeometry(20,20,60,20)self.btn_plist.clicked.connect(self.get_serial_info)self.btn_plist.adjustSize()self.btn_ser_init=QPushButton('初始化',self)self.btn_ser_init.setGeometry(20,50,60,20)self.btn_ser_init.clicked.connect(self.serial_init)self.btn_ser_init.adjustSize()self.btn_open=QPushButton('打开串口',self)self.btn_open.setGeometry(20,80,60,20)self.btn_open.clicked.connect(self.open_serial)self.btn_open.adjustSize()self.btn_close=QPushButton('关闭串口',self)self.btn_close.setGeometry(20,110,60,20)self.btn_close.clicked.connect(self.close_serial)self.btn_close.adjustSize()self.btn_read_data=QPushButton('读取数据',self)self.btn_read_data.setGeometry(20,140,60,20)self.btn_read_data.clicked.connect(self.read_data_size)self.btn_read_data.adjustSize()self.btn_write_data=QPushButton('发送数据',self)self.btn_write_data.setGeometry(40,460,60,20)self.btn_write_data.clicked.connect(self.send_data)self.btn_write_data.adjustSize()#Qcomboboxself.port_set=QComboBox(self)self.port_set.setGeometry(500,20,100,20)self.port_set.addItems(['COM1'])#self.port_set.activated.connect(self.Qcombo)self.lbl_port_set=QLabel(self)self.lbl_port_set.setGeometry(420,20,60,20)self.lbl_port_set.setText('串口号:')self.baud_set=QComboBox(self)self.baud_set.setGeometry(500,50,100,20)self.baud_set.addItems(['9600','19200','38400','115200'])self.lbl_baud_set=QLabel(self)self.lbl_baud_set.setGeometry(420,50,60,20)self.lbl_baud_set.setText('波特率:')self.stopbit_set=QComboBox(self)self.stopbit_set.setGeometry(500,80,100,20)self.stopbit_set.addItems(['0','1'])self.lbl_stopbit_set = QLabel(self)self.lbl_stopbit_set.setGeometry(420, 80, 60, 20)self.lbl_stopbit_set.setText('停止位:')self.parity_set=QComboBox(self)self.parity_set.setGeometry(500,110,100,20)self.parity_set.addItems(['无','奇校验','偶校验'])self.lbl_parity_set = QLabel(self)self.lbl_parity_set.setGeometry(420, 110, 60, 20)self.lbl_parity_set.setText('校验位:')self.databit_set=QComboBox(self)self.databit_set.setGeometry(500,140,100,20)self.databit_set.addItems(['8','7'])self.lbl_databit_set=QLabel(self)self.lbl_databit_set.setGeometry(420,140,60,20)self.lbl_databit_set.setText('数据位:')self.timeout_set=QLineEdit(self)self.timeout_set.setGeometry(500,170,100,20)self.timeout_set.setText('1000')self.lbl_timeout_set=QLabel(self)self.lbl_timeout_set.setGeometry(420,170,60,20)self.lbl_timeout_set.setText('超时设置:')self.lbl_timeout_set_2=QLabel(self)self.lbl_timeout_set_2.setGeometry(610,170,60,20)self.lbl_timeout_set_2.setText('ms')#self.le_senddata=QLineEdit(self)self.le_senddata.setGeometry(120,460,300,20)self.le_senddata.setText('010300100002C5CE')self.le_recdata=QTextEdit(self)self.le_recdata.setGeometry(120,220,600,200)self.setGeometry(100,100,800,600)self.setWindowTitle('简易串口调试助手-菌尘')# self.setStyleSheet(self.qssstyle)self.show()def Qcombo(self):print(self.port_set.currentText())print(self.baud_set.currentText())print(self.stopbit_set.currentText())print(self.parity_set.currentText())print(self.databit_set.currentText())print(self.timeout_set.text())def get_serial_info(self):   #获取可用串口列表#打印可用串口列表#self.need_serial = ''self.plist = list(serial.tools.list_ports.comports())if len(self.plist) <= 0:print('未找到串口')qm = QMessageBox.warning(self, '提示窗口', '未找到串口!请检查接线和电脑接口。', QMessageBox.Ok|QMessageBox.Cancel,QMessageBox.Ok)if qm == QMessageBox.Yes:print('Yes')else:print('No')else:for i in list(self.plist):self.port_set.addItem(i.name)#return self.need_serial#print(self.plist)def serial_init(self):   #初始化self.port = self.port_set.currentText()self.bps = int(self.baud_set.currentText())self.timeout = float(self.timeout_set.text())try:self.ser = serial.Serial(port=self.port,baudrate=self.bps,bytesize=8,parity='N',stopbits=1)print(self.ser)if self.ser.is_open:print('串口正常')except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)print('异常:', e)def open_serial(self):   #打开串口try:self.ser.open()except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)print('异常:', e)def close_serial(self):  #关闭串口try:self.ser.close()except Exception as e:QMessageBox.warning(self,'tips!',str(e),QMessageBox.Ok|QMessageBox.Cancel,QMessageBox.Ok)print('异常:', e)def read_data_size(self):ct=datetime.datetime.now()ct_str=ct.strftime("%Y-%m-%d %H:%M:%S")try:#self.size=10self.read_data=self.ser.read_all()#print(self.read_data)self.read_data_str=self.read_data.hex()   #字节转成16进制字符显示#re.findall(r'.{3}',self.read_data_str)self.read_data_str_fg=self.str_fenge(self.read_data_str)#print(self.read_data_str)self.le_recdata.append('\n'+'['+ct_str+']'+' '+self.read_data_str_fg+'\n')except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)#return self.read_datadef read_data_line(self):self.read_data=self.ser.readline()return self.read_datadef send_data(self):ct = datetime.datetime.now()                       #获取当前系统时间ct_str = ct.strftime("%Y-%m-%d %H:%M:%S")          #格式化当前系统时间(字符形式)try:self.senddata_s=self.le_senddata.text()self.senddata=bytes.fromhex(self.senddata_s)  #字符转成字节self.ser.write(self.senddata)#self.senddata_str=self.senddata.hex()self.senddata_str_fg=self.str_fenge(self.senddata_s)#self.le_senddata.setText(self.senddata.hex())self.le_recdata.append('\n' + '[' + ct_str+ ']' + ' ' + self.senddata_str_fg + '\n')#print(self.senddata)time.sleep(0.1)self.read_data_size()except Exception as e:QMessageBox.warning(self, 'tips!', str(e), QMessageBox.Ok | QMessageBox.Cancel, QMessageBox.Ok)def read_data_alway(self, way):print('开始接受数据:')while True:try:if self.ser.inWaiting:if(way == 0 ):for i in range(self.ser.inWaiting):print('接收ascII数据:'+str(self.read_data_size(1)))data1 = self.read_data_size(1).hex()data2 = int(data1, 16)print('接收到16进制数据:'+data1+'接收到10进制数据:'+str(data2))if(way == 1 ):data = self.ser.read_all()except Exception as e:print('异常:', e)def str_fenge(self,A):'''对字符串进行按长度分割,并在中间加入其他字符,如空格、短横等'''b = re.findall(r'.{2}',A)c = ' '.join(b)#print(c)return cif __name__ == '__main__':app = QApplication(sys.argv)ex = Serialwindow()sys.exit(app.exec_())

上面的程序经过测试,可以与流量计正常通讯。

使用python+Pyqt5来写一个简易串口调试助手相关推荐

  1. VB.net写一个简易串口RS485调试助手

    最近在调试带rs485串口通讯的设备,项目上主要是用PLC和串口通讯,因为PLC有集成好的串口块,使用起来比较容易,为了方便测试,就想着用上位机写一个简易的串口通讯程序,用于调试. 在网上查找了一些资 ...

  2. Python: pyqt5 自己写一个窗口文本编辑器

    PyQt5是Digia的一套Qt5应用框架与python的结合,同时支持2.x和3.x.Qt库由Riverbank Computing开发,是最强大的GUI库之一. >>> 今天,我 ...

  3. 用python 10min手写一个简易的实时内存监控系统

    http://www.cnblogs.com/shengxinjing/p/python.html 转载于:https://www.cnblogs.com/figofifa/p/5604215.htm ...

  4. python 画图 内存-用python 10min手写一个简易的实时内存监控系统

    hello world $(function () { // 使用当前时区,否则东八区会差八个小时 Highcharts.setOptions({ global: { useUTC: false } ...

  5. QT制作简易串口调试助手

    文章目录 QT制作简易串口调试助手 0 简介 1 界面制作 2 逻辑实现 2.1 添加与可用串口信息有关的类的准备 2.2 读取可用串口并添加到控件 2.3 打开串口 2.4 关闭串口 2.5 串口收 ...

  6. 串口调试助手,有需要的拿去用

    近半年都学搞单片机开发,STM8,STM32的单片机.以前都是写PC端的程序,一个偶然的机会转到单片机项目上,找了些书看了几天差不多就可以功手做了.任何事情只要你下决心去做,就一定可以做成,只是花的时 ...

  7. Python 利用PyQt5写一个简易的串口助手

    学习单片机,STM32好长时间了,也做了一些项目,一直想利用上位机实现电脑与单片机之间的传输数据,利用串口助手是最直接的通信方式,但串口助手不适合做上位机,如果会写串口助手的软件,基本能写自己写一个上 ...

  8. python写音乐播放器_AJ Kipper:用Python写一个简易的MP3播放器

    用Python写一个简易的MP3播放器 前言 最近在学习Web.py框架的时候,了解了基本的Python连接数据库(MySQL)的方法.学完后,总想用它来干点啥,于是,就想能不能写一个MP3播放器.一 ...

  9. python测试抽奖脚本_使用 Python 写一个简易的抽奖程序

    不知道有多少人是被这个头图骗进来的:) 事情的起因是这样的,上周有同学问小编,看着小编的示例代码敲代码,感觉自己也会写了,如果不看的话,七七八八可能也写的出来,但是一旦自己独立写一段程序,感觉到无从下 ...

  10. 【Linux操作系统】--攥写一个简易的shell工具

    目录 做一个简易的shell 第一步:打印提示符,在同一行打印出提示符 第二步:获取标准输入,获取命令字符串 第三步:将字符串分割,解析字符串 第四步:替换进程,执行第三方命令 3.5.执行第三方命令 ...

最新文章

  1. C#进行Visio二次开发之判断图纸是否有设备
  2. 如何用体验赢取用户信任?让 Waymo 来教教你
  3. go 实现斐波那契数列
  4. C语言实例第3期:在控制台打印出著名的杨辉三角
  5. MySQL sql99语法—等值连接
  6. MySQL 高级 - 触发器 - 查看及删除
  7. ACM经验分享[转]
  8. ubuntu14.04部署kickstart
  9. Hadoop 参数配置优化
  10. EMNLP2020文档级关系抽取模型GLRE 论文Global-to-Local Neural Networks for Document-Level Relation Extraction
  11. 谈谈 MVX 中的 Model
  12. 新兴职业背后的认知逻辑
  13. linux 内存告警门限,H3C LA系列无线网关 配置指导(V7)-R0304-6W100_基础配置指导_设备管理配置-新华三集团-H3C...
  14. 腾讯云服务器备案完整流程 40天备案的血与泪
  15. XML的优势及应用领域
  16. etcd入门系列三:身份验证访问控制
  17. 将要加入linux-2.6.29内核的cred
  18. html5实现刮刮卡效果
  19. 《工具箱-服务器相关》Moba连接FTP服务器,EElFTPSUnacceptedReplyError(error code is 550)已解决
  20. XL7005A xlsemi 降压型直流电源变换器芯片(高电压型)

热门文章

  1. CPC软件使用 专利申请说明书附图插入(简单粗暴)CPC软件安装
  2. 论文关于mysql数据库文献_数据库论文参考文献
  3. 图解《金字塔原理》,7步掌握其精华!
  4. 关于ucgui3.98(显示部分)移植
  5. AForge.net库类下载方式
  6. hcna华为认证网络工程师
  7. 拦截器和过滤器之间的区别
  8. mtk无线网卡 linux,在树莓派上使用基于MT7601的无线网卡(如360/百度/腾讯Wifi)
  9. Markdown用法——带圆圈的数字编号
  10. 【总结】6种机器学习中的优化算法:SGD,牛顿法,SGD-M,AdaGrad,AdaDelta,Adam