对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中list列表的一些进阶使用方法介绍
Aug 15 Python
python用reduce和map把字符串转为数字的方法
Dec 19 Python
用 Python 连接 MySQL 的几种方式详解
Apr 04 Python
PyQt4实现下拉菜单可供选择并打印出来
Apr 20 Python
Python程序打包工具py2exe和PyInstaller详解
Jun 28 Python
Python PIL读取的图像发生自动旋转的实现方法
Jul 05 Python
python读取并写入mat文件的方法
Jul 12 Python
numpy ndarray 取出满足特定条件的某些行实例
Dec 05 Python
python标识符命名规范原理解析
Jan 10 Python
python给list排序的简单方法
Dec 10 Python
python 监控服务器是否有人远程登录(详细思路+代码)
Dec 18 Python
matplotlib之多边形选区(PolygonSelector)的使用
Feb 24 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
深入分析使用mysql_fetch_object()以对象的形式返回查询结果
2013/06/05 PHP
php使用正则表达式获取图片url的方法
2015/01/16 PHP
php实现异步将远程链接上内容(图片或内容)写到本地的方法
2016/11/30 PHP
PHP实现防止表单重复提交功能【基于token验证】
2018/05/24 PHP
JavaScript 申明函数的三种方法 每个函数就是一个对象(一)
2009/12/04 Javascript
JavaScript中出现乱码的处理心得
2009/12/24 Javascript
onclick与listeners的执行先后问题详细解剖
2013/01/07 Javascript
jquery的live使用注意事项
2014/02/18 Javascript
javascript获取和判断浏览器窗口、屏幕、网页的高度、宽度等
2014/05/08 Javascript
jQuery中prev()方法用法实例
2015/01/08 Javascript
浅谈JavaScript前端开发的MVC结构与MVVM结构
2016/06/03 Javascript
Bootstrap3 datetimepicker控件使用实例
2016/12/13 Javascript
Bootstrap的Carousel配合dropload.js实现移动端滑动切换图片
2017/03/10 Javascript
关于Vue项目跨平台运行问题的解决方法
2018/09/18 Javascript
在Vant的基础上实现添加表单验证框架的方法示例
2018/12/05 Javascript
Angular2使用SVG自定义图表(条形图、折线图)组件示例
2019/05/10 Javascript
vue实现后台管理权限系统及顶栏三级菜单显示功能
2019/06/19 Javascript
JS异步处理的进化史深入讲解
2019/08/25 Javascript
vue中使用v-for时为什么不能用index作为key
2020/04/04 Javascript
梳理一下vue中的生命周期
2020/12/30 Vue.js
centos下更新Python版本的步骤
2013/02/12 Python
详解Python3.1版本带来的核心变化
2015/04/07 Python
解决Scrapy安装错误:Microsoft Visual C++ 14.0 is required...
2017/10/01 Python
Django ImageFiled上传照片并显示的方法
2019/07/28 Python
python线程定时器Timer实现原理解析
2019/11/30 Python
Python 使用 environs 库定义环境变量的方法
2020/02/25 Python
Python不支持 i ++ 语法的原因解析
2020/07/22 Python
Python 如何调试程序崩溃错误
2020/08/03 Python
I.T中国官网:精选时尚设计师单品网购平台
2018/03/26 全球购物
维也纳通行证:Vienna PASS
2019/07/18 全球购物
网络工程师职业规划
2014/02/10 职场文书
服装仓管员岗位职责
2014/06/17 职场文书
倡议书格式
2014/08/30 职场文书
法定代表人身份证明书(含说明)
2014/10/02 职场文书
2015自愿离婚协议书范本
2015/01/28 职场文书
小学教师求职信范文
2015/03/20 职场文书