Python 使用pyserial解析int值并绘制直方图
我在这段代码上已经工作了几个小时,由于我缺乏python知识,所以我没有走多远。我有大量来自Arduino的数据。(下面是串行数据示例) 正如你所看到的,开头有“垃圾”。以下是我迄今为止的代码:Python 使用pyserial解析int值并绘制直方图,python,matplotlib,arduino,serial-port,Python,Matplotlib,Arduino,Serial Port,我在这段代码上已经工作了几个小时,由于我缺乏python知识,所以我没有走多远。我有大量来自Arduino的数据。(下面是串行数据示例) 正如你所看到的,开头有“垃圾”。以下是我迄今为止的代码: import serial import matplotlib.pyplot as plt import numpy as np import time serialArduino = serial.Serial('/dev/ttyUSB0', 9600, timeout=3) plt.ion()
import serial
import matplotlib.pyplot as plt
import numpy as np
import time
serialArduino = serial.Serial('/dev/ttyUSB0', 9600, timeout=3)
plt.ion()
cnt=0
ydata = [0] * 290
line, = plt.plot(ydata)
plt.ylim([0,1000])
while True:
bytesToRead = serialArduino.inWaiting()
valueRead = serialArduino.readline().rstrip()
try:
list = int(valueRead)
except ValueError as e:
list = 0 # ????
# mylist = list.partition("\n")[0]
if list <=1000:
ydata.append(list)
del ydata[0]
line.set_xdata(np.arange(len(ydata)))
line.set_ydata(ydata)
plt.axis([ 0, 288 , 0, 1000])
binBoundaries = np.linspace(0, 288, 1.77)
plt.show()
time.sleep(1)
注意:我只关注从Arduino获取数据点列表的问题。我认为如何绘制这些数据应该是一个完全不同的问题,特别是如果你想在现场进行的话。(在这方面,关于StackOverflow,这里已经有几个问题涉及这个问题,例如,请参阅和)
这是我在现场发现的,没有任何测试:
#/usr/bin/env python2.7
导入序列号
将matplotlib.pyplot作为plt导入
将numpy作为np导入
导入时间
原始缓冲区=“”
ydata=[]
ydata_已更改=错误
ser=serial.serial('/dev/ttyUSB0',9600,超时=None)
#没有超时!
尽管如此:
#只读可用数据
waiting=ser.inWaiting()
如果等待>0:
#将新数据附加到传入缓冲区,删除“垃圾”
原始缓冲区=原始缓冲区+\
ser.read(waiting).replace('\x00','').replace('\n','')
#注意“部分”数字
#(例如,原始缓冲区='…,171,16',其中'16'
#应为“162”,但额外的“2”为
#仍在输入缓冲区中等待
idx=raw_buffer.rfind(','))
原始数据=原始缓冲区[0:idx]
原始缓冲区=原始缓冲区[idx+1:]
#获取新值列表并安全存储
原始列表=映射(λx:int(x)\
过滤器(λx:x!='',原始数据。拆分(','))
如果len(原始列表)>0:
扩展(原始列表)
ydata_已更改=真
如果ydata_发生变化:
ydata_已更改=错误
打印“新数据:”+str(ydata)
#用ydata做点什么
时间。睡眠(1)
代码有内联注释,否则应该是自解释的。请注意,此代码将永远运行,每次以某种方式扩展时,都会打印ydata
的完整内容
最后,让我添加一个观察:plt.show()
是一个阻塞调用,因此如果在循环中插入该指令,则在关闭图形之前将无法解析新数据。您可能希望:
- 将任意阈值设置为
,然后中断循环并打印内容len(ydata)
- 在两个不同但通信的线程上执行串行读取和打印
这是我在现场发现的,没有任何测试:
!/usr/bin/env python2.7
导入序列号
将matplotlib.pyplot作为plt导入
将numpy作为np导入
导入时间
原始缓冲区=“”
ydata=[]
ydata_已更改=错误
ser=serial.serial('/dev/ttyUSB0',9600,超时=None)
#没有超时!
尽管如此:
#只读可用数据
waiting=ser.inWaiting()
如果等待>0:
#将新数据附加到传入缓冲区,删除“垃圾”
原始缓冲区=原始缓冲区+\
ser.read(waiting).replace('\x00','').replace('\n','')
#注意“部分”数字
#(例如,原始缓冲区='…,171,16',其中'16'
#应为“162”,但额外的“2”为
#仍在输入缓冲区中等待
idx=raw_buffer.rfind(','))
原始数据=原始缓冲区[0:idx]
原始缓冲区=原始缓冲区[idx+1:]
#获取新值列表并安全存储
原始列表=映射(λx:int(x)\
过滤器(λx:x!='',原始数据。拆分(','))
如果len(原始列表)>0:
扩展(原始列表)
ydata_已更改=真
如果ydata_发生变化:
ydata_已更改=错误
打印“新数据:”+str(ydata)
#用ydata做点什么
时间。睡眠(1)
代码有内联注释,否则应该是自解释的。请注意,此代码将永远运行,每次以某种方式扩展时,都会打印ydata
的完整内容
最后,让我添加一个观察:plt.show()
是一个阻塞调用,因此如果在循环中插入该指令,则在关闭图形之前将无法解析新数据。您可能希望:
- 将任意阈值设置为
,然后中断循环并打印内容len(ydata)
- 在两个不同但通信的线程上执行串行读取和打印
导入re
,然后使用re.sub(“[^0-9a-zA-Z,]+”,'',raw_serial)
,其中raw_serial=ser.read(waiting)
。然而,这有点残酷,因为我不知道发生了什么
import serial
import matplotlib.pyplot as plt
import numpy as np
import time
serialArduino = serial.Serial('/dev/ttyUSB0', 9600, timeout=3)
plt.ion()
cnt=0
ydata = [0] * 290
line, = plt.plot(ydata)
plt.ylim([0,1000])
while True:
bytesToRead = serialArduino.inWaiting()
valueRead = serialArduino.readline().rstrip()
try:
list = int(valueRead)
except ValueError as e:
list = 0 # ????
# mylist = list.partition("\n")[0]
if list <=1000:
ydata.append(list)
del ydata[0]
line.set_xdata(np.arange(len(ydata)))
line.set_ydata(ydata)
plt.axis([ 0, 288 , 0, 1000])
binBoundaries = np.linspace(0, 288, 1.77)
plt.show()
time.sleep(1)
/*
* 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);
}