Estación meteorológica WIFI. Arduino + ESP8266-01 + ThingsPeak.com | Software

Índice

  1. Estación meteorológica WIFI |Introducción
  2. Estación meteorológica WIFI | Hardware
  3. Estación meteorológica WIFI | Módulo ESP8266-01
  4. ⇒ Estación meteorológica WIFI | Software

Hemos llegado al último paso para construir y programar una estación meteorológica WIFI autónoma con ESP8266-01 + Arduino + ThingsPeak.com. En esta entrada vamos a analizar el software que cargaremos tanto en el módulo ESP8266-01 como en la placa Arduino.

 

Pero antes de comenzar con esto, me gustaría hablar de un sistema llamado Watchdog Timer, que usaremos más adelante y que puede ser muy útil para proyectos remotos.

Timers WatchDog

Watchdog timer, o perro guardián, es un sistema que permite reiniciar la electrónica de forma automática en caso de que esta se quede congelada. Este tipo de sistemas son imprescindibles en aplicaciones de larga duración como la que nos ocupa, debido a que es relativamente habitual que la placa Arduino se quede ‘congelada’ tras largos periodos de tiempo funcionando. Esto puede representar un problema grave, ya que, de no disponer de ningún sistema de reinicio automático, habría que hacerlo de forma manual, y esto no siempre es posible cuando se trata de aplicaciones remotas.

Watchdog Arduino

Para ello, Arduino cuenta con la librería avr/wdt.h:

#include <avr/wdt.h>

Es muy simple de utilizar, simplemente indicamos el tiempo máximo de espera al declarar la función. Si en el loop principal no se llama a la función wdt_reset() al menos una vez cada ese tiempo, la placa Arduino será automáticamente reiniciada:

wdt_enable(WDTO_8S);

Podemos llamar a esta función tantas veces como queramos, pero siempre dejando un intervalo entre llamadas menor al tiempo especificado al declararla. En caso de exceder este tiempo entre una llamada y la siguiente, el sistema entenderá que la placa Arduino ha quedado congelada en algún punto, y automáticamente la reinicia:

wdt_reset();

Es posible que esta función no funcione en vuestra placa Arduino si lleva instalado un bootloader muy antiguo. Haced alguna prueba siempre antes de nada y comprobar que la placa se reinicia pasado el tiempo especificado si no se llama a la función wdt_reset(). En caso de ver que no funciona, aquí os dejo un enlace donde se especifica como actualizar el bootloader a una versión más reciente (optiboot).

Además de la versión software, existen alternativas hardware que realizan esta función. Para proyectos remotos donde la inversión sea más cara, donde no es posible reiniciar la electrónica de forma manual (como este proyecto en el que estoy trabajando), recomiendo utilizar también esta opción y añadir otro watchdog redundante. Sería una verdadera faena perder todo el equipo por un incidente de bloqueo.  Este módulo reinicia automáticamente la electrónica si no recibe un impulso cada 1min.

Watchdog Arduino

Software Arduino

Os dejo el software para cargar en la placa Arduino. Os dejo también las librerías necesarias:

Software Arduino

La estructura de ejecución principal se muestra a continuación. El sistema sale cada 5 minutos (parametrizable) del modo ahorro de energía, realiza lecturas de todos los sensores, conecta el MOSFET para activar el módulo ESP8266-01 y envía las variables por el canal serie. Siempre después de cada función, se llama a la función wdt_reset() para resetear el contador del watchdog timer:

void loop() {
  HacerLecturas();                  wdt_reset();
  if (oledON == 1)pantallaON();     wdt_reset();
  if (interrupt == 0)envioWIFI();   wdt_reset();
  if (visu == 1)plotCanalSerie();   wdt_reset();
  ModoAhorro();                     wdt_reset();
}

Existen otra serie de condiciones, como la rutina de visualización de las variables en la pantalla OLED, que se activa a través de un botón que a la vez activa una interrupción, sacando el sistema del modo ‘ahorro de energía’ y visualizando las variables en la pantalla. En caso de activar esta rutina, el sistema no activa el MOSFET de encendido del módulo ESP8266-01 para evitar sincronizar los valores con la web ThingsPeak.com cada vez que utilizamos la pantalla (recordad que el consumo de corriente de este módulo es muy elevado). La sincronización se hace periódicamente según el tiempo establecido como veremos a continuación.

Las lecturas de los sensores se hacen en el apartado HacerLecturas() utilizando las librerías que os dejo en la carpeta del enlace.

Cabe mencionar que el sensor debido al bajo consumo del sensor DHT11, he decidido utilizar la salida digital D7 de la propia placa Arduino para alimentarlo, de forma que solo alimentaremos el sensor cuando sea necesario. Por otro lado, la lectura de la tensión de batería se realiza 50 veces y se calcula la media para obtener una lectura precisa: 

void HacerLecturas() {
  digitalWrite(7, HIGH);   // Alimentar DHT11
  delay(20);
  bmp.setSampling(Adafruit_BMP280::MODE_NORMAL,     /* Operating Mode. */
                  Adafruit_BMP280::SAMPLING_X2,     /* Temp. oversampling */
                  Adafruit_BMP280::SAMPLING_X16,    /* Pressure oversampling */
                  Adafruit_BMP280::FILTER_X16,      /* Filtering. */
                  Adafruit_BMP280::STANDBY_MS_500); /* Standby time. */
  delay(2500);

  presion_BMP280 = bmp.readPressure();  // Leer presion atmosferica
  temp_BMP280    = bmp.readTemperature();  // Leer temperatura BMP280
  dht11.read(humedad_DHT11, temp_DHT11);  // Leer humedad
  Vbat_for = 0;
  for (int i = 0; i <= 49; i++) {  // Leer tension de bateria
    Vbat = analogRead(A1) * 4.11 / 1023.00;
    Vbat_for += Vbat;
    delay(20);
  }
}

Para poner el sistema en modo ‘ahorro de energía’ utilizaremos la librería «LowPower.h» y la llamaremos cada vez que queramos activar este modo utilizando la función LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF). De esta forma, activamos el modo bajo consumo durante 8 segundos (periodo máximo permitido por la librería y con un bucle for extendemos este periodo al tiempo, en este caso 8s x 38 = 304s (5 minutos):

attachInterrupt(digitalPinToInterrupt(2), wakeUp, LOW);
  for (int i = 0; i <= 37; i++) {
    LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
    if (interrupt == 1) break;
  }
detachInterrupt(digitalPinToInterrupt(2));

Conviene también realizar las dos pequeñas modificaciones hardware que menciono en esta entrada para reducir aun mas el consumo, ¡hasta solo 90uA!

Las interrupciones hadware asociadas a la rutina de visualización en la pantalla OLED solo estarán disponibles en el modo bajo consumo, fuera de este modo, es decir, o bien mientras se hacen las lecturas de los sensores o cuando estas se envían por canal serie al ESP8266-01, las interrupciones permanecen desactivadas para evitar errores.

detachInterrupt(digitalPinToInterrupt(2));

El envío de las variables por el canal serie desde la placa Arduino se hace a través de los pines D10 y D11 utilizando la librería SoftwareSerial.h:

#include <SoftwareSerial.h> 
SoftwareSerial ESPSerial(10, 11); // RX, TX

Para enviar las lecturas, primero se agrupan dentro de variable variables data[], y finalmente se envían por canal serie:

data[0] = temp_BMP280;
data[1] = temp_DHT11;
data[2] = humedad_DHT11;
data[3] = 0.00750064 * presion_BMP280;
data[4] = Vbat;

Antes de enviarlas, se activa la salida digital 5 para activar el MOSFET y encender el módulo ESP8266-01:

digitalWrite(5, HIGH); // Encender ESP8266-01
delay(1000);

ESPSerial.write((byte*)data, LengthData * sizeof(data[0]));

Una vez enviadas las lecturas de los sensores, la placa Ardunio permanece a la escucha de canal serie hasta recibir el diagnóstico desde el módulo ESP8266-01. Si recibimos un 200, la sincronización con la web ThingsPeak.com habrá sido correcta:

if (ESPSerial.available()) {
    ESP_Status = ESPSerial.parseInt();
    if (ESP_Status != 200) ESPenvio_Error++;
    else ESPenvio_Error = 0;
}

También he añadido una rutina para visualizar las lecturas de los sensores por el canal serie. 

Software ESP8266-01

Si no habéis leído la entrada dedicada al módulo ESP8266-01, recomiendo acudir primero a esta entrada. En ella hemos visto como alimentar y cablear el módulo de forma correcta y los problemas mas comunes:

Podéis descargar el software para cargar en el módulo ESP8266-01 en este enlace. Os dejo también las librerías necesarias:

Software ESP8266-01

En primer lugar, importante actualizar estos parámetros con los vuestros de vuestra red WIFI y canal de ThingsPeak.com:

#define SECRET_SSID "xxx"         // replace MySSID with your WiFi network name
#define SECRET_PASS "xxx"         // replace MyPassword with your WiFi password
#define SECRET_CH_ID xxx          // replace 0000000 with your channel number
#define SECRET_WRITE_APIKEY "xxx" // replace XYZ with your channel write API Key

Recordad que hemos instalado un MOSFET de desconexión para ahorrar energía y evitar que el módulo ESP8266-01 esté continuamente consumiendo energía, por lo que el módulo estará apagado hasta que desde la placa Arduino se active el MOSFET y se alimente el módulo WIFI.

La conexión a la red domestica se hace utilizando la función WiFi.begin(ssid, pass). Si no es posible conectarse, se hace otro intento transcurrido 3 segundos. Si tampoco ha sido posible conectarse, se entiende que el router está apagado y se deja de intentarlo para ahorrar energía hasta la siguiente conexión:

if (WiFi.status() != WL_CONNECTED) {
  for (int i = 0; i & lt; = 1; i++) {
    WiFi.begin(ssid, pass);
    delay(3000);
    if (WiFi.status() == WL_CONNECTED) break;
  }
}

Una vez iniciado el módulo ESP8266-01, se lee el canal serie y se descompone el ‘paquete’ de datos recibidos desde la placa Arduino de forma que quede ordenado por variables, en este caso 5 (temperatura BMP280, temperatura DHT11, humedad DHT11, presión atmosférica BMP280, y tensión de batería). Asignamos un canal de ThingsPeak.com a cada variable utilizando la función ThingSpeak.setField(). Evidentemente, este ‘paquete’ se ha generado en la placa Arduino siguiendo este mismo orden al introducir cada variable.

Serial.readBytes((byte*)data, LengthData * sizeof(data[0]));

ThingSpeak.setField(1, data[0]);    // temp_BMP280
ThingSpeak.setField(2, data[1]);    // temp_DHT11
ThingSpeak.setField(3, data[2]);    // humedad_DHT11
ThingSpeak.setField(4, data[3]);    // presion_BMP280
ThingSpeak.setField(5, data[4]);    // Vbat

En el software de la placa Arduino, las variables las hemos agrupado se esta forma:

data[0] = temp_BMP280;
data[1] = temp_DHT11;
data[2] = humedad_DHT11;
data[3] = 0.00750064 * presion_BMP280;
data[4] = Vbat;

Después, simplemente se recurre a la librería ThingsPeak.h para actualizar las lecturas de los sensores con la web ThingsPeak.com:

ESP_Status = ThingSpeak.writeFields(myChannelNumber, myWriteAPIKey);

Si las variables se han actualizado de forma correcta, lo que incluye habernos conectado a nuestra red WIFI de forma satisfactoria, la función devuelve un 200, que lo guardaremos en la variable ESP_Status. En caso de no haber podido sincronizar las variables con ThingsPeak.com, la función devolverá un valor diferente en función del error que haya tenido (no hay red WIFI, error de sincronización…).

Finalmente, enviamos esta variable de vuelta a la placa Arduino por el canal serie para que, en caso de no haber podido sincronizar las variables de forma correcta, hacer algún reintento:

Serial.print(ESP_Status);

Una vez cargado el software, no olvidéis colocar el módulo ESP8266-01 en el conector 4×2 correspondiente. 

 


¡Con esto hemos terminado con la estación meteorológica! Espero que os haya gustado, y si tenéis cualquier duda, no dudéis en escribirme en los comentarios.


Estación meteorológica con PCB 

También os puede interesar esta otra estación meteorológica, algo más compleja al estar diseñada con PCB de fabricación profesional.


Índice ‘Drone con Arduino’

  1. Conceptos generales sobre drones.
  2. Material necesario y montaje de los componentes hardware.
  3. Mando RC y receptor. Programación en Arduino (código).
  4. MPU6050 y su programación en Arduino (código).
  5. Batería LiPo (código).
  6. Control de estabilidad y PID. 
  7. Motores, ESC y su programación en Arduino (código).
  8. Calibración de hélices y motores (código). 
  9. Software completo y esquema detallado (código).
  10. ⇒ Probando el Software completo antes de volar.
  11. Como leer variables de Arduino en Matlab (código).
Drone casero con Arduino. Como hacer un drone con Arduino paso a paso

5/5 - (1 voto)
2 Comentarios

Añadir un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *