全网最适合入门的面向对象编程教程:60 Python面向对象归纳实例-传感器数据实时绘图器
全网最适合入门的面向目标编程教程:60 Python 面向目标归纳实例-传感器数据实时绘图器
摘要:
本文将结合之前内容完结模仿一个传感器系统软件,包括三个线程:传感器线程生成数据并经过串口发送给主机进程;主机进程经过串口接纳指令,进行数据滤波和处理后,将处理结果发送给绘图线程;绘图线程担任接纳数据并制作更新数据曲线。
原文链接:
往期引荐:
全网最适合入门的面向目标编程教程:00 面向目标规划办法导论
全网最适合入门的面向目标编程教程:01 面向目标编程的根本概念
全网最适合入门的面向目标编程教程:02 类和目标的 Python 完结-运用 Python 创立类
全网最适合入门的面向目标编程教程:03 类和目标的 Python 完结-为自界说类增加特点
全网最适合入门的面向目标编程教程:04 类和目标的Python完结-为自界说类增加办法
全网最适合入门的面向目标编程教程:05 类和目标的Python完结-PyCharm代码标签
全网最适合入门的面向目标编程教程:06 类和目标的Python完结-自界说类的数据封装
全网最适合入门的面向目标编程教程:07 类和目标的Python完结-类型注解
全网最适合入门的面向目标编程教程:08 类和目标的Python完结-@property装修器
全网最适合入门的面向目标编程教程:09 类和目标的Python完结-类之间的联系
全网最适合入门的面向目标编程教程:10 类和目标的Python完结-类的承继和里氏替换准则
全网最适合入门的面向目标编程教程:11 类和目标的Python完结-子类调用父类办法
全网最适合入门的面向目标编程教程:12 类和目标的Python完结-Python运用logging模块输出程序运转日志
全网最适合入门的面向目标编程教程:13 类和目标的Python完结-可视化阅览代码神器Sourcetrail的装置运用
全网最适合入门的面向目标编程教程:全网最适合入门的面向目标编程教程:14 类和目标的Python完结-类的静态办法和类办法
全网最适合入门的面向目标编程教程:15 类和目标的 Python 完结-__slots__魔法办法
全网最适合入门的面向目标编程教程:16 类和目标的Python完结-多态、办法重写与开闭准则
全网最适合入门的面向目标编程教程:17 类和目标的Python完结-鸭子类型与“file-like object“
全网最适合入门的面向目标编程教程:18 类和目标的Python完结-多重承继与PyQtGraph串口数据制作曲线图
全网最适合入门的面向目标编程教程:19 类和目标的 Python 完结-运用 PyCharm 主动生成文件注释和函数注释
全网最适合入门的面向目标编程教程:20 类和目标的Python完结-组合联系的完结与CSV文件保存
全网最适合入门的面向目标编程教程:21 类和目标的Python完结-多文件的安排:模块module和包package
全网最适合入门的面向目标编程教程:22 类和目标的Python完结-反常和语法错误
全网最适合入门的面向目标编程教程:23 类和目标的Python完结-抛出反常
全网最适合入门的面向目标编程教程:24 类和目标的Python完结-反常的捕获与处理
全网最适合入门的面向目标编程教程:25 类和目标的Python完结-Python判别输入数据类型
全网最适合入门的面向目标编程教程:26 类和目标的Python完结-上下文办理器和with句子
全网最适合入门的面向目标编程教程:27 类和目标的Python完结-Python中反常层级与自界说反常类的完结
全网最适合入门的面向目标编程教程:28 类和目标的Python完结-Python编程准则、哲学和标准大汇总
全网最适合入门的面向目标编程教程:29 类和目标的Python完结-断语与防御性编程和help函数的运用
全网最适合入门的面向目标编程教程:30 Python的内置数据类型-object根类
全网最适合入门的面向目标编程教程:31 Python的内置数据类型-目标Object和类型Type
全网最适合入门的面向目标编程教程:32 Python的内置数据类型-类Class和实例Instance
全网最适合入门的面向目标编程教程:33 Python的内置数据类型-目标Object和类型Type的联系
全网最适合入门的面向目标编程教程:34 Python的内置数据类型-Python常用复合数据类型:元组和命名元组
全网最适合入门的面向目标编程教程:35 Python的内置数据类型-文档字符串和__doc__特点
全网最适合入门的面向目标编程教程:36 Python的内置数据类型-字典
全网最适合入门的面向目标编程教程:37 Python常用复合数据类型-列表和列表推导式
全网最适合入门的面向目标编程教程:38 Python常用复合数据类型-运用列表完结仓库、行列和双端行列
全网最适合入门的面向目标编程教程:39 Python常用复合数据类型-调集
全网最适合入门的面向目标编程教程:40 Python常用复合数据类型-枚举和enum模块的运用
全网最适合入门的面向目标编程教程:41 Python常用复合数据类型-行列(FIFO、LIFO、优先级行列、双端行列和环形行列)
全网最适合入门的面向目标编程教程:42 Python常用复合数据类型-collections容器数据类型
全网最适合入门的面向目标编程教程:43 Python常用复合数据类型-扩展内置数据类型
全网最适合入门的面向目标编程教程:44 Python内置函数与魔法办法-重写内置类型的魔法办法
全网最适合入门的面向目标编程教程:45 Python完结常见数据结构-链表、树、哈希表、图和堆
全网最适合入门的面向目标编程教程:46 Python函数办法与接口-函数与事情驱动结构
全网最适合入门的面向目标编程教程:47 Python函数办法与接口-回调函数Callback
全网最适合入门的面向目标编程教程:48 Python函数办法与接口-方位参数、默许参数、可变参数和关键字参数
全网最适合入门的面向目标编程教程:49 Python函数办法与接口-函数与办法的差异和lamda匿名函数
全网最适合入门的面向目标编程教程:50 Python函数办法与接口-接口和笼统基类
全网最适合入门的面向目标编程教程:51 Python函数办法与接口-运用Zope完结接口
全网最适合入门的面向目标编程教程:52 Python函数办法与接口-Protocol协议与接口
全网最适合入门的面向目标编程教程:53 Python字符串与序列化-字符串与字符编码
全网最适合入门的面向目标编程教程:54 Python字符串与序列化-字符串格局化与format办法
全网最适合入门的面向目标编程教程:55 Python字符串与序列化-字节序列类型和可变字节字符串
全网最适合入门的面向目标编程教程:56 Python字符串与序列化-正则表达式和re模块运用
全网最适合入门的面向目标编程教程:57 Python字符串与序列化-序列化与反序列化
全网最适合入门的面向目标编程教程:58 Python字符串与序列化-序列化Web目标的界说与完结
全网最适合入门的面向目标编程教程:59 Python并行与并发-并行与并发和线程与进程
更多精彩内容可看:
给你的 Python 加加快:一文速通 Python 并行核算
一个MicroPython的开源项目集锦:awesome-micropython,包括各个方面的Micropython东西库
SenseCraft 布置模型到Grove Vision AI V2图画处理模块
文档和代码获取:
可拜访如下链接进行对文档下载:
https://github.com/leezisheng/Doc
本文档首要介绍怎么运用 Python 进行面向目标编程,需求读者对 Python 语法和单片机开发具有根本了解。比较其他解说 Python 面向目标编程的博客或书本而言,本文档愈加具体、侧重于嵌入式上位机运用,以上位机和下位机的常见串口数据收发、数据处理、动态图制作等为运用实例,一起运用 Sourcetrail 代码软件对代码进行可视化阅览便于读者了解。
相关示例代码获取链接如下:https://github.com/leezisheng/Python-OOP-Demo
正文
接下来,咱们将运用之前学习过的内容完结如下使命:
- 模仿传感器线程生成数据,经过串口协议传输给模仿主机进程;
- 模仿主机进程经过串口发送给传感器线程指令以获取数据,进行数据滤波和处理,并将数据传输给绘图线程;
- 绘图线程完结数据曲线制作和更新操作。
能够注意到,咱们之前为了论述面向目标编程的技巧,所提及的某些类和类之间的相关规划,在实践运用中并非最佳实践。此外,原先的程序代码中,为了增强读者的直观感触,咱们运用了很多的 print 句子进行输出。但是,这样的做法在程序进行并行运转时,不只会下降全体的履行功率,并且在调查终端输出时,关于多线程或多进程的运转次序也易形成混杂,使得了解变得困难。因而,咱们有必要对这部分代码进行优化调整,以进步程序的功能和可读性。
在以下代码中,咱们界说了一个 MasterProcess 主机多进程类,它承继了 Process 类,用于创立和办理主机多进程。能够看到 MasterProcess 主机多进程类直接在__ReadMasterSerial 和__WriteMasterSerial 办法中完结了串口的读写,而不像原先代码 MasterClass 类承继于 SerialClass 类。
示例代码如下:
class MasterProcess(Process):
'''
主机多进程类
'''
_# 类变量:_
_# START_CMD - 敞开指令 -0_
_# STOP_CMD - 封闭指令 -1_
_# SENDID_CMD - 发送ID指令 -2_
_# SENDVALUE_CMD - 发送数据指令 -3_
START_CMD, STOP_CMD, SENDID_CMD, SENDVALUE_CMD = (0, 1, 2, 3)
def __init__(self,
lock,
Queue,
simplequeue,
port:str = "COM17",
baudrate:int = 115200,
bytesize:int = serial.EIGHTBITS,
parity :str = serial.PARITY_NONE,
stopbits:int = serial.STOPBITS_ONE):
'''
MasterProcess初始化函数
:param lock: 互斥锁
:param Queue: 行列
:param port: 端口号
:param baudrate: 波特率
:param bytesize: 数据位
:param parity: 校验位
:param stopbits: 中止位
'''
self.lock = lock
self.Queue = Queue
self.simplequeue = simplequeue
self.dev = serial.Serial()
self.dev.port = port
self.dev.baudrate = baudrate
self.dev.bytesize = bytesize
self.dev.parity = parity
self.dev.stopbits = stopbits
_# 设置读取timeout超时时刻_
self.dev.timeout = 0.3
_# 设置写入timeout超时时刻_
self.dev.write_timeout = 0.3
_# 数据缓存_
self.datalist = []
_# 滤波器长度_
self.filterlength = 3
_# 数据处理类实例_
self.dataprocessobj = DateProcessClass(self.datalist,self.filterlength)
_# Process初始化办法_
Process.__init__(self)
def StartMasterSerial(self):
'''
翻开主机串口
:return: None
'''
self.dev.open()
def StopMasterSerial(self):
'''
中止主机串口
:return: None
'''
self.dev.close()
def __ReadMasterSerial(self):
'''
读取主机串口,私有办法
:return data[int] : 读取的数据
'''
_# 按行读取_
data = self.dev.readline()
_# 假如接纳到字节的情况下,进行处理_
if data != b'':
_# 收到为二进制数据_
_# 用utf-8编码将二进制数据解码为unicode字符串_
_# 字符串转为int类型_
data = int(data.decode('utf-8', 'replace'))
_# 不然,设置data为-1_
else:
data = -1
return data
def __WriteMasterSerial(self,write_data):
'''
写入主机串口,私有办法
:param write_data: 写入的数据
:return:
'''
_# 非堵塞办法写入_
self.dev.write(write_data.encode())
_# 输出换行符_
_# write的输入参数有必要是bytes格局_
_# 字符串数据需求encode()函数将其编码为二进制数据,然后才能够顺畅发送_
_# \r\n表明换行回车_
self.dev.write('\r\n'.encode())
def RecvSensorID(self):
'''
读取传感器ID
:return sensorid[int] : 读取的传感器id号
'''
sensorid = self.__ReadMasterSerial()
return sensorid
def RecvSensorValue(self):
'''
读取传感器数据值
:return data[int] : 读取的传感器数据
'''
data = self.__ReadMasterSerial()
return data
def SendSensorCMD(self,cmd):
'''
主机发送指令
:param cmd : MasterProcess中的类变量
:return: None
'''
self.__WriteMasterSerial(str(cmd))
一起,咱们在其间界说了一个 run 办法,这个办法在多进程发动后被调用。在这个办法中,首要翻开串口,然后发送获取 ID 的指令,接纳传感器的 ID 号。然后进入一个无限循环,每 9 次循环,核算一次最大值和最小值,并打印出来。然后发送获取数据的指令,接纳传感器的数据,将数据放入行列和列表中,然后对数据进行滤波处理,将滤波后的数据放入另一个行列。最终,打印出接纳到的传感器数据,并让当时进程休眠 0.5 秒。
示例代码如下:
def run(self):
'''
多进程start后运转的办法
:return: None
'''
_# 运转计数变量_
count = 0
_# 文件保存索引计数变量_
index = 0
_# 翻开串口_
self.StartMasterSerial()
self.lock.acquire()
print(" Master Process Started ")
self.lock.release()
_# 发送获取ID指令_
self.SendSensorCMD(self.SENDID_CMD)
_# 获取传感器ID号_
id = self.RecvSensorID()
self.lock.acquire()
print(" Recv Sensor ID : ", id)
self.lock.release()
while True:
if count == 9:
maxvalue = self.dataprocessobj.DateCalMax()
minvalue = self.dataprocessobj.DateCalMin()
self.lock.acquire()
print("----------------------------------")
print("Max Value: ", maxvalue)
print("Min Value: ", minvalue)
print("----------------------------------")
self.lock.release()
count = 0
else:
count = count + 1
_# 发送获取数据指令_
self.SendSensorCMD(self.SENDVALUE_CMD)
self.lock.acquire()
print("Master Send SENDVALUE_CMD")
self.lock.release()
_# 接纳传感器数据值_
data = self.RecvSensorValue()
self.Queue.put(data)
self.datalist.append(data)
filterdata,filterdatalist = self.dataprocessobj.DateFilter()