当前位置: 首页 > 知识库问答 >
问题:

使用Pyserial根据Arduino串行端口的电压绘制时间

钱弘壮
2023-03-14

如标题所示,我使用的是一个Arduino,它沿串行端口输出数据。它的产出如下:

120 1.23 170 2.54 210 2.32

左栏是以毫秒为单位的时间,右栏是0到5V之间的电压值。它们被一个空格隔开。编辑:似乎stackoverflow不允许我以表格形式打印,所以为了清楚起见,我有120个空间1.23\换行符170个空间2.54等等。我正在使用的Arduino草图:

#include <eHealth.h>


unsigned long time;
// The setup routine runs once when you press reset:
void setup() {
  Serial.begin(9600);  
}

// The loop routine runs over and over again forever:
void loop() {

  float ECG = eHealth.getECG();
  time = millis();
  Serial.print(time);
  Serial.print(" ");
  Serial.print(ECG, 3); 
  Serial.println(""); 


  delay(50);    // wait for 50 millisecond
}

现在在python方面,我尝试了几种不同的脚本来让它工作,但到目前为止都没有成功。我想根据电压值(右列)沿x轴(数据的左列)以毫秒为单位打印时间,并更新沿x轴的时间,使其随输入数据而变化。

我遇到的一段代码是这段代码,但它似乎更适合在同一个图形上绘制两段数据,这不是我想要的:

import sys, serial
import numpy as np
from time import sleep
from collections import deque
from matplotlib import pyplot as plt
import time


# class that holds analog data for N samples
class AnalogData:
  # constr
  def __init__(self, maxLen):
    self.ax = deque([0.0]*maxLen)       # maxLen = no. of samples?
    self.ay = deque([0.0]*maxLen)
    self.maxLen = maxLen

  # ring buffer
  def addToBuf(self, buf, val):
    if len(buf) < self.maxLen:
      buf.append(val)
    else:
      buf.pop()
      buf.appendleft(val)

  # add data
  def add(self, data):
    assert(len(data) == 2)
    self.addToBuf(self.ax, data[0])
    self.addToBuf(self.ay, data[1])

# plot class
class AnalogPlot:
  # constr
  def __init__(self, analogData):
    # set plot to animated
    plt.ion() 
    self.axline, = plt.plot(analogData.ax)
    self.ayline, = plt.plot(analogData.ay)
    plt.ylim([0,10])
   # update plot
  def update(self, analogData):
    self.axline.set_ydata(analogData.ax)
    self.ayline.set_ydata(analogData.ay)
    plt.draw()
def main():                           # main() function
  analogData = AnalogData(200)        # data range (maxLen)
  analogPlot = AnalogPlot(analogData)
  print 'plotting data...'
  # open serial port
  ser = serial.Serial('/dev/tty.usbmodem1411', 9600)
  blt = 0
  blot = []
  for i in range(5) : # total data points to plot
      line = ser.readline()
      data = [float(val) for val in line.split(" ")]
      blt = blt+1
      blot.append(float(val)) 
      #print blot
      print data
      if(len(data) == 2):
        analogData.add(data)
        analogPlot.update(analogData)     
  #close serial
  ser.flush()
  ser.close()
  time.sleep(1)
  plt.close("all")
  f=open("plot_store_1", "w")
  f.write("\n".join(str(x) for x in blot))
  plt.close("all")
# call main
if __name__ == '__main__':
  main()

理想情况下,我想要这样的输出:

http://2.bp.blogspot.com/-IoeJ2QN-3Y0/UqeA2ZTTe9I/AAAAAAAADZg/PEOAZaCnYj0/s1600/VID_20131210_211336.mp4

共有1个答案

唐修明
2023-03-14

这里有一个你如何做你想做的事情的例子,但是首先要注意:

  1. 在注释行中,您可以找到如何从串行端口获取真实数据的线索(因为我没有串行端口来测试它,您必须自己尝试……)
  2. 使用N可以控制最多要打印多少个点
  3. 使用refreshMillis可以控制绘图的刷新速率
  4. 您可以按原样运行代码并查看示例图

现在代码是:

from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg
import matplotlib.figure as mfig
import PyQt4.QtGui as gui, PyQt4.QtCore as core
import collections
import time
import random

#import serial
#ser = serial.Serial('/dev/tty.usbmodem1411', 9600)
#def get_line():
#    return ser.readline()

def get_line():
    x = time.time()%10000
    y = random.random() * 5
    return "%d %.3f\n" % (x,y)

refreshMillis = 300
N = 10
xs = collections.deque(maxlen=N)
ys = collections.deque(maxlen=N)

app = gui.QApplication([])

fig = mfig.Figure()
canvas = FigureCanvasQTAgg(fig)

ax = fig.add_subplot(111)
ax.set_ylim([0,5])
line2D, = ax.plot(xs,ys)
canvas.show()

def process_line():
    line = get_line()
    data = map(float,line.split(' '))
    xs.append(data[0])
    ys.append(data[1])
    line2D.set_data(xs,ys)
    xmin, xmax = min(xs),max(xs)
    if xmin == xmax:
        ax.set_xlim([xmin,xmin+1])
    else:
        ax.set_xlim([xmin,xmax])
    canvas.draw()

timer = core.QTimer()
timer.timeout.connect(process_line)
timer.start(refreshMillis)

app.exec_()

#ser.flush()
#ser.close()
 类似资料:
  • 我正在尝试构建一个代码,以便在我的代码和我的Arduino Uno之间进行通信。我有一个温度传感器(tmp36)连接到COM3中的Arduino板,我想实时绘制温度值。我还有一个开始按钮,用来开始获取数据并将其绘制在图形中,还有一个停止按钮用来停止这样做。当我运行代码时,我收到一条消息:“无法将字符串转换为float:b'Anal'”,参考第19行:“data=np.append(data,flo

  • 为了绘制一个地区的障碍物,我计划使用与Arduino Mega连接的夏普红外测距仪,然后尝试使用python和matplotlib在极地直方图类型地图上实时绘制。我对如何继续通过串行连接的Arduino和python接口有点困惑。 任何帮助都会很好。 谢谢

  • 问题内容: 我有一个Java程序,必须读取Arduino发送的信息。我从这里获取了Java代码。现在,我不太了解它是如何工作的,但是我尝试对其进行修改,并且得到了以下信息: 我创建一个对象串行COM口,我需要在主程序,然后我使用和当我需要它。 效果很好,Arduino获取数据并将其显示在LCD显示屏中。问题是。程序运行时,它会不断从串行端口读取数据(大约每40毫秒一次),但这并不意味着Arduin

  • 问题内容: 我想知道是否有一种方法可以通过PHP读取我的串行端口-可行:-) 在练习Arduino技能时,我开发了一个简单的LED ON / OFF草图。通过在串行监视器中 打开 或 关闭 它可以工作。 下一步,我整理了一个网页,充当GUI界面,以单击链接并执行上面的打开和关闭功能。该基于Web的GUI可通过PHP使用。我正在使用PHP SERIAL 类与Arduino使用的串行端口进行交互。 问

  • 我想知道是否有一种方法可以通过PHP来完成对串行端口的读取——有效:—— 在练习Arduino技能时,我设计了一个简单的LED开关示意图。它通过在串行监视器中输入on或off来工作。 下一步,我把一个网页放在一起,作为一个GUI界面,点击一个链接并执行上面的开关功能。这个基于网络的GUI通过PHP工作。我使用PHP串行类与Arduino使用的串行端口进行交互。 问题是我需要找到一种从串口获取反馈的

  • 我有一个UBlox接收器连接到我的电脑,我试图阅读它使用PySerial,但我是新的python,希望得到一些澄清/帮助了解数据。 我的代码如下所示: 我在文件中得到什么,当我打印msg的“类型”时,它是一个列表: \x3\x3\x10 10 10 10 10 10 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0