As titled I am using an Arduino that outputs data along the serial port. It outputs as such:
120 1.23 170 2.54 210 2.32
The left column is time in milliseconds and the right column is a voltage value between 0 and 5V. The are separated by a space. EDIT: It appears stackoverflow won't let me print in tabular form, so to make it clear, I have 120 space 1.23 \newline 170 space 2.54 and so on. The Arduino sketch I am using:
#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
}
Now on the python end of things, I have tried a few different scripts to get it to work, but have been unsuccessful so far. I want to print the time in milliseconds along the x-axis (left column of data) against the voltage value (right column) and update the time along the x-axis so it is changing with the incoming data.
One of the pieces of code I have come across is this one, but this appears to be more suitable for plotting two pieces of data on the same graph, which is not what I want:
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()
Ideally I would want an output like this: