Data Logger Shield
Material requerido.
Arduino UNO o equivalente. | |
Un Data logger shield. | |
Un Sensor de temperatura y humedad DHT11, | |
Un porta pilas. |
Este tutorial es poco mas que una traducción de la excelente presentación que de este shield hacen en la página Adafruit Data Logging Shield
Registrando datos
Hay muchas veces, que cuando estás trabajándote un proyecto, tienes una serie de ideas de cómo hacerlo y de que datos necesitas para ponerlo en marcha. Haces un diseño previo y comienzas a trabajar sobre las condiciones en las que ciertos controles deben ejecutarse o ciertas alarmas dispararse.
El problema de esto radica en que normalmente, aunque puedes tener una idea aproximada de cuáles son estos puntos de control, en la práctica los valores útiles de estos controles son muy borrosos porque aún no has construido el circuito, o porque no está mu claro que valores tomarán las variables en la realidad y porque como todo en la vida surge él depende.
Y cuando te encuentras en eta situación solo hay una salida valida. Recurrir al principio fundamental en el que se basa toda Técnica y toda la Ciencia: Tomar medidas reales para un estudio posterior.
La diferencia básica entre la ciencia y la filosofía es que la primera mide y la segunda razona con independencia de la realidad ( Con lo que el desvarío está garantizado en un porcentaje muy alto de los casos. Espero que no haya muchos filósofos leyendo esto) , y con mucha frecuencia tendemos a olvidar que es la ciencia y su empeño en medir la realidad la que nos ha traída hasta el mundo moderno… Arduinos incluidos.
Así que al final, hay que medir y tomar datos para su estudio posterior y poder afinar esos proyectos que dependen, precisamente, de los valores claves de las variables.
Y cuando llegas a esta situación, necesitas un sistema de registrar datos de campo, provenientes de diferentes sensores según el proyecto y normalmente que incluya un reloj de tiempo real RTC, para poder fechar el día y hora en que se registran esos valores.
En sesiones previas hemos visto que podemos comunicar nuestros Arduinos mediante Bluetooth, WIFI o RF con un portátil por ejemplo. Pero hay veces que tienes que tomar los datos en el monte o en un globo aerostático y no hay posibilidad de envió inmediato de datos al PC y por eso vamos a necesitar un sistema que nos permita registrar y guardar esos datos en local.
Ya vimos que Arduino dispone de algunos bytes de EEPROM para almacenar datos a prueba de apagones, pero su tamaño es muy limitado y no valdría para meses de captura de datos, por lo que en el mundo Arduino solemos recurrir a sistemas prácticos, como una tarjeta SD.
Estas tarjetas son pequeñas y adecuadas para guardar los datos registrados y además son muy baratas y de tamaños enormes más de 32 Gb en este momento por poco dinero y muy capaces de almacenar los datos recogidos durante años si hiciese falta.
A un sistema que incluya un reloj en tiempo real y un sistema de almacenamiento de los datos de sensores se le llama en ingles Data Logger o registro de datos en cristiano y vamos a dedicar esta sesión a presentar un shield así, y ver cómo utilizarlo en nuestros proyectos.
Arduino Data Logger Shield
Podemos conseguir independientemente un RTC y un Lector grabador de tarjetas SD discretos y hacer un pequeño montaje para disponer de un data Logger, pero como siempre, el mercado está atento a ver que nos puede vender y como no somos los primeros en tener este problema, nos ofrecen un sistema de lo mas resultón esto.
En Arduino disponemos del Data Logger Shield V1:
Es un shield cómodo con todo lo necesario integrado, Lector de tarjetas SD más RTC con su pila, un regulador de 3.3V para alimentar el grabador de SD (Que suele consumir un poco más de lo que el regulador de Arduino maneja con soltura) y además incluye un área de prototipos para que conectas tus sensores, de modo que puedas montar un sistema sencillo y sin cablecitos colgando.
Características del Data Logger Shield:
Usando el reloj de tiempo real
En una sesión anterior hablamos del Reloj de tiempo real o RTC basado en el chip 1307, y por eso vamos a pasar un poco por encima de algunas cosas que ya vimos allí, pero hagamos un repaso rápido (Para los vagos).
¿Por qué usar un reloj externo cunado Arduino tiene su propio reloj con millis ()?
Vale. En primer lugar porque el reloj interno cuenta mili segundos desde que Arduino arrancó y no tiene una referencia real con el tiempo universal (O sea la hora de tu reloj)
Podríamos a pesar de todo, ponerle en hora ese reloj y funcionaria correctamente… durante un tiempo, hasta que se reinicie a 0 al cabo de unos pocos días, porque tiene capacidad limitada, y además si por cualquier razón nuestro equipo se apagase volvería a contar el tiempo desde 0, lo que falsearía nuestros datos irrevocablemente.
El reloj interno de Arduino es muy útil para proyectos que requieren medir tiempos cortos, pero no toma de datos a largo plazo (más allá de unos días) y por eso surge este tipo de relojes con respaldo de batería. Para que puedan funcionar con una fecha y hora precisas durante años (Al menos 5, según el fabricante)
En el mismo shield incluye el porta baterías con lo que nos resuelve dos problemas al tiempo.
Como el RTC DS1307 es un reloj I2C, el shield se reserva los pines A4 y A5 para su manejo, y para programarlo vamos a usar la librería RTClib-master.
Empecemos con un ejemplo inicial para comprobar que el reloj funciona correctamente.
Probando el reloj RTC y la batería
Necesitas esta librería para el reloj RTClib-master. Baja la e instala la siguiendo el procedimiento habitual y después carga este programa. Prog_141_1
Si es la primera vez que usas el shield, la hora no estará fijada y veras algo así:
No te asustes por el mensaje que es normal. Tenemos que poner en hora el reloj y la forma más fácil es que busques esta línea:
//RTC.adjust(DateTime(__DATE__, __TIME__));
Y le quites el comentario. Esta instrucción hace que asigne al reloj la fecha y hora de la última compilación del sketch. Por eso si das al botón de compilar y cargar en tu Arduino IDE, pondrá la hora fácilmente sin que te compliques la vida.
Si abres la consola serie veras que te ha puesto el reloj con la hora de tu PC (Que espero que tengas debidamente ajustado):
Esta librería de tiempo es una nueva versión de aquella que usamos en la sesión del RTC y por eso vale la pena comentar que se ha simplificado y reescrito para mayor coherencia.
Básicamente una vez que el reloj está ajustado usamos now () para tomar la fecha y hora actual y ahora podemos usar diferentes propiedades:
DateTime now = RTC.now();
Propiedad | Devuelve un integer con |
---|---|
now.year() | el año |
now.month() | el mes |
now.day() | el día |
now.hour() | la hora |
now.minute | el minuto |
now.second() | el segundo |
now.unixtime() |
Devuelve un long con el formato time de unix, que es el valor de los segundos transcurridos desde el día 1 de enero de 1970 a las 00:00. Este valor nos permite hacer aritmética con horas y fechas fácilmente y lleva cuenta de años bisiestos y todo eso
|
Probado la tarjeta SD
Imagínate que queremos guardar la temperatura y la humedad de un secadero de chorizos (Por poner un ejemplo) con su fecha y hora Unix para su estudio posterior.
Usaríamos un long 32 bits para la fecha, más dos byte para temperatura y humedad. En total 6 bytes. Pongamos 10 para poder registrar otro par de valores de integers.
Si tomamos una muestra cada minuto, son 60 por hora y 1.440 muestras diarias. A 364 días por año suponen 524.160 muestras al año de 10 bytes. Es decir necesitamos 5 GBytes largos por año.
Hoy no es difícil conseguir tarjetas SD de 32 GB por 15€ con lo que podríamos almacenar sobre 6 años de datos sin pasar a leer la tarjeta. No está mal ¿No? Por eso las SDs se utilizan profusamente en Arduinos, Raspberrys y demás fauna de bajo coste. Son pequeñas, baratas y eficaces. No se puede pedir más.
En primer lugar aseguraros de vuestra tarjeta SD esta formateada en FAT16 o FAT32, porque la librería no reconoce otras cosas.
Necesitáis descargar e instalar la librería correspondiente sdfatlib, y ya estamos listos para probar. Carga el programa que encontrareis en:
\\Ejemplos\SD-Master\CardInfo
Es un programita que simplemente comprobara que tu tarjeta está correctamente insertada y formateada de modo reconocible. Obtendréis una salida similar a esto:
Básicamente os informa de que ve la SD, que esta formateada en FAT32 en mi caso, su tamaño y cosas así. Además como yo tenía algo más escrito en ella devuelve un listado de ficheros.
En realidad lo importante es que no te dé un mensaje como este:
Si os ocurre esto, comprobar si la tarjeta está bien insertada hasta el fondo, en la orientación adecuada y formateada en FAT16 o FAT32. Y no hay más, ya estamos listos para montar un programa que registre datos de cualquier tipo.
Programa de toma de datos
Vamos a usar un simple DHT11 como sensor de temperatura y humedad para tomar un par de valores típicos y guardarlos en la SD, y para ello vamos a usar un circuito atípico, por pura vagancia.
En la sesión anterior en la que hablamos del DHT11, os mostramos el circuito que cualquier profesor educado os pondrá en la pizarra, con su resistencia de Pull up y en su protoboard como Dios manda,
Pero es bastante molesto hacer esto porque no quiero usar una protoboard y cablecitos, a fin de poder mover por ahí el registrador de datos y tampoco quiero poner una resistencia o soldar nada en la zona de protoboard para no estropear un Shield nuevecito para algo tan sencillo.
Así que voy a hacer el circuito gamberro que funciona fetén y no da por el saco, pero negad públicamente que esto se puede hacer, que a las cátedras les puede dar un ataque de nervios si lo ven.
El circuito consiste simplemente en montar el DHT11 con sus pines directamente encajados en los pines hembras de nuestro shield de data Logging, mas o menos así:
Como no consume casi nada, es de lo más sencillo y ahora basta con definir como salidas los pines de alimentación y GND (Y poner el valor correspondiente antes de empezar) y después leer el pin central, en mi caso son los pines 7,6 y 5, pero fijaros en vuestro sensor que hay modelos de 4 pines en lugar de 3 y tendréis que adaptarlo.
Y en lugar de poner un resistencia de Pull Up, definimos ese pin (el 6 para mi) como INPUT_PULLUP y a otra cosa. Hagamos un programa de ejemplo para captar la idea: Prog_141_2
#include <DHT11.h> DHT11 dht11(6); void setup() { Serial.begin(9600); pinMode(5, OUTPUT) ; // DHT11 GND pinMode(7, OUTPUT) ; // DHT11 Vcc pinMode(6, INPUT_PULLUP) ; // DHT11 pin de lectura digitalWrite(7, HIGH) ; // Damos tension digitalWrite(5, LOW) ; delay (500); }
En las primeras líneas incluimos la librería correspondiente y definimos una instancia del sensor. Después defino los pines 5 y 7 como salidas para escribir en ellos un poco más abajo, LOW y HIGH de modo que den tensión al sensor.
El resto es para leer el sensor e imprimir sus valores:
void loop() { int err; float temp, hum; if((err = dht11.read(hum, temp)) == 0) // Si devuelve 0 es que ha leido bien { Serial.print("Temperatura: "); Serial.print(temp); Serial.print(" Humedad: "); Serial.print(hum); Serial.println(); } else { Serial.println(); Serial.print("Error Num :"); Serial.print(err); Serial.println(); } delay(1000); // Para solo leer una vez por segundo }
En la consola obtendréis una cosa como esta:
Así que ya tenemos listo el sensor para leer temperatura y humedad, además del reloj de tiempo real. Solo nos queda ver como utilizamos la tarjeta SD, y el tema no da para mucho.
Escribiendo en la tarjeta SD
Básicamente hay que incluir una llamada a SD_lib como siempre, e incluir un par de librerías para usarla. Aquí os dejo el programa completo Prog_141_3
#include <SD.h> #include <Wire.h> #include <SPI.h>
La librería usa SPI para comunicarse con el lector de SD, y el shield usa el pin digital 10 como chip Select
const int chipSelect = 10; // SD card pin select
Tenéis que definirlo como OUTPUT incluso si por lo que sea no vais a utilizarlo, para evitar cosas raras. Es conveniente definir algo así:
File logfile;
Donde File es un tipo de datos definido en la librería que contiene un Handler o puntero a la estructura en la tarjeta, y así ya tenemos definido uno para usarlo luego.
Para iniciar su uso, comprobamos que SD.begin() devuelve true, para asegurar de hay una SD insertada y que se puede leer y escribir en ella:
if (!SD.begin(chipSelect)) error("No hay tarjeta SD."); else Serial.println("Tarjeta SD inicializada.");
Ahora podemos fijar el nombre del fichero e intentar abrirlo:
char Filename = “Registro” ; logfile = SD.open(Filename, FILE_WRITE);
Y ahora ya podemos escribir en el fichero:
logfile.print("Time") ; logfile.print("Temperatura") ; logfile.println("Humedad") ;
Exactamente como a la puerta serie, pero va a un fichero de texto secuencial en la SD con el nombre elegido.
Por ultimo como los datos leídos ocupan poco, se van quedando en el buffer de salida hasta que a nuestro Arduino le dé por vaciarlos o porque le forcemos a ello con la instrucción flush():
now = RTC.now(); logfile.print(now.unixtime()); // seconds since 1/1/1970 logfile.print(", "); logfile.print(count); logfile.print(", "); logfile.print(temp); logfile.print(", "); logfile.println(hum); if ( count++ >64 ) // Este numero controla cada cuantas lecturas escribimos { // No escribais demasiado a menudo, darle al menos 64/128 logfile.flush(); // Para forzar la escritura en la SD count = 0 ; }
Y el tema no da para mucho más. Obtendréis una salida a consola si eco está en True, como esta
Tomando datos en el exterior
Vale hasta aqui todo muy bonito, pero teniamos enchufado nuestro shield y Arduino al USB y en el monte no hay de eso. ¿Como alimentamos un proyecto que aguante un tiempo donde no hay enchufes?
Pues solo hay una solucion barata: Baterias. Dependiendo de su numero y potencia, nuestro proyecto durara mas o menos recogiendo datos. Y el sistema mas sencillo es usar pilas vulgares y un portapilas.
Se enchufan al conector de Arduino y listo para una temporada de captura de datos, que soy incapaz de predecir cuanto puede ser eso. Aquí os dejo un mini vídeo con el resultado:
Como esto ya se ha alargado un poco más de lo normal, vamos a dejar para una nueva sesión la recogida y formateo de los datos, así como el presentarlos para su estudio.
En el próximo tuto veremos como recoger los datos y hacer por ejemplo un excel para ver como se han comportado los valores de los sensores.
Resumen de la sesión