Proyecto de IoT sencillo con Wemos D1 mini, sensores DHT11, MQTT y un panel de control web con node.js
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
images
mqtt-broker
mqtt-client/dashboard
wemos-d1-mini
.gitignore
LICENSE
README.md

README.md

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 ");
}

Ver el código fuente

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() {

}

Ver el código fuente

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() {

}

Ver el código fuente

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);
  }
}

Ver el código fuente

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

Ver el archivo Vagrantfile

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

Licencia de Creative Commons
Esta obra está bajo una licencia de Creative Commons Reconocimiento-CompartirIgual 4.0 Internacional.