用pyserial解析int值并绘制直方图

2024-04-26 03:48:28 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经花了好几个小时来编写这段代码,由于缺乏python知识,我还没有走多远。我有大量的数据来自Arduino。(下面是串行数据示例)

'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00171,170,171,171,171,172,171,171,172,171,170,168,169,170,170,170,168,170,171,170,170,170,170,170,171,170,170,170,169,169,169,170,169,168,168,167,168,168,169,167,168,168,168,168,168,167,167,168,169,168,169,169,168,169,167,167,167,167,167,166,167,167,167,167,166,167,167,166,166,167,167,167,167,167,166,166,167,166,166,166,166,166,166,165,166,166,166,165,166,165,166,166,165,166,166,166,165,165,166,165,165,165,165,165,166,166,165,165,165,165,166,165,165,165,165,165,165,165,165,166,166,165,165,165,162,167,165,166,166,165,164,167,166,165,165,165,164,166,165,164,164,164,165,165,164,165,164,164,164,164,164,164,165,164,164,164,164,164,164,163,164,164,164,163,164,164,164,164,164,164,164,163,164,164,164,164,163,164,164,164,163,164,164,163,163,163,163,163,163,164,163,163,163,163,163,163,163,163,163,164,163,163,163,163,163,163,162,163,163,163,163,162,163,163,163,163,163,163,163,163,163,163,163,163,163,162,163,162,162,163,162,163,162,162,162,162,163,163,162,162,162,162,162,163,162,163,163,162,163,162,162,162,162,162,163,162,162,160,162,162,163,162,162,162,165,163,162,162,162,162,162,162,162,162,162,161,162,161,162,162,162,161,161,162,161,161,161,161,\n'

正如你所看到的,一开始就有“垃圾”。以下是我目前为止的代码:

^{pr2}$

我最大的问题是去掉“垃圾”并将“好数字”从逗号中分离出来,这样它们就可以被解释为单独的数字(我甚至需要这样做吗?)。我想\n已经处理好了。我很感激你能给我的任何帮助、建议或链接。在

编辑:我贴的时候有些压痕弄乱了。还修改了一些代码。在

Arduino代码(Pro Tricket 5V/16MHz(FTDI))

    /*
 * Macro Definitions
 */
#define SPEC_TRG         A0
#define SPEC_ST          A1
#define SPEC_CLK         A2
#define SPEC_VIDEO       A3

#define SPEC_CHANNELS    288 // New Spec Channel
uint16_t data[SPEC_CHANNELS];

void setup(){

  //Set desired pins to OUTPUT
  pinMode(SPEC_CLK, OUTPUT);
  pinMode(SPEC_ST, OUTPUT);

  digitalWrite(SPEC_CLK, HIGH); // Set SPEC_CLK High
  digitalWrite(SPEC_ST, LOW); // Set SPEC_ST Low

  Serial.begin(9600); // Baud Rate set to 9600

}

/*
 * This functions reads spectrometer data from SPEC_VIDEO
 * Look at the Timing Chart in the Datasheet for more info
 */
void readSpectrometer(){

  int delayTime = 1; // delay time

  // Start clock cycle and set start pulse to signal start
  digitalWrite(SPEC_CLK, LOW);
  delayMicroseconds(delayTime);
  digitalWrite(SPEC_CLK, HIGH);
  delayMicroseconds(delayTime);
  digitalWrite(SPEC_CLK, LOW);
  digitalWrite(SPEC_ST, HIGH);
  delayMicroseconds(delayTime);

  //Sample for a period of time
  for(int i = 0; i < 3000; i++){

      digitalWrite(SPEC_CLK, HIGH);
      delayMicroseconds(delayTime);
      digitalWrite(SPEC_CLK, LOW);
      delayMicroseconds(delayTime); 

  }

  //Set SPEC_ST to low
  digitalWrite(SPEC_ST, LOW);

  //Sample for a period of time
  for(int i = 0; i < 85; i++){

      digitalWrite(SPEC_CLK, HIGH);
      delayMicroseconds(delayTime);
      digitalWrite(SPEC_CLK, LOW);
      delayMicroseconds(delayTime); 

  }

  //One more clock pulse before the actual read
  digitalWrite(SPEC_CLK, HIGH);
  delayMicroseconds(delayTime);
  digitalWrite(SPEC_CLK, LOW);
  delayMicroseconds(delayTime);

  //Read from SPEC_VIDEO
  for(int i = 0; i < SPEC_CHANNELS; i++){

      data[i] = analogRead(SPEC_VIDEO);

      digitalWrite(SPEC_CLK, HIGH);
      delayMicroseconds(delayTime);
      digitalWrite(SPEC_CLK, LOW);
      delayMicroseconds(delayTime);

  }

  //Set SPEC_ST to high
  //digitalWrite(SPEC_ST, HIGH);

  //Sample for a small amount of time
  for(int i = 0; i < 7; i++){

      digitalWrite(SPEC_CLK, HIGH);
      delayMicroseconds(delayTime);
      digitalWrite(SPEC_CLK, LOW);
      delayMicroseconds(delayTime);

  }

  digitalWrite(SPEC_CLK, HIGH);
  delayMicroseconds(delayTime);

}

/*
 * The function below prints out data to the terminal or 
 * processing plot
 */
void printData(){

  for (int i = 0; i < SPEC_CHANNELS; i++){
    Serial.print(data[i]);
    Serial.print(',');

  }

  Serial.print("\n");
}

void loop(){

  readSpectrometer();
  printData();
  delay(1000);  

}

Tags: tofordataintlowstspechigh
1条回答
网友
1楼 · 发布于 2024-04-26 03:48:28

注意:我只关注从Arduino获取数据点列表的问题。我认为如何绘制这些数据应该是一个完全不同的问题,尤其是如果你想实时绘制。(在这方面,StackOverflow上已经有几个问题涉及这个问题,例如,请参见thisthis


这是我在没有任何测试的情况下当场得出的结论:

#!/usr/bin/env python2.7

import serial
import matplotlib.pyplot as plt
import numpy as np
import time

raw_buffer = ''
ydata = []
ydata_changed = False
ser = serial.Serial('/dev/ttyUSB0', 9600, timeout=None)
                                          # no timeout!

while True:

    # read only available data
    waiting = ser.inWaiting()
    if waiting > 0:

        # append new data to incoming buffer, remove 'junk'
        raw_buffer = raw_buffer + \
                     ser.read(waiting).replace('\x00', '').replace('\n', '')

        # Take care of 'partial' numbers
        # (e.g. raw_buffer='...,171,16' where '16'
        # should be '162' but the extra '2' is
        # still waiting in the input buffer
        idx = raw_buffer.rfind(',')
        raw_data = raw_buffer[0:idx]
        raw_buffer = raw_buffer[idx + 1:]

        # get list of new values and store them safely
        raw_list = map(lambda x: int(x), \
                   filter(lambda x: x != '', raw_data.split(',')))

        if len(raw_list) > 0:
            ydata.extend(raw_list)
            ydata_changed = True

    if ydata_changed:
        ydata_changed = False
        print "New Data: " + str(ydata)

        # do something with ydata

    time.sleep(1)

代码有内联注释,否则应该是自解释的。请注意,此代码将永远运行,每次以某种方式扩展时,都会打印ydata的全部内容。在

最后,让我添加一个观察结果:plt.show()是一个阻塞调用,因此如果在循环中插入该指令,则在关闭图形之前,您将无法解析新数据。您可能希望:

  • 将任意阈值设置为len(ydata),之后您将脱离循环并绘制内容
  • 在两个不同但通信的线程上执行串行读取和绘图

相关问题 更多 >