Hoy vamos a ver cómo enviar datos (específicamente temperatura y humedad) recogidos del sensor DHT22 a Adafruit.
Lo que usaremos para enviar los datos será la tarjeta NodeMCU ESP8266, aunque el código explicado aquí funciona para muchas más tarjetas.
Librerías necesarias
Te recomiendo usar VSCode con PlatformIO para programar la tarjeta. Mostraré la guía para instalar las librerías desde PlatformIO, pero si usas el IDE de Arduino puedes encontrarla por el mismo nombre.
Vamos a leer la temperatura con el DHT22, así que por favor mira este post en donde se indica cómo instalar las librerías y descargar el encabezado faltante, no es muy largo.
También necesitamos las librerías de Adafruit.
Busca adafruit communication e instala Adafruit IO Arduino.
Busca adafruit mqtt e instala Adafruit MQTT Library.
Finalmente busca ArduinoHttpClient e instala ArduinoHttpClient.
Al final debe verse así:
Configuración de Adafruit
Veremos todo lo que se tiene que hacer en el sitio web de Adafruit.
Dashboard
Vamos a crear un dashboard en donde mostraremos una gráfica de la temperatura y la humedad. Comenzamos creando un escritorio o dashboard.
Ve al sitio de adafruit: https://io.adafruit.com/ (si no tienes cuenta, crea una y todo eso, ¿ya sabes, no?)
Ahora en Dashboards selecciona View All y más tarde en Actions elige Create a new Dashboard:
Ponle un nombre y descripción que quieras. Luego haz click en Create.
Feeds
Necesitamos dos feeds, uno de temperatura y otro de humedad. Más tarde vamos a poner estos feeds en el escritorio creado anteriormente.
Ve a Feeds > View All y en Actions haz click en Create a new Feed:
Elige el nombre que gustes, pero recuérdalo. Yo creé uno con el nombre Temperatura y otro con el nombre Humedad.
Repite el paso para crear el Feed de humedad. No olvides los nombres, pues más tarde los vamos a usar.
Gráfica Line Chart
Como último paso regresa a Dashboards > View All y haz click en el que creamos anteriormente. En la parte derecha selecciona create a new block, en el tipo selecciona Line Chart:
Después de eso, elige los feeds creados anteriormente:
En la siguiente ventana puedes dejar todo intacto o configurarlo a tu gusto. Yo lo he dejado así:
Claves de Adafruit IO
En la parte derecha hay un apartado que dice AIO KEY, al hacer click en el mismo te dará tu usuario y clave. Hay que copiarlas para usarlas más tarde.
Eso es todo lo necesario en la parte de Adafruit.
Código fuente
Veremos ahora la parte para conectarnos a Adafruit, crear los feeds y enviarlos al servidor para graficarlos. Recuerda que vamos a leer el sensor DHT22.
Archivo de configuración config.h
Según los ejemplos de Adafruit podemos colocar nuestra clave en el archivo config.h
, el mío se ve así:
/************************ Adafruit IO Config *******************************/
// visit io.adafruit.com if you need to create an account,
// or if you need your Adafruit IO key.
#define IO_USERNAME "parzibyte"
#define IO_KEY "hunter2"
/******************************* WIFI **************************************/
// the AdafruitIO_WiFi client will work with the following boards:
// - HUZZAH ESP8266 Breakout -> https://www.adafruit.com/products/2471
// - Feather HUZZAH ESP8266 -> https://www.adafruit.com/products/2821
// - Feather HUZZAH ESP32 -> https://www.adafruit.com/product/3405
// - Feather M0 WiFi -> https://www.adafruit.com/products/3010
// - Feather WICED -> https://www.adafruit.com/products/3056
// - Adafruit PyPortal -> https://www.adafruit.com/product/4116
// - Adafruit Metro M4 Express AirLift Lite ->
// https://www.adafruit.com/product/4000
// - Adafruit AirLift Breakout -> https://www.adafruit.com/product/4201
// - Adafruit AirLift Shield -> https://www.adafruit.com/product/4285
// - Adafruit AirLift FeatherWing -> https://www.adafruit.com/product/4264
#define WIFI_SSID "parzibyte"
#define WIFI_PASS "hunter2"
// uncomment the following line if you are using airlift
// #define USE_AIRLIFT
// uncomment the following line if you are using winc1500
// #define USE_WINC1500
// comment out the following lines if you are using fona or ethernet
#include "AdafruitIO_WiFi.h"
#if defined(USE_AIRLIFT) || defined(ADAFRUIT_METRO_M4_AIRLIFT_LITE) || \
defined(ADAFRUIT_PYPORTAL)
// Configure the pins used for the ESP32 connection
#if !defined(SPIWIFI_SS) // if the wifi definition isnt in the board variant
// Don't change the names of these #define's! they match the variant ones
#define SPIWIFI SPI
#define SPIWIFI_SS 10 // Chip select pin
#define NINA_ACK 9 // a.k.a BUSY or READY pin
#define NINA_RESETN 6 // Reset pin
#define NINA_GPIO0 -1 // Not connected
#endif
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS, SPIWIFI_SS,
NINA_ACK, NINA_RESETN, NINA_GPIO0, &SPIWIFI);
#else
AdafruitIO_WiFi io(IO_USERNAME, IO_KEY, WIFI_SSID, WIFI_PASS);
#endif
/******************************* FONA **************************************/
// the AdafruitIO_FONA client will work with the following boards:
// - Feather 32u4 FONA -> https://www.adafruit.com/product/3027
// uncomment the following two lines for 32u4 FONA,
// and comment out the AdafruitIO_WiFi client in the WIFI section
// #include "AdafruitIO_FONA.h"
// AdafruitIO_FONA io(IO_USERNAME, IO_KEY);
/**************************** ETHERNET ************************************/
// the AdafruitIO_Ethernet client will work with the following boards:
// - Ethernet FeatherWing -> https://www.adafruit.com/products/3201
// uncomment the following two lines for ethernet,
// and comment out the AdafruitIO_WiFi client in the WIFI section
// #include "AdafruitIO_Ethernet.h"
// AdafruitIO_Ethernet io(IO_USERNAME, IO_KEY);
Configuramos dos cosas: las claves de acceso a Adafruit, y las claves para conectar a la red WiFi, pues obviamente necesitamos internet para acceder.
Por cierto, aquí se crea una variable llamada io
, que es de tipo AdafruitIO_Wifi
pasándole nuestras credenciales.
Creación de feeds en código
Dentro del código vamos a crear igualmente los feeds; son de tipo AdafruitIO_Feed
y al instanciarlos deben tener los nombres que te dije que tenías que anotar:
// Recuerda que en io.feed() debes indicar el nombre del feed que configuraste en la web
AdafruitIO_Feed *temperaturaAdafruit = io.feed("Temperatura");
AdafruitIO_Feed *humedadAdafruit = io.feed("Humedad");
Nota: con el plan gratuito y todo eso, no deberíamos alimentar a los feeds en menos tiempo de 5 segundos. Es decir, hay que enviar datos cada 5 (o más) segundos.
Leer temperatura
Ahora leemos el sensor y enviamos los datos. La parte importante es cuando invocamos al método save
del feed, pasándole el valor.
// Si han pasado más de 5 segundos desde la última vez, enviar a Adafruit!
if (millis() - ultimaVez > TIEMPO_ESPERA)
{
humedad = sensor.readHumidity();
temperaturaEnGradosCelsius = sensor.readTemperature();
// En ocasiones puede devolver datos erróneos; por eso lo comprobamos
if (isnan(temperaturaEnGradosCelsius) || isnan(humedad))
{
ultimaVez = millis();
return;
}
temperaturaAdafruit->save(temperaturaEnGradosCelsius);
humedadAdafruit->save(humedad);
ultimaVez = millis();
}
No olvides lo del sensor DHT22 y el pin D8, que ya expliqué anteriormente pero en resumen si usas el D8 debes desconectar el sensor al subir el código. Eres libre de usar otro pin igualmente.
Poniendo todo junto
El código main.cpp
se ve así:
/*
____ _____ _ _ _
| _ \ | __ \ (_) | | |
| |_) |_ _ | |__) |_ _ _ __ _____| |__ _ _| |_ ___
| _ <| | | | | ___/ _` | '__|_ / | '_ \| | | | __/ _ \
| |_) | |_| | | | | (_| | | / /| | |_) | |_| | || __/
|____/ \__, | |_| \__,_|_| /___|_|_.__/ \__, |\__\___|
__/ | __/ |
|___/ |___/
Blog: https://parzibyte.me/blog
Ayuda: https://parzibyte.me/blog/contrataciones-ayuda/
Contacto: https://parzibyte.me/blog/contacto/
Copyright (c) 2020 Luis Cabrera Benito
Licenciado bajo la licencia MIT
El texto de arriba debe ser incluido en cualquier redistribucion
*/
#include "config.h"
#include "DHT.h"
#define TIEMPO_ESPERA 5000 // Cada cuánto leer del sensor
/*
Nota importante: si usas el pin D8 (como lo recomiendo)
recuerda desconectar el lector del mismo cada vez que reinicies
o quieras subir el código, pues el mismo "interfiere" con el
monitor serial
*/
#define PIN_CONEXION D8 // A cuál pin está conectado el lector
#define TIPO_SENSOR DHT22 // Puede ser DHT11 también
DHT sensor(PIN_CONEXION, TIPO_SENSOR);
// Recuerda que en io.feed() debes indicar el nombre del feed que configuraste en la web
AdafruitIO_Feed *temperaturaAdafruit = io.feed("Temperatura");
AdafruitIO_Feed *humedadAdafruit = io.feed("Humedad");
int ultimaVez = millis(); // Para enviar cada X segundos pero sin usar delay
float humedad, temperaturaEnGradosCelsius = 0;
void setup()
{
// Iniciar sensor DHT
sensor.begin();
// Intentar conectar a Adafruit
io.connect();
while (io.status() < AIO_CONNECTED)
{
delay(500);
}
}
// Ahora viene el loop, al cual se entra en caso de que en el setup
// todo haya ido bien
void loop()
{
// Dejar que Adafruit haga sus cosas...
io.run();
// Si han pasado más de 5 segundos desde la última vez, enviar a Adafruit!
if (millis() - ultimaVez > TIEMPO_ESPERA)
{
humedad = sensor.readHumidity();
temperaturaEnGradosCelsius = sensor.readTemperature();
// En ocasiones puede devolver datos erróneos; por eso lo comprobamos
if (isnan(temperaturaEnGradosCelsius) || isnan(humedad))
{
ultimaVez = millis();
return;
}
temperaturaAdafruit->save(temperaturaEnGradosCelsius);
humedadAdafruit->save(humedad);
ultimaVez = millis();
}
delay(10);
}
Demostración
Hay que subir el código al ESP8266 y conectar el sensor como normalmente se hace.
Después puedes ir a la página de Adafruit y ver los resultados en el dashboard, que se irán actualizando cada 5 segundos:
Si quieres verlo en vivo puedes entrar a mi dashboard, solo que no te garantizo que se vea al momento de que leas esto, pues probablemente ya habré desconectado el sensor.
Conclusión
Adafruit es un buen servicio para ver nuestros datos en tiempo real, aunque yo prefiero crear servidores propios, pero es cosa de cada persona.
Vimos cómo leer el sensor, pero realmente podemos hacer muchas cosas más. Por ejemplo, encender y apagar una bombilla usando un relevador… solo que eso es cosa de otro post.