Icono del sitio Home Assistant Fácil

Guía de introducción a MQTT con ESP8266 y Raspberry Pi

En este artículo voy a hablar de qué es MQTT el protocolo de comunicación ideal para el IoT. Además, tendrás un amplio tutorial para configurar este protocolo con Raspberry Pi y comunicar con un ESP8266 ya sea un NodeMCU o un Wemos, mis placas favoritas.

Para hablar del protocolo MQTT tenemos que remontarnos en el tiempo por un momento. Este protocolo permite que las máquinas hablen entre sí es decir, de máquina a máquina o M2M (del inglés Machine To Machine).

En un extremo tenemos un usuario final, en este caso es un dispositivo capaz de capturar información a través de sensores. Información como la temperatura, presión, humedad, niveles o cosas así. Toda esta información se envía a través de las redes de datos.

Durante mucho tiempo, esta arquitectura o disposición nos ha servido. Dispositivos enviando datos para ser almacenados en servidores. Sin embargo, las cosas o los objetos cada vez tienen más conectividad.

En general, como sociedad, nos hemos vuelto más conectados. De repente en este panorama ha surgido una nueva tecnología que se llama Internet de las Cosas o IoT (del inglés Internet of Things).

Esto ha hecho que la red de dispositivos que ahora pueden comunicarse entre sí, haya eclosionado. Cada vez existen más cosas u objetos conectados a Internet.

Entonces, lo que ha sucedido es que hay una necesidad real de un protocolo muy ligero, que consuma muy poco ancho de banda y que permita comunicarse a través de la publicación/suscripción para tener una comunicación bidireccional real con acuses de recibo.

Esto permite que los dispositivos pasen de tener una iteración punto a punto a una iteración más sofisticada donde se establezcan verdaderos diálogos entre las máquinas.

Aquí es donde entra en juego MQTT, un protocolo que permite eso: publicación y suscripción de mensajes, comunicación bidireccional y acuses de recibo de dichos mensajes.

¿Qué es MQTT?

Como ya he comentado, MQTT es un protocolo M2M y son siglas en inglés, Message Queue Telemetry Transport. Está basado en un protocolo de mensajería publicación/suscripción, al contrario que HTTP que es petición/respuesta.

Uno de sus puntos fuertes es que es extremadamente simple y ligero. Por este motivo es muy interesante para sistemas que requieren poco ancho de banda, tienen una alta latencia y requieren de poco consumo de los dispositivos.

Los objetivos del protocolo MQTT es minimizar el ancho de banda, comunicación bidireccional entre dispositivos, minimizar los requerimientos de los dispositivos tanto recursos como consumo y garantizar la fiabilidad y cierto grado de seguridad.

La latencia es el tiempo desde que se envía un mensaje hasta que llega a su destino. Cuanto más tiempo, más latencia.

¿Quién creó MQTT?

Al final, como sucede con casi todas las tecnologías, surgió por una necesidad. Los ingenieros Dr. Andy Stanford-Clark de IBM y Arlen Nipper de Eurotech fueron los creadores del protocolo MQTT.

En 1.999 estaban trabajando en la construcción de un oleoducto. De repente tenían la necesidad de enviar datos a través de un protocolo de comunicaciones que optimizara el ancho de banda y el consumo de las baterías.

Por aquel entonces para transmitir información desde un sitio remoto como un desierto, un bosque o una montaña, tenías que hacer uso de la comunicación vía satélite. Este tipo de comunicación era extremadamente caro en aquellos tiempos.

Ahora tenemos otras tecnologías como las redes LPWAN como SigFox o Lora. Pero en 1999 no había tantas posibilidades. Esto les llevó a crear el protocolo MQTT para un caso concreto pero en la actualidad se utiliza en infinidad de proyectos.

En comunicaciones máquina a máquina o M2M, dispositivos que utilizan tecnología IoT, aplicaciones móviles con la necesidad de optimizar el ancho de banda y el consumo eléctrico. Puedes ver un montón de proyectos en la web oficial de MQTT.

¿Es un estándar de comunicaciones?

Desde el año 2014 se ha convertido en un estándar OASIS. Esta organización sin ánimo de lucro, se orienta al desarrollo, la convergencia y la adopción de los estándares de comercio electrónico y servicios web.

Debemos dar mucha importancia a que un protocolo o una tecnología se convierta en un estándar. Esto permite que los proyectos evolucionen de forma independiente a los protocolos o tecnologías.

Los estándares ofrecen un alto grado de compatibilidad entre desarrollos, seguridad, interoperabilidad y escalabilidad de los proyectos sin preocuparnos de los protocolos.

El ejemplo más claro es TCP/IP, un protocolo inventando en los años 70 y que a día de hoy se sigue utilizando masivamente.

Además de ser un estándar, es de código abierto. La especificación del protocolo se ha publicado abiertamente con una licencia libre. Fue en el año 2011 cuando las empresas IBM y Eurotech donaron el código MQTT al proyecto Eclipse.

¿Es un protocolo seguro?

Siempre debemos partir de la suposición que mientras que una máquina esté conectada a Internet, no se puede garantizar la seguridad al 100%. Partiendo de este hecho, MQTT soporta cifrado mediante SSL.

Por lo tanto, podemos enviar datos cifrados a través de la red utilizando este protocolo. Eso sí, se debe pagar un precio.

Cuando se utiliza cifrado SSL se añade una sobrecarga a la red y los microcontroladores, haciendo que MQTT ya no sea un protocolo tan ligero y simple.

Arquitectura de un sistema MQTT

En esta sección haré un repaso rápido de cómo se estructura un sistema que utilice el protocolo MQTT. Hablaré de la arquitectura típica.

Lo primero es ver cómo se conectan los dispositivos. Utilizan una topología en estrella es decir, todos los clientes se conectan directamente a un punto central que hace de servidor. En MQTT este servidor se llama Broker.

El Broker es la parte central de la arquitectura y todos los mensajes pasan por él.

Arquitectura publicación/suscripción de MQTT

Se trata de una arquitectura basada en eventos. Cada mensaje se envía a los receptores que se hayan suscrito a una publicación concreta. El Broker se encarga de distribuir los mensajes a los receptores.

El topic es el tema donde se suscriben los receptores para recibir el mensaje. Voy a hacer una comunicación típica para entender el concepto de arquitectura publicación/suscripción.

Un cliente se suscribe a un topic que es como el tema, a quién va dirigido el mensaje. Lo podemos asemejar como el asunto de un email. Un mensaje no tiene destinatario concreto, puede haber uno, muchos o ninguno.

El emisor, el que envía el mensaje, no sabe a quién va dirigido dicho mensaje, sólo el Broker lo sabe. Cuando llega un nuevo mensaje se lo envía a aquellos que se han suscrito al topic.

El mensaje puede ser cualquier cosa, una temperatura, un 1 o un 0, un texto, … El formato es totalmente libre, lo decide el programador y el tamaño máximo depende de la implementación del protocolo MQTT y no de la especificación.

¿Qué es el topic?

Como ya he comentado, el topic es el tema del mensaje, a quién va dirigido ese mensaje. Es un concepto que tenemos que tener muy claro así que vamos a verlo con una analogía.

Imagínate una editorial que publica revistas sobre temas técnicos. Tiene dos categorías principales: electrónica y programación.

Dentro de estas categorías, la editorial define unas sub-categorías donde se tratan temas más específicos. Para electrónica tiene placas de desarrollo y componentes. Para programación tiene programación backend y programación frontend.

Por último, están las revistas que van destinadas a algo concreto. Dentro de electrónica/placas de desarrollo hay dos revistas una dedicada a Arduino y otra al ESP8266. En electrónica/componentes hay otras dos revistas dedicadas a los sensores DHT11 y DS18b20.

En la categoría de programación ocurre lo mismo. Dentro de programación/programación backend se publican dos revistas orientadas a Java y NodeJS. Por último en programación/programación frontend se publican otras dos revistas centradas en JavaScript y HTML.

El resumen de esta organización sería el siguiente.

Por ejemplo te puedes suscribir a la revista de Arduino y recibir sólo esa revista. Sin embargo, si te suscribes a la categoría de placas de desarrollo, recibirás todas las revistas de esa categoría: Arduino y ESP8266.

De igual forma, si te suscribes a programación recibirás todas las revistas: Java, NodeJS, JavaScript y HTML. Creo que el concepto de lo que es la publicación/suscripción con un topic o tema queda claro.

Pero los topic dentro de MQTT tienen su propia sintaxis. Por ejemplo, si quieres recibir sólo la revista de Arduino tienes que suscribirte a /editorial maker/electrónica/placas desarrollo/arduino.

Sintaxis de los topic

El símbolo / es un separador de niveles. Siempre se pone para separar cada uno de los niveles.

Cuando trabajamos con un dispositivo del IoT utilizamos otros nombres para los topic. Por ejemplo, podríamos tener algo como esto para medir la temperatura:

Existen comodines como el símbolo + y #.

El símbolo + se sustituye por cualquier nivel. Si por ejemplo nos queremos suscribir a todos los topic de temperatura podemos hacerlo de la siguiente manera

/casa/+/temperatura

El símbolo + se sustituirá por cada nivel que tenga como nivel superior casa y como nivel inferior temperatura.

El símbolo # también es un comodín. Este símbolo cubre varios nieves aguas abajo. Por ejemplo si quieres suscribirte a todos los mensajes que se envían a casa sólo tienes que hacer lo siguiente

/casa/#

Donde estamos indicando que todos los mensajes que se envíen a cualquier nivel dentro del topic casa lo recibirás.

Estructura de un mensaje MQTT

Lo más importante dentro del protocolo MQTT son los mensajes. Se envían de forma asíncrona es decir, no hay que esperar respuesta una vez que se envía un mensaje.

Cada mensaje consta de 3 partes:

Al ser uno de los objetivos consumir el menor ancho de banda, cada bit está estudiado cuidadosamente para que cumpla con este objetivo.

¿Cómo funciona la arquitectura MQTT?

Una de las características más importantes es que los clientes o nodos no depende unos de otros ya que no tienen conocimiento de quién está al otro lado. Puede incluso que no haya nadie en el otro extremo.

Esto permite algo muy importantes en proyectos de este tipo: la escalabilidad.

Al contrario de lo que ocurre con el protocolo HTTP, no hay que hacer una petición para recibir información desde un cliente. Cada cliente MQTT abre una conexión permanente TCP con el Broker.

El Broker tiene la capacidad de hacer que los mensajes sean persistentes, guardando el mensaje hasta que se conecte el cliente al que va dirigido. Te recuerdo que el Broker es el único que sabe quién está suscrito a un topic.

Servicio de Calidad o QoS

He hablado en varias ocasiones de que MQTT es un protocolo fiable. Eso se debe a que tiene implementado un Servicio de Calidad o QoS (del inglés Quality of Service). Este servicio determina cómo se entrega el mensaje a los receptores.

El QoS se especifica en cada mensaje que se envía y puede haber 3 grados de calidad:

Utilizar un grado de calidad u otro dependerá de la fiabilidad que queramos tener en nuestro sistema. Sin embargo, debes tener en cuenta que cuanta más calidad menor será el rendimiento.

Ahora que ya tenemos los conocimientos técnicos, vamos a poner en práctica todo esto para montar nuestro sistema basado en el protocolo MQTT.

Instalación Mosquitto en Raspberry Pi

Para instalar MQTT en una Raspberry Pi voy a utilizar un servidor ampliamente conocido como es Eclipse Mosquitto.

Mosquitto es un mediador de mensajes que incluye el protocolo MQTT. Además es de código abierto lo que supone una ventaja para los Makers ya que lo podemos utilizar sin ningún tipo de problema.

Para que el protocolo MQTT esté en constante disponibilidad, es recomendable instalar el broker en un servidor que esté siempre encendido. Tenemos diferentes opciones pero la más interesante es Raspberry Pi por su bajo coste y consumo.

Vamos a ver los pasos que deben seguir para tener operativo nuestro servidor MQTT.

Debes tener instalado Raspbian y recomendable la versión Jessie. En la página web de la Fundación Raspberry Pi tienes un tutorial paso a paso.

Paso 1: Instalar Broker MQTT

Si ya tienes experiencia con Raspberry Pi conocerás apt-get. Se trata de una herramienta para gestionar paquetes instalables a través de la línea de comandos. Desafortunadamente no podemos utilizar sólo esta herramienta para instalar Mosquitto MQTT.

Esto es debido a que si lo hacemos, no nos instalará la última versión del software y nos generará errores de compatibilidad de software.

La Raspberry Pi tiene que estar conectada a Internet para poder instalar el Broker MQTT Mosquitto.

Abre una terminal en tu Raspberry Pi.

Lo primero es descargar la signing key o clave de firma utilizando el comando wget. Este comando descarga el fichero indicado como parámetro en el directorio en el que te encuentras.

Añadimos la clave para a una lista para autenticar el paquete que vamos a descargar más tarde.

Luego tienes que ir a la siguiente carpeta utilizando el comando cd.

Después descargamos la lista de repositorios de Mosquitto con wget.

Si tu versión de Raspbian es Jessie, ejecuta el siguiente comando.

Si tu versión de Raspbian es Stretch, ejecuta el siguiente comando.

Si utilizas la última versión, Buster, utiliza el siguiente comando.

Como ves, si utilizas una versión anterior o más reciente, lo único que tienes que hacer es cambiar el nombre la versión.

Ahora para no tener que estar constantemente poniendo la palabra sudo, escribimos lo siguiente en la terminal para ser usuario root.

Este paso no es obligatorio, si no lo haces tendrás que poner sudo en los comandos que van a continuación.

Como ves, la shell cambia de aspecto. A partir de ahora ya no hace falta poner la palabra sudo antes.

Actualizamos la lista de paquetes disponibles y sus versiones.

Esto puede tardar un rato así que ten paciencia.

Ejecuta el siguiente comando para instalar el Broker Mosquitto.

Por último, para poder conectar al Broker MQTT tienes que editar el archivo mosquitto.conf ejecutando el siguiente comando.

Añade la siguiente configuración

Con esto ya tendríamos el Broker Mosquitto instalado en nuestra Raspberry Pi. Ahora toca instalar el cliente para hacer las pruebas.

Paso 2: Instalar cliente MQTT en Raspberry Pi

Este paso va a ser muy sencillo. Si todavía no has cerrado la terminal anterior sólo tendrás que escribir el siguiente comando.

Recuerda que si no estás logueado como root tendrás que poner antes del comando sudo.

En un momento dado te hará la siguiente pregunta «Do you want to continue? (¿Quieres continuar?)». Tienes que dar a la tecla «y» y al Enter.

Con esto ya tendríamos todo lo necesario para hacer nuestro primer ejemplo.

Paso 3: Ejemplo con Mosquitto MQTT

Ahora mismo si tu Raspberry Pi está conectada a la red de tu casa, puedes crear un topic accesible desde cualquier cliente MQTT que esté conectado al Broker.

De momento, lo único que queremos es probar que todo está bien instalado así que lo haremos sobre la misma Raspberry Pi.

Pero antes de continuar vamos a ver los dos comandos que vamos a utilizar del cliente MQTT Mosquitto, mosquitto_sub y mosquitto_pub.

Comando mosquitto_sub

Este comando nos permite suscribirnos a un topic escuchando y mostrando por pantalla los mensajes enviados a este topic. Puede tomar muchos parámetros pero nosotros nos vamos a centrar en 4.

Donde:

Comando mosquitto_pub

Con este comando podemos publicar mensajes muy simples. Como ocurre con mosquitto_subpuede tomar muchos parámetros, este comando pero a nosotros nos importan sólo 6.

Donde:

Ahora sólo nos queda probar así que abre dos terminales en la Raspberry Pi.

Uno va a ser el que publique y otro el que esté escuchando. Elige el que quieras y escribe el siguiente comando.

La terminal se queda esperando a recibir algún mensaje.

En el otro terminal escribe el siguiente comando que envía un mensaje al topic casa/comedor/temperatura.

Ahora si te fijas en la terminal donde estaba esperando un mensaje aparece precisamente el que hemos enviado.

Puedes seguir jugando con los comodines que hemos visto anteriormente. Utiliza los símbolos + y #.

Por último es aconsejable que nuestra Raspberry Pi tenga una IP estática o fija. Esto quiere decir que aunque se desconecte de la red, siempre tendrá la misma IP. Esto lo puedes hacer siguiendo el tutorial de ModMyPi.

Y así de fácil hemos conseguido crear una red con el protocolo MQTT. Ahora lo que haremos es poder encender un LED conectado a un NodeMCU desde la Raspberry Pi.

Enviando y recibiendo mensajes MQTT con NodeMCU

Lo primero de todo es que tienes que tener una placa con un ESP8266. Yo suelo recomendar NodeMCU que la puedes comprar por menos de 8€. Pero también te puede servir cualquier placa de desarrollo como una Wemos que cuesta también menos de 8€.

Antes de continuar, te recomiendo que leas el artículo tutorial paso a paso con NodeMCU y cómo programar NodeMCU desde el IDE de Arduino. Es necesario tener listo tanto el IDE como la placa de desarrollo.

Ahora sí, ya podemos empezar a trabajar con NodeMCU y MQTT. Lo primero será instalar la librería.

Instalando la librería PubSubClient

Una de las grandes ventajas que tenemos a la hora de prototipar con Arduino o ESP8266, es que tenemos un montón de librerías que nos hacen la vida mucho más fácil. Si no tienes experiencia con librerías, te aconsejo que eches un vistazo al tutorial donde explico cómo instalar librerías en el IDE de Arduino.

PubSubClient es una librería compatible con Arduino y ESP8266. Básicamente hace que nuestra placa se comporte como un cliente MQTT es decir, que podamos publicar mensajes y suscribirnos a un topic o varios para recibir mensajes.

Da lo mismo si utilizas un Arduino o un ESP8266, el código es prácticamente el mismo. La diferencia reside en cómo nos conectamos a la red WiFi, cada placa utiliza su propia librería.

Lo primero es instalar la librería siguiendo. Abre el  la opción del menú Programa>Incluir Librería>Gestor de librerías y busca PubSubClient

Luego le das a instalar y listo, ya tienes el la librería instalada en tu ordenador y prepara para ser utilizada.

Enviando un mensaje a través del protocolo MQTT con NodeMCU

Vamos a partir de uno de los ejemplos que vienen dentro de la librería. Lo encontrarás en Archivo>Ejemplos>PubSubClient>mqtt_esp8266. Esta opción te abre el siguiente código.

Vamos a ir viendo las modificaciones que tenemos que hacer para enviar un mensaje con el protocolo MQTT desde NodeMCU.

Paso 1: poner ssid, password y mqtt_server

Sustituye por los valores de tu red WiFi y de tu servidor o Broker MQTT. Como lo tenemos instalado en la Raspberry Pi, lo único que tienes que haces es entrar en una línea de comandos y poner lo siguiente.

Esto te mostrará algo parecido a lo siguiente.

En mi caso, la IP de mi Raspberry Pi es la 192.168.0.167

Por lo tanto el código que debes cambiar quedaría algo parecido a esto.

Paso 2: cambiar el topic donde enviamos el mensaje

Vamos a comenzar cambiando los topic que vienen por defecto. El esquema de nuestra red MQTT será el siguiente:

Antes de continuar déjame que te explique este esquema. El nivel superior es la casa. De aquí partirán el resto de niveles. En este caso sólo tenemos uno que es el despacho pero podría haber más niveles como habitación, cocina, salón, etc…

Del despacho salen dos subniveles: luz y temperatura. Lo lógico es suscribirse a dos topic:

Como hemos visto antes, existe una gran variedad de topic si utilizamos los comodines + y #. Pero en este ejemplo no los vamos a utilizar.

Por otro lado tenemos que tener claro cual es la función de cada uno de estos topic. Por ejemplo, el topic casa/despacho/luz debería ser un actuador y por lo tanto, el dispositivo que se encargue de controlar la luz debería estar suscrito y escuchando los mensajes que llegan a ese topic.

Puede ser un Arduino MKR1000, un ESP8266 o cualquier otra placa con conexión a la red. En esta placa podemos conectar un relé que controle una luz. Al recibir un mensaje en el topic casa/despacho/luz, actuará en consecuencia.

Si es un 1 activará el relé y si es un 0 lo apagará. Así de sencillo.

A la vez, el mismo dispositivo puede publicar la temperatura en el topic casa/despacho/temperatura. Ahora sólo nos falta saber quién publicará en el topic de la luz y quién recibirá los mensajes de temperatura.

Ese otro dispositivo puede ser cualquier cosa. Imagínate una Raspberry Pi que sea capaz de trabajar como cliente MQTT. Se pueden hacer aplicaciones con muchos lenguajes que tienen librerías o frameworks para conectarnos vía MQTT.

Como hemos visto al configurar Mosquitto con Raspberry Pi, hemos instalado un cliente MQTT. Por lo tanto, Raspberry Pi se comportará como Broker y como cliente.

Seremos capaces de enviar un mensaje a NodeMCU para que encienda el LED. Por otro lado, nos suscribiremos al topic de temperatura para leer la información que envíe NodeMCU.

Todo esto lo podemos hacer fácilmente con Node-RED aunque esto se sale fuera de este tutorial. Si quieres aprender cómo hacerlo, no te pierdas esta introducción a Node-RED.

Panel de control Acuario con Node-RED, Wemos Mini D1 y protocolo MQTT

La idea final es que un topic puede lanzar un evento como actuador o como sensor. Lo típico es que los actuadores se suscriban y escuchen mensajes. Por otro lado los sensores publicarán en un topic los datos que van adquiriendo.

En este ejemplo, NodeMCU se suscribirá al topic casa/despacho/luz y publicará en casa/despacho/temperatura los datos de temperatura. Raspberry Pi se suscribirá al topic casa/despacho/temperatura y enviará mensajes a casa/despacho/luz.

Ahora sólo nos falta cambiar los topic. Ves a la línea 98 y sustituye esto

Por esto

En esta línea estamos diciendo que publique un mensaje (Enviando el primer mensaje) en el topic casa/despacho/temperatura.

Luego en la línea 100 sustituye esto

Por esto

En esta línea estamos diciendo que se suscriba al topic casa/despacho/luz.

Sólo nos falta cambiar la línea 125. Sustituye esto

Por esto

Probando la aplicación MQTT con ESP8266 y Raspberry Pi

Por último nos queda probar todo el sistema. No te olvides de cargar el código en la placa con las modificaciones hechas. Te dejo aquí una copia donde sólo tienes que poner el nombre de la WiFi, la contraseña y la IP del Broker.

Abre una terminal en la Raspberry Pi y escribe el siguiente comando.

Si ya has cargado el código comprobarás cómo estás recibiendo mensajes desde NodeMCU. Tendrás algo parecido a esto.

Abre otro terminal y escribe el siguiente comando.

Si el LED que vienen incorporado en la placa estaba encendido, se apagará.

Si escribes este otro comando

Encenderás el LED. Así de sencillo :)

Conclusiones proyecto MQTT con ESP8266 y Raspberry Pi

Ha sido un artículo largo, ya sabes que a mi encanta tratar el tema de principio a fin. Hemos empezado viendo qué es MQTT, un protocolo de comunicaciones muy ligero y sencillo.

Los objetivos de MQTT son optimizar el ancho de banda, minimizar los recursos a nivel de hardware y hacer que las comunicaciones sean fiables.

La típica arquitectura de un sistema MQTT se basa en una red con topología de estrella donde hay un nodo central llamado Broker por el que pasan todas las comunicaciones. Los clientes se conectan al Broker para recibir y enviar mensajes.

Un topic es el tema al que se suscriben los clientes y el tema al que se pueden enviar mensajes.

Por último, hemos puesto en práctica lo aprendido montando el Broker MQTT Mosquitto en una Raspberry Pi. Utilizando como cliente tanto la Raspberry Pi como un NodeMCU hemos visto cómo comunicar estos dos dispositivos y enviar mensajes entre ellos.

Se trata de un protocolo que tiene muchas posibilidades en el movimiento Maker y dentro del IoT. Te aconsejo que sigas practicando y nos cuentes, en los comentarios, qué te parece MQTT.

¿Conocías el protocolo MQTT?

¿Dónde utilizarías MQTT con un ESP8266 y Raspberry Pi?

Salir de la versión móvil