page contents

使用Python串口实时显示数据并绘图的例子(2)

四、通过多线程实现串口数据的实时绘图import pyqtgraph as pg 这里主要开了一个线程去处理串口,剩下的和上面内容一样。 代码: import arrayimport serialimport threadingimport numpy ...


四、通过多线程实现串口数据的实时绘图import pyqtgraph as pg

这里主要开了一个线程去处理串口,剩下的和上面内容一样。

代码:

  1. import array
  2. import serial
  3. import threading
  4. import numpy as np
  5. import time
  6.  
  7.  
  8. i = 0
  9. def Serial():
  10. while(True):
  11. n = mSerial.inWaiting()
  12. if(n):
  13. if data!=" ":
  14. dat = int.from_bytes(mSerial.readline(1),byteorder='little') # 格式转换
  15. n=0
  16. global i;
  17. if i < historyLength:
  18. data[i] = dat
  19. i = i+1
  20. else:
  21. data[:-1] = data[1:]
  22. data[i-1] = dat
  23.  
  24. def plotData():
  25. curve.setData(data)
  26.  
  27.  
  28. if __name__ == "__main__":
  29. app = pg.mkQApp() # 建立app
  30. win = pg.GraphicsWindow() # 建立窗口
  31. win.setWindowTitle(u'pyqtgraph逐点画波形图')
  32. win.resize(800, 500) # 小窗口大小
  33. data = array.array('i') # 可动态改变数组的大小,double型数组
  34. historyLength = 200 # 横坐标长度
  35. a = 0
  36. data=np.zeros(historyLength).__array__('d')#把数组长度定下来
  37. p = win.addPlot() # 把图p加入到窗口中
  38. p.showGrid(x=True, y=True) # 把X和Y的表格打开
  39. p.setRange(xRange=[0, historyLength], yRange=[0, 255], padding=0)
  40. p.setLabel(axis='left', text='y / V') # 靠左
  41. p.setLabel(axis='bottom', text='x / point')
  42. p.setTitle('semg') # 表格的名字
  43. curve = p.plot() # 绘制一个图形
  44. curve.setData(data)
  45. portx = 'COM24'
  46. bps = 19200
  47. # 串口执行到这已经打开 再用open命令会报错
  48. mSerial = serial.Serial(portx, int(bps))
  49. if (mSerial.isOpen()):
  50. print("open success")
  51. mSerial.write("hello".encode()) # 向端口些数据 字符串必须译码
  52. mSerial.flushInput() # 清空缓冲区
  53. else:
  54. print("open failed")
  55. serial.close() # 关闭端口
  56. th1 = threading.Thread(target=Serial)#目标函数一定不能带()被这个BUG搞了好久
  57. th1.start()
  58. timer = pg.QtCore.QTimer()
  59. timer.timeout.connect(plotData) # 定时刷新数据显示
  60. timer.start(50) # 多少ms调用一次
  61. app.exec_()

效果如图:


五、与下位机通讯实现波形实时监测

在这里与第四阶段基本相同,需要注意的是,如果收数据直接画图的话,波形会出现问题。所以串口传输数据时使用循环队列(先进先出),数据来之后先进队列,之后再定时器调用函数,出队列,更新图。

理论上刷新数据的时间需要大于下位机发送数据的间隔时间,否则队列会越来越大,而且图的刷新不连贯。再就是有一个小问题,因为正弦波有负值,我又没找到很好的把Byte转为char的方法,所以只能手动代码处理,先转成int类型,再把第八位(符号位)清零,得到绝对值。然后再取负,得到我们需要的数据。

但发现Python无法进行移位操作,python是int类型是无精度类型,不会发生溢出而进行截取的情况,所以只能先转为二进制在移位,太麻烦,这里直接通过减去一个数的方法来实现了。

代码:

  1. import pyqtgraph as pg
  2. import array
  3. import serial
  4. import threading
  5. import numpy as np
  6. from queue import Queue
  7. import time
  8.  
  9.  
  10. i = 0
  11. q = Queue(maxsize=0)
  12. def Serial():
  13. global i;
  14. global q;
  15. while(True):
  16. n = mSerial.inWaiting()
  17. if(n):
  18. dat = int.from_bytes(mSerial.readline(1),byteorder='little') # 格式转换
  19. if(dat>>7):
  20. dat =256-dat
  21. dat =0-dat
  22. q.put(dat)
  23.  
  24. def plotData():
  25. global i;
  26. if i < historyLength:
  27. data[i] = q.get()
  28. i = i+1
  29. else:
  30. data[:-1] = data[1:]
  31. data[i-1] = q.get()
  32. curve.setData(data)
  33.  
  34.  
  35. if __name__ == "__main__":
  36. app = pg.mkQApp() # 建立app
  37. win 
    • 发表于 2020-01-03 09:35
    • 阅读 ( 732 )
    • 分类:Python开发

你可能感兴趣的文章

相关问题

0 条评论

请先 登录 后评论
Pack
Pack

1135 篇文章

作家榜 »

  1. 轩辕小不懂 2403 文章
  2. 小柒 1470 文章
  3. Pack 1135 文章
  4. Nen 576 文章
  5. 王昭君 209 文章
  6. 文双 71 文章
  7. 小威 64 文章
  8. Cara 36 文章