iot-demo
Descripción del proyecto
En cada aula del instituto vamos a tener un Wemos D1 mini y un sensor de temperatura/humedad DHT11 que va a ir tomando medidas de forma constante y las va a ir publicando en un broker MQTT. También existirán otros dispositivos y aplicaciones que estarán suscritas a los topics del broker MQTT donde se publican los valores recogidos por los sensores. Podríamos seguir la siguiente estructura de nombres para los topics del edificio:
ies/aula<número>/temperature
ies/aula<número>/humidity
Por ejemplo para el aula20
tendríamos los siguientes topics:
ies/aula20/temperature
ies/aula20/humidity
Diagrama
Hardware
Wemos D1 mini
Puedes encontrar más información en la documentación oficial.
Sensor de temperatura/humedad DHT11
Puedes encontrar más información en la documentación oficial.
Wemos D1 mini
Lectura del sensor de temperatura/humedad DHT11
Vamos a hacer uso de la librería de Adafruit DHT para trabajar con los sensores DHT11. Podemos usar el siguiente código de ejemplo:
#include "DHT.h"
#define DHTPIN D4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
void setup() {
Serial.begin(115200);
Serial.println("IoT demo");
dht.begin();
}
void loop() {
delay(2000);
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C ");
}
Cómo obtener la dirección MAC de un Wemos D1 mini
En las aulas estamos usando filtrado por MAC, por lo que será necesario conocer la dirección MAC de nuestros dispositivos Wemos D1 mini. Podemos usar el siguiente código de ejemplo:
#include <ESP8266WiFi.h>
void setup() {
delay(500);
Serial.begin(115200);
Serial.print("MAC: ");
Serial.println(WiFi.macAddress());
}
void loop() {
}
Configuración WiFi
El servicio de DHCP está desactivado en los puntos de acceso WiFi por lo que tendremos que asignar una dirección IP estática a cada uno de los dispostivos Wemos D1 mini. Por ejemplo, para la siguiente configuración de red:
- WiFi SSID:
AULA20
- WiFi Password:
aula20
- IP:
192.168.1.10
- Puerta de enlace:
192.168.1.1
- Máscara de red:
255.255.255.0
Utilizaríamos el siguiente código:
#include <ESP8266WiFi.h>
#define WLAN_SSID "AULA20"
#define WLAN_PASS "aula20"
IPAddress ip(192, 168, 1, 10);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
WiFiClient client;
//----------------------------------------------
void connectWiFi() {
WiFi.config(ip, gateway, gateway, subnet);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
//----------------------------------------------
void setup() {
Serial.begin(115200);
connectWiFi();
}
void loop() {
}
Configuración para publicar datos en el broker MQTT
Vamos a hacer uso de la librería Adafruit MQTT para conectar con el broker MQTT y publicar los datos que vamos obteniendo de los sensores DHT11. En nuestro caso vamos a tener la siguiente configuración de red:
- WiFi SSID:
AULA20
- WiFi Password:
aula20
- IP:
192.168.1.10
- Puerta de enlace:
192.168.1.1
- Máscara de red:
255.255.255.0
Y la configuración del broker MQTT será la siguiente:
- Servidor MQTT:
192.168.1.200
- Puerto MQTT:
1883
- Topic para los valores de temperatura:
ies/aula20/temperature
- Topic para los valores de humedad:
ies/aula20/humidity
En este ejemplo no vamos a proteger el acceso al topic con usuario y contraseña.
#include "DHT.h"
#include <ESP8266WiFi.h>
#include "Adafruit_MQTT.h"
#include "Adafruit_MQTT_Client.h"
#define DHTPIN D4
#define DHTTYPE DHT11
DHT dht(DHTPIN, DHTTYPE);
#define WLAN_SSID "AULA20"
#define WLAN_PASS "aula20"
IPAddress ip(192, 168, 1, 10);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);
#define MQTT_SERVER "192.168.1.200"
#define MQTT_SERVERPORT 1883
#define MQTT_USERNAME ""
#define MQTT_KEY ""
#define MQTT_FEED_TEMP "ies/aula20/temperature"
#define MQTT_FEED_HUMI "ies/aula20/humidity"
WiFiClient client;
Adafruit_MQTT_Client mqtt(&client, MQTT_SERVER, MQTT_SERVERPORT, MQTT_USERNAME, MQTT_USERNAME, MQTT_KEY);
Adafruit_MQTT_Publish temperatureFeed = Adafruit_MQTT_Publish(&mqtt, MQTT_FEED_TEMP);
Adafruit_MQTT_Publish humidityFeed = Adafruit_MQTT_Publish(&mqtt, MQTT_FEED_HUMI);
//----------------------------------------------
void connectWiFi();
//----------------------------------------------
void setup() {
Serial.begin(115200);
Serial.println("IoT demo");
dht.begin();
connectWiFi();
connectMQTT();
}
//----------------------------------------------
void loop() {
delay(2000);
float h = dht.readHumidity();
float t = dht.readTemperature();
if (isnan(h) || isnan(t)) {
Serial.println("Failed to read from DHT sensor!");
return;
}
Serial.print("Humidity: ");
Serial.print(h);
Serial.print(" %\t");
Serial.print("Temperature: ");
Serial.print(t);
Serial.println(" *C ");
temperatureFeed.publish(t);
humidityFeed.publish(h);
}
//----------------------------------------------
void connectWiFi() {
WiFi.config(ip, gateway, gateway, subnet);
WiFi.begin(WLAN_SSID, WLAN_PASS);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
}
//----------------------------------------------
void connectMQTT() {
if (mqtt.connected())
return;
Serial.print("Connecting to MQTT... ");
while (mqtt.connect() != 0) {
Serial.println("Error. Retrying MQTT connection in 5 seconds...");
mqtt.disconnect();
delay(5000);
}
}
MQTT broker
Vagrantfile
para la máquina virtual
Vamos a utilizar una máquina virtual con Ubuntu Xenial64 para nuestro broker MQTT. Este podría ser el archvivo Vagrantfile
con la configuración de la máquina virtual:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "public_network", ip: "192.168.1.200"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y mosquitto mosquitto-clients
SHELL
end
Instalación
Vamos a instalar mosquitto, un broker MQTT open source usado para la comunicación entre dispositivos en el IoT.
sudo apt-get install -y mosquitto mosquitto-clients
Configuración
Configuramos mosquitto para que acepte conexiones de red desde cualquier interfaz del servidor. Editamos el archivo:
/etc/mosquitto/mosquitto.conf
y añadimos la siguiente línea:
bind_address 0.0.0.0
Publicar mensajes en un topic
mosquitto_pub -h <host> -t <topic> -m <mensaje>
Por ejemplo, el comando:
mosquitto_pub -h 192.168.1.200 -t ies/aula20/temperature -m "hello world!"
Publica el mensaje "hello world!"
en el topic ies/aula20/temperature
en el MQTT broker que está en la IP 192.168.1.200
.
Suscribirse a un topic
mosquitto_sub -h <host> -t <topic>
Por ejemplo, el comando:
mosquitto_sub -h 192.168.1.200 -t ies/aula20/temperature
Se suscribe al topic ies/aula20/temperature
que está en el MQTT broker con dirección IP 192.168.1.200
.
Cliente MQTT
Dashboard
Como cliente MQTT vamos a tener una nueva máquina virtual que se va a suscribir a los topics del broker MQTT y va a mostrar los valores de los sensores en un panel de control web como el que se muestra a continuación. La dirección IP de la máquina virtual será la 192.168.1.100
y tendrá un servidor web con node.js en el puerto 3000
.
Vagrantfile
para la máquina virtual del dashboard
Vamos a utilizar una máquina virtual con Ubuntu Xenial64 para nuestro servidor web con node.js que va a alojar el dashboard. Este podría ser el archvivo Vagrantfile
con la configuración de la máquina virtual:
# -*- mode: ruby -*-
# vi: set ft=ruby :
Vagrant.configure("2") do |config|
config.vm.box = "ubuntu/xenial64"
config.vm.network "public_network", ip: "192.168.1.100"
config.vm.provision "shell", inline: <<-SHELL
apt-get update
apt-get install -y nodejs
apt-get install -y npm
cd /vagrant/web
npm install
SHELL
end
Servidor web con node.js
Ver el código fuente del servidor web con node.js
Autor
Este material ha sido desarrollado por José Juan Sánchez.
Licencia
Esta obra está bajo una licencia de Creative Commons Reconocimiento-CompartirIgual 4.0 Internacional.