[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