Code Monkey home page Code Monkey logo

arduscope's Introduction

Arduscopio

Arduscopio es una interfaz Arduino-Python desarrollada para la adquisición de datos analógicos. El comportamiento de la interfaz imita algunas características propias de un osciloscopio, tales como la funcionalidad de Trigger y el cambio de escala temporal.

Arduscopio surge como una iniciativa para facilitar la adquisición de datos en la materia Laboratorio 3 del Departamento de Física de la Facultad de Ciencias Exactas y Naturales de la UBA.

Screenshot

Instalación

Python

El paquete puede ser instalado utilizando PIP:

pip install arduscope

El paquete instala las siguientes dependencias en caso de no encontrarse presentes:

  • Numpy
  • Matplotlib
  • PySerial

Arduino

El código de Arduino puede ser descargado desde el repositorio del proyecto.

Click derecho en este link -> Guardar como

Debe ser cargado en una Arduino UNO (excluyente). Ninguna fracción del código fue pensada para ser compatible con otra placa. Cualquier funcionamiento del código fuera de Arduino UNO es mera coincidencia.

Ejemplo de uso

Los elementos centrales del paquete son el objeto Arduscope (la interfaz entre Python y el Arduino) y el objeto ArduscopeScreen (un contenedor para los resultados adquiridos)

En primer lugar debemos importar estas clases del paquete que instalamos:

from arduscope import Arduscope, ArduscopeScreen

Luego podemos crear una instancia del Arduscopio, indicando el puerto de conexión. Nos conviene utilizar el contexto with ... as para no olvidarnos de cerrar el puerto.

Arduino IDE nos muestra el nombre del puerto en la esquina inferior derecha.

En Windows los puertos suelen llamarse "COM1", "COM2", etc. En Linux el formato suele ser "/dev/ttyUSB0" o parecido.

with Arduscope(port='/dev/ttyUSB0') as arduino:

El objeto que instanciamos bajo el nombre arduino (podría ser cualquier otro) tiene una serie de propiedades y métodos.

La lógica general es que las propiedades se configuren primero y luego se active la adquisición.

Si el usuario olvida detener la adquisición y cambia una propiedad la adquisición se detiene y reanuda automáticamente.

  arduino.frequency = 2000        # Frecuencia de adquisición (en Hz)
  arduino.pulse_width = 0.05      # Ancho del pulso digital (en Segundos)
  arduino.trigger_value = 2.5     # Valor del trigger (en Volts)
  arduino.amplitude = 5.0         # Amplitud de la señal (en Volts)
  arduino.n_channels = 2          # Cantidad de canales (1 a 6)
  arduino.trigger_channel = "A0"  # Canal/Modo de trigger (ver apartado)
  arduino.trigger_offset = 0.0    # Offset del trigger (en fracción de pantalla)

Para comenzar la adquisición se utiliza el método start_acquire().

La misma puede ser detenida mediante stop_acquire().

Estos métodos no detienen la ejecución principal del programa.

El método live_plot() abre un gráfico de Matplotlib y actualiza su contenido para cada nueva pantalla. Requiere que el modo ventana de Matplotlib se encuentre activo.

Hasta que el gráfico no es cerrado la ejecución principal se detiene, generando un momento para que el usuario vea los datos en tiempo real y decida si quiere continuar con su script o detenerlo.

  arduino.start_acquire()
  arduino.live_plot()

A continuación podemos trabajar con los datos adquiridos.

En primer lugar conviene asegurar que fueron adquiridas la cantidad de pantallas que necesitamos. Para eso podemos usar la función wait_until(n_screens, timeout).

Esta función detiene la ejecución principal hasta que el buffer de pantallas tenga n_screens almacenadas. También podemos pasarle un parámetro opcional de timeout para que se produzca un error por tiempo límite (en segundos).

Si la cantidad de pantallas ya fue alcanzada al llamar esta función el resultado será inmediato. También podriamos detener la adquisición para que el buffer deje de sobreescribirse.

  arduino.wait_until(n_screens=50, timeout=None)

Podemos acceder al buffer mediante la propiedad screens. Este buffer es un objeto de tipo deque pero a efectos de lectura podemos tratarlo como una lista común de Python.

Cada elemento en el buffer es un objeto de tipo ArduscopeScreen, nuestro contenedor de resultados. Si queremos trabajar con la última pantalla podemos acceder a ella utilizando un índice negativo:

screen = arduino.screens[-1]

Este objeto contiene todas las propiedades del Arduscopio al momento de la adquisición. Podemos consultar la frecuencia o el valor del trigger (por ejemplo).

También tiene un vector x generado a partir de la frecuencia que corresponde al eje temporal. Los canales quedan almacenados en una lista dentro de la propiedad channels.

Podriamos graficar del siguiente modo:

fig, ax = plt.subplots(1, 1, figsize=(8, 6))
ax.plot(screen.x, screen.channels[0], label='a0')
ax.plot(screen.x, screen.channels[1], label='a1')
ax.set_title(f"Trigger: {screen.trigger_value}")
plt.show()

Finalmente podríamos querer almacenar una medicin en un archivo. El objeto screen provee un metodo save para facilitar esta tarea. El formato se decide en base a la extensión del archivo creado:

screen.save("data.csv")   # Formato CSV (separado por comas)
screen.save("data.npz")   # Formato NPZ (array comprimido de Numpy)
screen.save("data.json")  # Formato JSON (objeto de JavaScript)

Para recuperar una pantalla guardada vamos a crear un nuevo objeto ArduscopeScreen del siguiente modo:

screen = ArduscopeScreen.load("data.csv")

Ejemplo completo

import matplotlib.pyplot as plt
from arduscope import Arduscope, ArduscopeScreen

with Arduscope(port='/dev/ttyUSB0') as arduino:
    arduino.frequency = 2000
    arduino.pulse_width = 0.05
    arduino.trigger_value = 2.5
    arduino.amplitude = 5.0
    arduino.n_channels = 2
    arduino.trigger_channel = "A0"
    arduino.trigger_offset = 0.0
    
    arduino.start_acquire()
    arduino.live_plot()

    arduino.wait_until(n_screens=50, timeout=None)

screen = arduino.screens[-1]

fig, ax = plt.subplots(1, 1, figsize=(8, 6))
ax.plot(screen.x, screen.channels[0], label='a0')
ax.plot(screen.x, screen.channels[1], label='a1')
ax.set_title(f"Trigger: {screen.trigger_value}")
plt.show()

screen.save("data.csv")   # Formato CSV (separado por comas)
screen.save("data.npz")   # Formato NPZ (array comprimido de Numpy)
screen.save("data.json")  # Formato JSON (objeto de JavaScript)

# screen = ArduscopeScreen.load("data.csv")

arduscope's People

Contributors

alemazzeo avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.