[pyar] Consulta de matplotlib
Leonel Caraccioli
leonel en backupnet.com.ar
Mie Ene 21 00:01:18 ART 2015
Gente, buenas, hoy estuve probando para una conocida un graficador de
valores analógicos en python.
Es para la facultad de bioquimica de la UBA. Necesitan un adquisidor de
datos para un equipo de perfusión [1]. El equipo mide presiones y las
saca los valores analógicos de tensión.
El problema que tienen ahora es que necesitan mandar estos datos a una
PC para poder hacer unos cálculos.
Les propuse hacerlo con Arduino/Python. Empecé a probar algunas cosas, y
vi de usar matplotlib.
Anda lindo, adjunto el video [2]
Pero es lento, me carga el microprocesador mucho y les puse poco tiempo
de muestreo al Arduino, si le pongo más rápido la PC se empieza a
atrasar mucho y deja de ser en tiempo real que es lo que necesito para
tener un dalay (por supuesto acumulativo). No se como mejorarlo. Les
pego al final del correo el código.
La idea es arrancar con esto y empezar a probar más opciones y
agrandarlo (loguear, sacar derivadas, picos, etc.)
Alguien me puede dar un mano para ver si se puede hacer más rápida la
ejecución soy medio queso en python. También pensé en usar otra opción
no matplotlib.
El programa va a ser libre y estar en los repos de OpenMolo [3].
Saludos
Leonel
[1] -
http://es.wikipedia.org/wiki/Relaci%C3%B3n_ventilaci%C3%B3n_perfusi%C3%B3n
[2] - https://www.youtube.com/watch?v=5Yxf22UblQs
[3] - www.OpenMolo.com.ar
###########################################################
### Arduino:
###########################################################
// analog-plot
//
// Read analog values from A0 and A1 and print them to serial port.
//
// electronut.in
#include "Arduino.h"
void setup()
{
// initialize serial comms
Serial.begin(115200);
}
void loop()
{
// read A0
int val1 = analogRead(0);
// read A1
int val2 = analogRead(1);
// print to serial
byte b1, b2;
b1 = val1 & 0xFF;
b2 = ( val1 >> 8 ) & 0xFF;
Serial.write(b1);
Serial.write(b2);
b1 = val2 & 0xFF;
b2 = ( val2 >> 8 ) & 0xFF;
Serial.write(b1);
Serial.write(b2);
Serial.println();
// wait
delay(100);
}
###########################################################
### Python:
###########################################################
"""
ldr.py
Display analog data from Arduino using Python (matplotlib)
Author: Mahesh Venkitachalam
Website: electronut.in
"""
import sys, serial, argparse
import numpy as np
from time import sleep
from collections import deque
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# plot class
class AnalogPlot:
# constr
def __init__(self, strPort, maxLen):
# open serial port
self.ser = serial.Serial(strPort, 115200)
self.ax = deque([0.0]*maxLen)
self.ay = deque([0.0]*maxLen)
self.maxLen = maxLen
# add to 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])
# update plot
def update(self, frameNum, a0, a1):
try:
# line = self.ser.readline()
# data = [float(val) for val in line.split()]
data = [0,0];
b1 = ord(self.ser.read(1))
b2 = ord(self.ser.read(1))
data[0] = b1 + b2*256
b1 = ord(self.ser.read(1))
b2 = ord(self.ser.read(1))
data[1] = b1 + b2*256
line = self.ser.readline()
# print data
if(len(data) == 2):
self.add(data)
a0.set_data(range(self.maxLen), self.ax)
a1.set_data(range(self.maxLen), self.ay)
except KeyboardInterrupt:
print('exiting')
return a0,
# clean up
def close(self):
# close serial
self.ser.flush()
self.ser.close()
# main() function
def main():
# create parser
parser = argparse.ArgumentParser(description="LDR serial")
# add expected arguments
parser.add_argument('--port', dest='port', required=True)
# parse args
args = parser.parse_args()
#strPort = '/dev/tty.usbserial-A7006Yqh'
strPort = args.port
print('reading from serial port %s...' % strPort)
# plot parameters
analogPlot = AnalogPlot(strPort, 100)
print('plotting data...')
# set up animation
fig = plt.figure()
ax = plt.axes(xlim=(0, 100), ylim=(0, 1023))
a0, = ax.plot([], [])
a1, = ax.plot([], [])
anim = animation.FuncAnimation(fig, analogPlot.update,
fargs=(a0, a1),
interval=50)
# show plot
plt.show()
# clean up
analogPlot.close()
print('exiting.')
# call main
if __name__ == '__main__':
main()
More information about the pyar
mailing list