对python3 Serial 串口助手的接收读取数据方法详解


Posted in Python onJune 12, 2019

其实网上已经有许多python语言书写的串口,但大部分都是python2写的,没有找到一个合适的python编写的串口助手,只能自己来写一个串口助手,由于我只需要串口能够接收读取数据就可以了,故而这个串口助手只实现了数据的接收读取。

创建串口助手首先需要创建一个类,重构类的实现过程如下:

#coding=gb18030

import threading
import time
import serial

class ComThread:
 def __init__(self, Port='COM3'):
 #构造串口的属性
  self.l_serial = None
  self.alive = False
  self.waitEnd = None
  self.port = Port
  self.ID = None
  self.data = None
 #定义串口等待的函数
 def waiting(self):
  if not self.waitEnd is None:
   self.waitEnd.wait()

 def SetStopEvent(self):
  if not self.waitEnd is None:
   self.waitEnd.set()
  self.alive = False
  self.stop()
 #启动串口的函数
 def start(self):
  self.l_serial = serial.Serial()
  self.l_serial.port = self.port
  self.l_serial.baudrate = 115200
  #设置等待时间,若超出这停止等待
  self.l_serial.timeout = 2
  self.l_serial.open()
  #判断串口是否已经打开
  if self.l_serial.isOpen():
   self.waitEnd = threading.Event()
   self.alive = True
   self.thread_read = None
   self.thread_read = threading.Thread(target=self.FirstReader)
   self.thread_read.setDaemon(1)
   self.thread_read.start()
   return True
  else:
   return False

创建好类后,就要实现串口读取的功能,其读取数据的函数如下:

首先要创建一个字符串来存放接收到的数据:

data = ''
   data = data.encode('utf-8')#由于串口使用的是字节,故而要进行转码,否则串口会不识别

在创建好变量来接收数据后就要开始接收数据:

n = self.l_serial.inWaiting()#获取接收到的数据长度
   if n: 
     #读取数据并将数据存入data
     data = data + self.l_serial.read(n)
     #输出接收到的数据
     print('get data from serial port:', data)
     #显示data的类型,便于如果出错时检查错误
     print(type(data))

将数据接收完后,就要对接收到的数据进行处理,提取出有用信息,由于下位机使用的协议不一样,因此处理的方法也不一样,我使用的协议是**+ID+*Data+*,因此我的提取方法如下:

#获取还没接收到的数据长度
n = self.l_serial.inWaiting()
#判断是否已经将下位机传输过来的数据全部提取完毕,防止之前没有获取全部数据
if len(data)>0 and n==0:
 try:
  #将数据转换为字符型
  temp = data.decode('gb18030')
  #输出temp类型,看转码是否成功
  print(type(temp))
  #输出接收到的数据
  print(temp)
  将数据按换行分割并输出
  car,temp = str(temp).split("\n",1)
  print(car,temp)
 
  #将temp按':'分割,并获取第二个数据
  string = str(temp).strip().split(":")[1]
  #由于前面分割后的数据类型是列表,因此需要转换成字符串,而后按照'*'分割,得到的也就是我们需要的Id和data
  str_ID,str_data = str(string).split("*",1)
 
  print(str_ID)
  print(str_data)
  print(type(str_ID),type(str_data))
  #判断data最后一位是否是'*',若是则退出,若不是则输出异常
  if str_data[-1]== '*':
   break
  else:
   print(str_data[-1])
   print('str_data[-1]!=*')
 except:
  print("读卡错误,请重试!\n")

其输出结果为:

get data from serial port:b'ID:4A622E29\n\xbf\xa8\xd6\xd0\xbf\xe924\xca\xfd\xbe\xdd\xce\xaa:1*80*\r\n'
<class 'bytes'>
<class 'str'>
ID:4A622E29
卡中块24数据为:1*80*

ID:4A622E29 卡中块24数据为:1*80*
80*
<class 'str'> <class 'str'>

串口助手完整代码如下:

#coding=gb18030

import threading
import time
import serial

class ComThread:
 def __init__(self, Port='COM3'):
  self.l_serial = None
  self.alive = False
  self.waitEnd = None
  self.port = Port
  self.ID = None
  self.data = None

 def waiting(self):
  if not self.waitEnd is None:
   self.waitEnd.wait()

 def SetStopEvent(self):
  if not self.waitEnd is None:
   self.waitEnd.set()
  self.alive = False
  self.stop()

 def start(self):
  self.l_serial = serial.Serial()
  self.l_serial.port = self.port
  self.l_serial.baudrate = 115200
  self.l_serial.timeout = 2
  self.l_serial.open()
  if self.l_serial.isOpen():
   self.waitEnd = threading.Event()
   self.alive = True
   self.thread_read = None
   self.thread_read = threading.Thread(target=self.FirstReader)
   self.thread_read.setDaemon(1)
   self.thread_read.start()
   return True
  else:
   return False

 def SendDate(self,i_msg,send):
  lmsg = ''
  isOK = False
  if isinstance(i_msg):
   lmsg = i_msg.encode('gb18030')
  else:
   lmsg = i_msg
  try:
   # 发送数据到相应的处理组件
   self.l_serial.write(send)
  except Exception as ex:
   pass;
  return isOK

 def FirstReader(self):
  while self.alive:
   time.sleep(0.1)

   data = ''
   data = data.encode('utf-8')

   n = self.l_serial.inWaiting()
   if n:
     data = data + self.l_serial.read(n)
     print('get data from serial port:', data)
     print(type(data))

   n = self.l_serial.inWaiting()
   if len(data)>0 and n==0:
    try:
     temp = data.decode('gb18030')
     print(type(temp))
     print(temp)
     car,temp = str(temp).split("\n",1)
     print(car,temp)

     string = str(temp).strip().split(":")[1]
     str_ID,str_data = str(string).split("*",1)

     print(str_ID)
     print(str_data)
     print(type(str_ID),type(str_data))

     if str_data[-1]== '*':
      break
     else:
      print(str_data[-1])
      print('str_data[-1]!=*')
    except:
     print("读卡错误,请重试!\n")

  self.ID = str_ID
  self.data = str_data[0:-1]
  self.waitEnd.set()
  self.alive = False

 def stop(self):
  self.alive = False
  self.thread_read.join()
  if self.l_serial.isOpen():
   self.l_serial.close()
#调用串口,测试串口
def main():
 rt = ComThread()
 rt.sendport = '**1*80*'
 try:
  if rt.start():
   print(rt.l_serial.name)
   rt.waiting()
   print("The data is:%s,The Id is:%s"%(rt.data,rt.ID))
   rt.stop()
  else:
   pass
 except Exception as se:
  print(str(se))

 if rt.alive:
  rt.stop()

 print('')
 print ('End OK .')
 temp_ID=rt.ID
 temp_data=rt.data
 del rt
 return temp_ID,temp_data


if __name__ == '__main__':

 #设置一个主函数,用来运行窗口,便于若其他地方下需要调用串口是可以直接调用main函数
 ID,data = main()

 print("******")
 print(ID,data)

以上这篇对python3 Serial 串口助手的接收读取数据方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
深入理解python对json的操作总结
Jan 05 Python
python bottle框架支持jquery ajax的RESTful风格的PUT和DELETE方法
May 24 Python
在Python中使用AOP实现Redis缓存示例
Jul 11 Python
python smtplib模块实现发送邮件带附件sendmail
May 22 Python
解决python3读取Python2存储的pickle文件问题
Oct 25 Python
2019 Python最新面试题及答案16道题
Apr 11 Python
python3字符串操作总结
Jul 24 Python
给我一面国旗 python帮你实现
Sep 30 Python
python 使用while循环输出*组成的菱形实例
Apr 12 Python
在keras中对单一输入图像进行预测并返回预测结果操作
Jul 09 Python
Python tempfile模块生成临时文件和临时目录
Sep 30 Python
Python 如何将integer转化为罗马数(3999以内)
Jun 05 Python
Python 串口读写的实现方法
Jun 12 #Python
Python获取数据库数据并保存在excel表格中的方法
Jun 12 #Python
Python中一些深不见底的“坑”
Jun 12 #Python
python 实现查找文件并输出满足某一条件的数据项方法
Jun 12 #Python
Python当中的array数组对象实例详解
Jun 12 #Python
Django模型序列化返回自然主键值示例代码
Jun 12 #Python
pandas实现将dataframe满足某一条件的值选出
Jun 12 #Python
You might like
PHP中的extract的作用分析
2008/04/09 PHP
php 运行效率总结(提示程序速度)
2009/11/26 PHP
php引用传值实例详解学习
2013/11/06 PHP
Thinkphp集成抖音SDK的实现方法
2020/04/28 PHP
javascript中使用replaceAll()函数实现字符替换的方法
2010/12/25 Javascript
让图片旋转任意角度及JQuery插件使用介绍
2013/03/20 Javascript
Javascript设置对象的ReadOnly属性(示例代码)
2013/12/25 Javascript
js跳转页面方法总结
2014/01/29 Javascript
jQuery中DOM树操作之使用反向插入方法实例分析
2015/01/23 Javascript
JavaScript预解析及相关技巧分析
2016/04/21 Javascript
Json解析的方法小结
2016/06/22 Javascript
移动端脚本框架Hammer.js
2016/12/15 Javascript
用Electron写个带界面的nodejs爬虫的实现方法
2019/01/29 NodeJs
[00:32]10月24、25日 辉夜杯外卡赛附加赛开赛!
2015/10/23 DOTA
[45:18]完美世界DOTA2联赛循环赛 PXG vs IO 第二场 11.06
2020/11/09 DOTA
Python读取网页内容的方法
2015/07/30 Python
Python使用redis pool的一种单例实现方式
2016/04/16 Python
python 读入多行数据的实例
2018/04/19 Python
mac下pycharm设置python版本的图文教程
2018/06/13 Python
Python 字符串与二进制串的相互转换示例
2018/07/23 Python
python实现自动网页截图并裁剪图片
2018/07/30 Python
python分数表示方式和写法
2019/06/26 Python
python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法
2019/10/04 Python
Pandas之read_csv()读取文件跳过报错行的解决
2020/04/21 Python
浅谈JupyterNotebook导出pdf解决中文的问题
2020/04/22 Python
CSS3颜色值RGBA与渐变色使用介绍
2020/03/06 HTML / CSS
Sneaker Studio匈牙利:购买运动鞋
2018/03/26 全球购物
Europcar澳大利亚官网:全球汽车租赁领域的领导者
2019/03/24 全球购物
莫斯科大型旅游休闲商品超市:Camping.ru
2020/09/16 全球购物
shell的种类有哪些
2015/04/15 面试题
环境科学专业研究生求职信
2013/10/02 职场文书
施工协议书范本
2014/04/22 职场文书
岳庙导游词
2015/02/04 职场文书
2015年护士医德医风自我评价
2015/03/03 职场文书
2019森林防火宣传标语大全!
2019/07/03 职场文书
Python使用Web框架Flask开发项目
2022/06/01 Python