domingo, 20 de noviembre de 2016

Depuración gráfica en arduino con ESP8266 Witty Linux y SciDavis

Programar en Arduino es sencillo,  depurar los programas que hacemos en busca de errores ya no lo es tanto. Al contrario que en otros entornos de programación no disponemos de herramientas de depuración paso a paso ni de puntos de ruptura. En muchas ocasiones es complicado saber qué está pasando exactamente dentro de ese pequeño objeto al que tenemos un acceso bastante limitado.
La única herramienta que tenemos para visualizar como se está comportando nuestro programa es la escritura en el puerto de comunicaciones. Con la clase Serial podemos escribir la información que nos parezca significativa y ver esa información en la consola del IDE de Arduino. El problema es que esa información a veces es muy difícil de interpretar , sea porque varía muy rápido  en el tiempo y no podemos leerla sea porque el valor que queremos examinar depende a su vez de otro sensor  u otros y no es fácil ver como se relacionan. Esto ocurre sobre todo cuando hemos cometido un error a la hora de conectar, diseñar el circuito o programar el sketch.
Sin embargo, hay una manera de depurar gráficamente los valores de nuestros sensores y variables de una manera relativamente sencilla. Lo vamos a ver con un ejemplo muy simple y bastante tonto, pero que servirá para el caso. Usaremos, como no, nuestro pequeño Witty que trae de serie incorporados ya una fotoresistencia y un botón los cuales vamos a utilizar para el ejemplo.

A continuación vemos un programa que utiliza el puerto serie para volcar los valores significativos y poder visualizar desde la consola qué es lo que está ocurriendo dentro del microcontrolador.


int PHOTO_R = A0;
int BUTTON = 4;

void setup(){
  Serial.begin(115200);

  pinMode(PHOTO_R,INPUT);
  pinMode(BUTTON,INPUT);
   
}

void loop(){
  
    //Photoresistence read and print
    int photoResistence = analogRead(PHOTO_R);
    Serial.print(photoResistence);
    Serial.print("-");

    //Button read and print
    int buttonVal = digitalRead(BUTTON);
    Serial.print(buttonVal);
    Serial.print("-");

    //Calculated value and print
    int calc = photoResistence / ((buttonVal + 1) * 2);
    Serial.printĺn(calc);
    
    delay(100);
    
}

El programa lee el valor de la fotoresistencia, (posibles valores entre 0 y 1024) y lo envía al puerto serie.  Posteriormente envía también un guión con objeto de separar este dato del siguiente. A continuación se realiza la lectura del botón (posibles valores entre 0 y 1, pulsado y sin pulsar respectivamente) El valor se envía al puerto serie e inmediatamente se envía también un guión separador. Por último se realiza un cálculo cuyo valor dependerá del valor de la fotoresistencia y si se encuentra o no pulsado el botón. Al igual que los anteriores se envía al puerto serie. Este programa producirá la siguiente salida ( He tapado la fotoresistencia y pulsado el botón durante la ejecución para hacer variar los valores).

1024-1-256
1024-1-256
1024-1-256
1024-1-256
1024-1-256
1024-1-256
1024-1-256
1024-1-256
1024-1-256
574-1-143
364-1-91
350-1-87
354-1-88
435-1-108
947-1-236
906-1-226
388-1-97
367-1-91
557-1-139
779-1-194
940-1-235
934-1-233
738-1-184
509-1-127
458-1-114
435-1-108
428-1-107
421-1-105
422-1-105
430-1-107
1024-1-256
1024-1-256
909-1-227
649-1-162
618-1-154
881-1-220
629-0-314
797-0-398
910-0-455
635-0-317
1024-0-512
752-0-376

Gracias a que hemos puesto un retardo al final del loop, podemos leer la salida, de lo contrario veríamos pasar los numeros a toda velocidad y sin posibilidad de leerlos. Aún así tampoco es fácil interpretar lo que está pasando. Vamos a intentar mejorarlo realizando unas modificaciones en el programa.

Modifica el separador (aunque podríamos dejarlo, como está, la verdad) y añade los milisegundos de ejecución a la salida por el puerto serie. También disminuye el tiempo de retardo para aumentar el número de muestras. Se podría eliminar el retardo si queremos la máxima resolución. El valor del botón lo multiplicamos por 1024 para que pueda tomar dos valores 0 y 1024 que serán más fáciles de observar después.

int PHOTO_R = A0;
int BUTTON = 4;

void setup(){
  Serial.begin(115200);

  pinMode(PHOTO_R,INPUT);
  pinMode(BUTTON,INPUT);
   
}

void loop(){
  
    //Photoresistence read and print
    int photoResistence = analogRead(PHOTO_R);
    Serial.print(photoResistence);
    Serial.print(";");

    //Button read and print
    int buttonVal = digitalRead(BUTTON);
    Serial.print(buttonVal * 1024);
    Serial.print(";");

    //Calculated value and print
    int calc = photoResistence / ((buttonVal + 1) * 2);
    Serial.print(calc);
    Serial.print(";");

    //Time in milliseconds
    Serial.println(millis());

    delay(10);
    
}

Instala el programa cu si no lo tienes instalado. En Debian / Ubuntu sería:

apt-get install cu

Ahora crea este script con el nombre dump0.sh y  dale permisos de ejecución:

#!/bin/bash
cu -l /dev/ttyUSB0 -s 115200
cat </dev/ttyUSB0

Con el squetch subido al Witty y en ejecución, desde una consola en linux ejecuta:

./dump0.sh > data.csv

Pulsa el botón, pasa la mano por delante de la fotoresistencia, es decir prueba el circuito durante unos segundos. Para finalizar cierra el terminal. Habrás generado el fichero data.csv con todos los datos de la ejecución.

Instala el programa SciDavis. Si lo quieres instalar desde los repositorios de Debian / Ubuntu sería:

sudo apt-get install scidavis

Arranca el programa y ejecuta la opción Archivo -> Importar ASCII



Selecciona el fichero data.csv desde el sistema de ficheros y elige el punto y coma como separador.



Se importarán los datos en una tabla. Haz  click con el botón derecho del ratón en las columnas y sustituye los números por nombres significativos desde la opción editar. Asegúrate que las columnas 1,2 y 3 tienen asignado en la gráfica el eje Y de ordenadas y la columna 4 el eje X de abcisas.



Pulsando en la tecla control, pincha en las cabeceras de las cuatro columnas. Deberían que dar todas seleccionadas. Hecho esto seleccionar la opción de menú Gráfica -> Línea.


Deberíamos ver una gráfica similar a esta:


Ahora podemos entender mejor como están evolucionando los valores de nuestro circuito en el tiempo. También es posible realizar un zoom muy rápido y detallado en la zona de la gráfica que nos interese así como saber exactamente qué valores está tomando un punto de la gráfica si utilizamos la herramienta correspondiente. Evidentemente podríamos utilizar cualquier otro programa para representar la gráfica, una hoja de cálculo, por ejemplo, que importan directamente los ficheros con formato csv. El motivo de usar este programa es que está pensado específicamente para el análisis de datos, es muy rápido, maneja bien volúmenes altos de datos, de código abierto, permite realizar zoom sobre áreas muy pequeñas, etc.
Pues esto es todo, espero que os haya servido, y vosotros ¿cómo depuráis? Si tenéis alguna manera diferente de hacerlo por favor, dejadlo en los comentarios.

Acceso al código y ficheros en GitHub:

No hay comentarios:

Publicar un comentario