经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
全网最适合入门的面向对象编程教程:20 类和对象的 Python 实现-组合关系的实现与 CSV 文件保存
来源:cnblogs  作者:FreakStudio  时间:2024/7/19 10:38:15  对本文有异议

全网最适合入门的面向对象编程教程:20 类和对象的 Python 实现-组合关系的实现与 CSV 文件保存

摘要:

本文主要介绍了在使用 Python 面向对象编程时,如何实现组合关系,同时对比了组合关系和继承关系的优缺点,并讲解了如何通过 csv 模块来保存 Python 接收/生成的数据。

原文链接:

FreakStudio的博客

往期推荐:

学嵌入式的你,还不会面向对象??!

全网最适合入门的面向对象编程教程: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 自动生成文件注释和函数注释

更多精彩内容可看:

给你的 Python 加加速:一文速通 Python 并行计算

一文搞懂 CM3 单片机调试原理

肝了半个月,嵌入式技术栈大汇总出炉

电子计算机类比赛的“武林秘籍”

一个MicroPython的开源项目集锦:awesome-micropython,包含各个方面的Micropython工具库

文档和代码获取:

可访问如下链接进行对文档下载:

https://github.com/leezisheng/Doc

image

本文档主要介绍如何使用 Python 进行面向对象编程,需要读者对 Python 语法和单片机开发具有基本了解。相比其他讲解 Python 面向对象编程的博客或书籍而言,本文档更加详细、侧重于嵌入式上位机应用,以上位机和下位机的常见串口数据收发、数据处理、动态图绘制等为应用实例,同时使用 Sourcetrail 代码软件对代码进行可视化阅读便于读者理解。

相关示例代码获取链接如下:https://github.com/leezisheng/Python-OOP-Demo

正文

前面讲了面向类与对象的继承,知道了继承是一种什么“是”什么的关系。然而类与类之间还有另一种关系,这就是组合。组合是将几个对象收集在一起生成一个新对象的行为。当一个对象是另外一个对象的一部分时,组合通常是不错的选择。

例如,汽车是由发动机、传动装置、启动装置、车前灯、挡风玻璃以及其他部件组成的,发动机又是由活塞、曲柄轴和阀门等组合而成的。汽车是发动机等多个元器件的抽象,而发动机是活塞等元器件的抽象,二者处于不同的层次而又有彼此交互的接口,组合是提供不同抽象层的好办法。汽车对象可以提供司机所需要的接口,同时也能够获取内在组成部分,从而为机械师提供适合操作的深层抽象。当然,如果机械师需要更多信息来诊断问题或调整发动机,这些组成部分也可以进一步被细分。

总的来说,组合就是让不同的类混合并且加入其他类中来增加功能和代码重用性,这种适用于由多个小类组成一个大类的情况,并且不需要对小类进行太多修改。在前面示例中,我们实现了主机的串口收发和绘图功能,在实际应用中,我们往往需要将传感器数据存储到文件中,以便后续的查看和处理,很明显前面的传感器数据为一维的时间序列数据,适合存储为表格类型(即列标题为索引和值),我们通常将该类数据保存为 csv 格式文件,csv 是一种字符串文件的格式,它组织数据的语法就是在字符串之间加分隔符(行与行之间是加换行符,同行字符之间是加逗号分隔),可以用任意的文本编辑器打开(如记事本),也可以用 Excel 打开,还可以通过 Excel 把文件另存为 csv 格式。用 csv 格式存储数据,读写比较方便,易于实现,文件也会比 Excel 文件小。但 csv 文件缺少 Excel 文件本身的很多功能,如不能嵌入图像和图表,不能生成公式等等。

操作 csv 文件我们需要借助 csv 模块,python 自带 csv 模块,不需要我们使用 pip 安装,我们可以点击如下链接查看 csv 模块使用方法:

https://docs.python.org/zh-cn/3.13/library/csv.html#csv.writer

image

这里,我们首先定义一个 FileIOClass 类,其中具有初始化方法、写入传感器数据到文件方法和关闭文件方法,示例代码如下:

  1. import csv
  2. _# 使用typing模块提供的复合注解功能_
  3. from typing import List
  4. class FileIOClass:
  5. def __init__(self,path:str="G:\\Python面向对象编程\\Demo\\file.csv"):
  6. '''
  7. 初始化csv文件和列标题
  8. :param path: 文件路径和文件名
  9. '''
  10. self.path = path
  11. _# path为输出路径和文件名,newline=''是为了不出现空行_
  12. self.csvFile = open(path, "w+", newline='')
  13. _# rowname为列名,index-索引,data-数据_
  14. self.rowname = ['index', 'data']
  15. _# 返回一个writer对象,将用户的数据在给定的文件型对象上转换为带分隔符的字符串_
  16. self.writer = csv.writer(self.csvFile)
  17. _# 写入csv文件的列标题_
  18. self.writer.writerow( self.rowname)
  19. def WriteFile(self,index:List[int],data:List[int])->None:
  20. '''
  21. :param index: 传感器索引列表
  22. :param data: 传感器数据列表
  23. :return:
  24. '''
  25. writedatalist = []
  26. for i in range(len(data)):
  27. writedatalist.append([index[i],data[i]])
  28. _# 将列表中的每个元素将被写入CSV文件的一列中_
  29. self.writer.writerow(writedatalist[i])
  30. def CloseFile(self)->None:
  31. '''
  32. 关闭文件
  33. :return: None
  34. '''
  35. self.csvFile.close()

这里,在初始化方法中,我们需要传入文件保存路径。之后创建一个 writer 对象,将用户的数据在给定的文件型对象上转换为带分隔符的字符串,同时写入 csv 文件的列标题。在 WriteFile 方法中传入数据的索引列表用于表示数据的先后顺序,之后是数据列表(这里的类型注解需要使用 typing 模块提供的复合注解功能),并循环将每个元素将被写入 CSV 文件的一列中,最后定义了文件的关闭方法。

image

在主函数中,我们创建 FileIOClass 对象,写入模拟传感器数据后关闭文件,以下为示例代码和运行效果:

  1. if __name__ == '__main__':
  2. path = "G:\\Python面向对象编程\\Demo\\file.csv"
  3. data = [11,42,307,46,55,61,78,80,19,11]
  4. index = [count for count in range(len(data))]
  5. file = FileIOClass(path)
  6. file.WriteFile(index,data)
  7. file.CloseFile()

image

这里,我们可以直接在 MasterClass 类的初始化中创建 FileIOClass 类的实例化对象来实现组合。代码如下:

  1. _# 文件保存路径_
  2. self.savepath = "G:\\Python面向对象编程\\Demo\\file.csv"
  3. _# 创建FileIOClass类的实例化对象_
  4. self.fileio = FileIOClass(self.savepath)

通过 sourcetrail,我们可以清晰看到类之间的组合与继承关系:

image

image

在主程序中,我们在主机接收 10 次数据后,将数据保存到 file.csv 中:

  1. if __name__ == "__main__":
  2. _ # 创建数据列表_
  3. datalist = []
  4. m = MasterClass(state = MasterClass.IDLE_STATE,
  5. port = "COM17",
  6. wintitle = "Basic plotting examples",
  7. plottitle = "Updating plot",
  8. width = 1000,
  9. height = 600)
  10. m.StartMaster()
  11. m.SendSensorCMD(MasterClass.SENDID_CMD)
  12. m.RecvSensorID()
  13. # 循环10次接收数据
  14. for i in range(10):
  15. m.SendSensorCMD(MasterClass.SENDVALUE_CMD)
  16. value = m.RecvSensorValue()
  17. datalist.append(value)
  18. indexlist = [count for count in range(len(datalist))]
  19. # 写入数据
  20. m.fileio.WriteFile(indexlist,datalist)
  21. m.fileio.CloseFile()

如下为运行效果:

image

目前,整个文件的完整代码如下,可以看到单单是这么一个简单程序就有了三百多行,对于代码查找修改来讲,非常不便。同时我们注意到,几个不同类之间似乎功能并不相同,不应该放到一个文件中。下一节我们将会说如何利用 Python 中的模块和包来组织我们的代码。

完整代码如下:

  1. _# 串口相关库_
  2. import serial
  3. import serial.tools.list_ports
  4. _# 队列相关_
  5. import queue
  6. import random
  7. _# 日志输出相关库_
  8. import logging
  9. _# 曲线作图相关库_
  10. import pyqtgraph as pg
  11. import numpy as np
  12. from pyqtgraph.Qt import QtCore
  13. _# 文件读写相关库_
  14. import csv
  15. _# 使用typing模块提供的复合注解功能_
  16. from typing import List
  17. import time
  18. _# # 设置日志输出级别_
  19. _# logging.basicConfig(level=logging.DEBUG)_
  20. _# 在配置下日志输出目标文件和日志格式_
  21. LOG_FORMAT="%(asctime)s-%(levelname)s-%(message)s"
  22. logging.basicConfig(filename='my.log',level=logging.DEBUG,format=LOG_FORMAT)
  23. class SerialClass:
  24. _# 限定SerialClass对象只能绑定以下属性_
  25. __slots__ = ('dev','_SerialClass__devstate')
  26. _# 初始化_
  27. _# 使用默认参数_
  28. def __init__(self,
  29. devport:str = "COM17",
  30. devbaudrate:int = 115200,
  31. devbytesize:int = serial.EIGHTBITS,
  32. devparity :str = serial.PARITY_NONE,
  33. devstopbits:int = serial.STOPBITS_ONE):
  34. _# 直接传入serial.Serial()类_
  35. self.dev = serial.Serial()
  36. self.dev.port = devport
  37. self.dev.baudrate = devbaudrate
  38. self.dev.bytesize = devbytesize
  39. self.dev.parity = devparity
  40. self.dev.stopbits = devstopbits
  41. _# 表示串口设备的状态-打开或者关闭_
  42. _# 初始化时为关闭_
  43. self.__devstate = False
  44. print("SerialClass init")
  45. logging.info("SerialClass init")
  46. _# 取值方法_
  47. @property
  48. def devstate(self):
  49. return self.__devstate
  50. _# 打开串口_
  51. def OpenSerial(self):
  52. print("SerialClass-OpenSerial")
  53. logging.info("SerialClass-OpenSerial")
  54. self.dev.open()
  55. self.__devstate = True
  56. _# 关闭串口_
  57. def CloseSerial(self):
  58. print("SerialClass-CloseSerial")
  59. logging.info("SerialClass-CloseSerial")
  60. self.dev.close()
  61. self.__devstate = False
  62. _# 串口读取_
  63. def ReadSerial(self):
  64. print("SerialClass-ReadSerial")
  65. logging.info("SerialClass-ReadSerial")
  66. if self.__devstate:
  67. _# 阻塞方式读取_
  68. _# 按行读取_
  69. data = self.dev.readline()
  70. _# 收到为二进制数据_
  71. _# 用utf-8编码将二进制数据解码为unicode字符串_
  72. _# 字符串转为int类型_
  73. data = int(data.decode('utf-8', 'replace'))
  74. return data
  75. _# 串口写入_
  76. def WriteSerial(self,write_data):
  77. print("SerialClass-WriteSerial")
  78. logging.info("SerialClass-WriteSerial")
  79. if self.__devstate:
  80. _# 非阻塞方式写入_
  81. self.dev.write(write_data.encode())
  82. _# 输出换行符_
  83. _# write的输入参数必须是bytes 格式_
  84. _# 字符串数据需要encode()函数将其编码为二进制数据,然后才可以顺利发送_
  85. _# \r\n表示换行回车_
  86. self.dev.write('\r\n'.encode())
  87. def RetSerialState(self):
  88. if self.dev.isOpen():
  89. self.__devstate = True
  90. return True
  91. else:
  92. self.__devstate = False
  93. return False
  94. class PlotClass:
  95. _# 绘图类初始化_
  96. def __init__(self,wintitle:str="Basic plotting examples",plottitle:str="Updating plot",width:int=1000,height:int=600):
  97. '''
  98. 用于初始化Plot类
  99. :param wintitle: 窗口标题
  100. :param plottitle: 图层标题
  101. :param width: 窗口宽度
  102. :param height: 窗口高度
  103. '''
  104. _# Qt应用实例对象_
  105. self.app = None
  106. _# 窗口对象_
  107. self.win = None
  108. _# 设置窗口标题_
  109. self.title = wintitle
  110. _# 设置窗口尺寸_
  111. self.width = width
  112. self.height = height
  113. _# 传感器数据_
  114. self.value = 0
  115. _# 计数变量_
  116. self.__count = 0
  117. _# 传感器数据缓存列表_
  118. self.valuelist = []
  119. _# 绘图曲线_
  120. self.curve = None
  121. _# 图层对象_
  122. self.plotob = None
  123. _# 图层标题_
  124. self.plottitle = plottitle
  125. _# 定时器对象_
  126. self.timer = QtCore.QTimer()
  127. _# 定时时间_
  128. self.time = 0
  129. _# Qt应用和窗口初始化_
  130. self.appinit()
  131. print("PLOT INIT SUCCESS")
  132. logging.info("PLOT INIT SUCCESS")
  133. _# 应用程序初始化_
  134. def appinit(self):
  135. '''
  136. 用于qt应用程序初始化,添加窗口、曲线和图层
  137. :return: None
  138. '''
  139. _# 创建一个Qt应用,并返回该应用的实例对象_
  140. self.app = pg.mkQApp("Plotting Example")
  141. _# 生成多面板图形_
  142. _# show:(bool) 如果为 True,则在创建小部件后立即显示小部件。_
  143. _# title:(str 或 None)如果指定,则为此小部件设置窗口标题。_
  144. self.win = pg.GraphicsLayoutWidget(show=True, title=self.title)
  145. _# 设置窗口尺寸_
  146. self.win.resize(self.width, self.height)
  147. _# 进行窗口全局设置,setConfigOptions一次性配置多项参数_
  148. _# antialias启用抗锯齿,useNumba对图像进行加速_
  149. pg.setConfigOptions(antialias=True, useNumba=True)
  150. _# 添加图层_
  151. self.plotob = self.win.addPlot(title=self.plottitle)
  152. _# 添加曲线_
  153. self.curve = self.plotob.plot(pen='y')
  154. _# 接收数据_
  155. def GetValue(self,value):
  156. '''
  157. 用于接收传感器数据,加入缓存列表
  158. :param value: 传感器数据
  159. :return: None
  160. '''
  161. self.value = value
  162. _# 加入数据缓存列表_
  163. self.valuelist.append(value)
  164. print("PLOT RECV DATA : "+str(self.value))
  165. logging.info("PLOT RECV DATA : "+str(self.value))
  166. _# 更新曲线数据_
  167. def DataUpdate(self):
  168. '''
  169. 用于定时进行曲线更新,这里模拟绘制正弦曲线
  170. :return: None
  171. '''
  172. _# 模拟绘制正弦曲线_
  173. _# 计数变量更新_
  174. self.__count = self.__count + 0.1
  175. self.value = np.sin(self.__count)
  176. self.GetValue(self.value)
  177. _# 将数据转化为图形_
  178. self.curve.setData(self.valuelist)
  179. _# 设置定时更新_
  180. def SetUpdate(self,time:int = 100):
  181. '''
  182. 设置定时更新任务
  183. :param time: 定时的时间
  184. :return: None
  185. '''
  186. _# 定时器结束,触发DataUpdate方法_
  187. self.timer.timeout.connect(self.DataUpdate)
  188. _# 启动定时器_
  189. self.timer.start(time)
  190. _# 定时时间_
  191. self.time = time
  192. print("PLOT SET UPDATA")
  193. logging.info("PLOT SET UPDATA")
  194. _# 进入主事件循环并等待_
  195. pg.exec()
  196. class FileIOClass:
  197. def __init__(self,path:str="G:\\Python面向对象编程\\Demo\\file.csv"):
  198. '''
  199. 初始化csv文件和列标题
  200. :param path: 文件路径和文件名
  201. '''
  202. self.path = path
  203. _# path为输出路径和文件名,newline=''是为了不出现空行_
  204. self.csvFile = open(path, "w+", newline='')
  205. _# rowname为列名,index-索引,data-数据_
  206. self.rowname = ['index', 'data']
  207. _# 返回一个writer对象,将用户的数据在给定的文件型对象上转换为带分隔符的字符串_
  208. self.writer = csv.writer(self.csvFile)
  209. _# 写入csv文件的列标题_
  210. self.writer.writerow(self.rowname)
  211. def WriteFile(self,index:List[int],data:List[int])->None:
  212. '''
  213. :param index: 传感器索引列表
  214. :param data: 传感器数据列表
  215. :return:
  216. '''
  217. writedatalist = []
  218. for i in range(len(data)):
  219. writedatalist.append([index[i],data[i]])
  220. _# 将列表中的每个元素将被写入CSV文件的一列中_
  221. self.writer.writerow(writedatalist[i])
  222. def CloseFile(self)->None:
  223. '''
  224. 关闭文件
  225. :return: None
  226. '''
  227. self.csvFile.close()
  228. class SensorClass(SerialClass):
  229. _# 类变量:_
  230. _# RESPOND_MODE -响应模式-0_
  231. _# LOOP_MODE -循环模式-1_
  232. RESPOND_MODE,LOOP_MODE = (0,1)
  233. _# 类变量:_
  234. _# START_CMD - 开启命令 -0_
  235. _# STOP_CMD - 关闭命令 -1_
  236. _# SENDID_CMD - 发送ID命令 -2_
  237. _# SENDVALUE_CMD - 发送数据命令 -3_
  238. START_CMD,STOP_CMD,SENDID_CMD,SENDVALUE_CMD = (0,1,2,3)
  239. _# 类的初始化_
  240. def __init__(self,port:str = "COM11",id:int = 0,state:int = RESPOND_MODE):
  241. _# 调用父类的初始化方法,super() 函数将父类和子类连接_
  242. super().__init__(port)
  243. self.sensorvalue = 0
  244. self.sensorid = id
  245. self.sensorstate = state
  246. print("Sensor Init")
  247. logging.info("Sensor Init")
  248. @staticmethod
  249. _# 判断传感器ID号是否正确:这里判断ID号是否在0到99之间_
  250. def IsTrueID(id:int = 0):
  251. if id >= 0 and id <= 99:
  252. print("Sensor ID True")
  253. return True
  254. else:
  255. print("Sensor ID False")
  256. return False
  257. _# 传感器上电初始化_
  258. def InitSensor(self):
  259. _# 传感器上电初始化工作_
  260. _# 同时输出ID号以及状态_
  261. print("Sensor %d Init complete : %d"%(self.sensorid,self.sensorstate))
  262. logging.info("Sensor %d Init complete : %d"%(self.sensorid,self.sensorstate))
  263. _# 开启传感器_
  264. def StartSensor(self):
  265. super().OpenSerial()
  266. print("Sensor %d start serial %s "%(self.sensorid,self.dev.port))
  267. logging.info("Sensor %d start serial %s "%(self.sensorid,self.dev.port))
  268. _# 停止传感器_
  269. def StopSensor(self):
  270. super().CloseSerial()
  271. print("Sensor %d close serial %s " % (self.sensorid, self.dev.port))
  272. logging.info("Sensor %d close serial %s " % (self.sensorid, self.dev.port))
  273. _# 发送传感器ID号_
  274. def SendSensorID(self):
  275. super().WriteSerial(str(self.sensorid))
  276. print("Sensor %d send id "%self.sensorid)
  277. logging.info("Sensor %d send id "%self.sensorid)
  278. _# 发送传感器数据_
  279. def SendSensorValue(self):
  280. _# 生成[1, 10]内的随机整数_
  281. data = random.randint(1, 10)
  282. super().WriteSerial(str(data))
  283. print("Sensor %d send data %d" % (self.sensorid,data))
  284. logging.info("Sensor %d send data %d" % (self.sensorid,data))
  285. _# 接收主机指令_
  286. def RecvMasterCMD(self):
  287. cmd = super().ReadSerial()
  288. print("Sensor %d recv cmd %d " % (self.sensorid,cmd))
  289. logging.info("Sensor %d recv cmd %d " % (self.sensorid,cmd))
  290. return cmd
  291. class MasterClass(SerialClass,PlotClass):
  292. _# 类变量:_
  293. _# BUSY_STATE -忙碌状态-0_
  294. _# IDLE_STATE -空闲状态-1_
  295. BUSY_STATE, IDLE_STATE = (0, 1)
  296. _# 类变量:_
  297. _# START_CMD - 开启命令 -0_
  298. _# STOP_CMD - 关闭命令 -1_
  299. _# SENDID_CMD - 发送ID命令 -2_
  300. _# SENDVALUE_CMD - 发送数据命令 -3_
  301. START_CMD, STOP_CMD, SENDID_CMD, SENDVALUE_CMD = (0, 1, 2, 3)
  302. _# 类的初始化_
  303. def __init__(self,state:int = IDLE_STATE,port:str = "COM17",wintitle:str="Basic plotting examples",plottitle:str="Updating plot",width:int=1000,height:int=600):
  304. _# 分别调用不同父类的__init__方法_
  305. SerialClass.__init__(self,port)
  306. PlotClass.__init__(self,wintitle,plottitle,width,height)
  307. self.valuequeue = queue.Queue(10)
  308. self.__masterstatue = state
  309. _# 初始化完成的标志量_
  310. self.INIT_FLAG = False
  311. _# 文件保存路径_
  312. self.savepath = "G:\\Python面向对象编程\\Demo\\file.csv"
  313. _# 创建FileIOClass类的实例化对象_
  314. self.fileio = FileIOClass(self.savepath)
  315. print("MASTER INIT SUCCESSS")
  316. logging.info("MASTER INIT SUCCESSS")
  317. @classmethod
  318. def MasterInfo(cls):
  319. print("Info : "+str(cls))
  320. _# 开启主机_
  321. def StartMaster(self):
  322. super().OpenSerial()
  323. print("START MASTER :"+self.dev.port)
  324. logging.info("START MASTER :"+self.dev.port)
  325. _# 停止主机_
  326. def StopMaster(self):
  327. super().CloseSerial()
  328. print("CLOSE MASTER :" + self.dev.port)
  329. logging.info("CLOSE MASTER :" + self.dev.port)
  330. _# 接收传感器ID号_
  331. def RecvSensorID(self):
  332. sensorid = super().ReadSerial()
  333. print("MASTER RECIEVE ID : " + str(sensorid))
  334. logging.info("MASTER RECIEVE ID : " + str(sensorid))
  335. return sensorid
  336. _# 接收传感器数据_
  337. def RecvSensorValue(self):
  338. data = super().ReadSerial()
  339. print("MASTER RECIEVE DATA : " + str(data))
  340. logging.info("MASTER RECIEVE DATA : " + str(data))
  341. self.valuequeue.put(data)
  342. return data
  343. _# 主机发送命令_
  344. def SendSensorCMD(self,cmd):
  345. super().WriteSerial(str(cmd))
  346. print("MASTER SEND CMD : " + str(cmd))
  347. logging.info("MASTER SEND CMD : " + str(cmd))
  348. _# 主机返回工作状态-_
  349. def RetMasterStatue(self):
  350. return self.__masterstatue
  351. _# 重写父类的DataUpdate方法_
  352. def DataUpdate(self):
  353. self.SendSensorCMD(self.SENDVALUE_CMD)
  354. self.value = self.RecvSensorValue()
  355. self.WriteSerial("Recv:"+str(self.value))
  356. self.GetValue(self.value)
  357. self.curve.setData(self.valuelist)
  358. print("PLOT UPDATA : " + str(self.value))
  359. logging.info("PLOT UPDATA : " + str(self.value))
  360. class DevClass(SerialClass):
  361. def __init__(self,port:str = "COM1"):
  362. super().__init__(port)
  363. _# 开启设备_
  364. def StartDev(self):
  365. super().OpenSerial()
  366. print("START Dev :" + self.dev.port)
  367. def ReadSerial(self,byte_size):
  368. if super().RetSerialState():
  369. data = self.dev.read(byte_size)
  370. data = int(data.decode('utf-8', 'replace'))
  371. return data
  372. _# 判断串口类对象的串口是否开启_
  373. def IsSerialConnected(serialclass):
  374. return serialclass.RetSerialState()
  375. if __name__ == "__main__":
  376. _# 创建数据列表_
  377. datalist = []
  378. m = MasterClass(state = MasterClass.IDLE_STATE,
  379. port = "COM17",
  380. wintitle = "Basic plotting examples",
  381. plottitle = "Updating plot",
  382. width = 1000,
  383. height = 600)
  384. m.StartMaster()
  385. m.SendSensorCMD(MasterClass.SENDID_CMD)
  386. m.RecvSensorID()
  387. _# 循环10次接收数据_
  388. for i in range(10):
  389. m.SendSensorCMD(MasterClass.SENDVALUE_CMD)
  390. value = m.RecvSensorValue()
  391. datalist.append(value)
  392. indexlist = [count for count in range(len(datalist))]
  393. _# 写入数据_
  394. m.fileio.WriteFile(indexlist,datalist)
  395. m.fileio.CloseFile()

image

原文链接:https://www.cnblogs.com/FreakEmbedded/p/18310673

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号