Bloque 4.2: Protocolo MQTT para Comunicación M2M

Comunicando dispositivos de forma eficiente en el Internet de las Cosas (IoT).

Diapositivas del Tema

Consulta la presentación visual de este tema para una mejor comprensión de los conceptos.

Ver Presentación →

La Necesidad de una Comunicación Ligera

En el mundo de IoT, donde dispositivos con recursos limitados (como sensores y microcontroladores) necesitan comunicarse constantemente, los protocolos tradicionales como HTTP pueden ser demasiado pesados. MQTT surge como una solución optimizada para este entorno.

1. Introducción a los Protocolos de Comunicación

Para que dispositivos puedan intercambiar información en una red, necesitan seguir un conjunto de reglas estandarizadas, conocidas como protocolos. Existen muchos protocolos de comunicación, cada uno con sus ventajas y desventajas dependiendo del contexto de uso.

1.1. Protocolos Comunes en IoT y Redes

HTTP (HyperText Transfer Protocol)

El protocolo fundamental de la web. Es ampliamente conocido y fácil de usar, pero puede ser ineficiente para dispositivos con recursos limitados.

  • Ventajas: Estándar, bien documentado, fácil de depurar, funciona a través de firewalls.
  • Desventajas: Encabezados grandes (overhead), comunicación basada en solicitud/respuesta (no "push"), consume más energía y ancho de banda.
Zigbee

Un protocolo de comunicación inalámbrica de bajo consumo diseñado para redes de área personal (PAN). Opera en la banda de 2.4 GHz.

  • Ventajas: Muy bajo consumo de energía, redes malladas (mesh) auto-configurables, seguridad integrada.
  • Desventajas: Alcance limitado, requiere hardware especializado, no se conecta directamente a internet sin un gateway.
CoAP (Constrained Application Protocol)

Diseñado específicamente para dispositivos con recursos muy limitados. Es similar a HTTP pero más ligero y puede funcionar sobre UDP.

  • Ventajas: Muy ligero, soporta multicast, diseñado para RESTful services.
  • Desventajas: Menos maduro que HTTP/MQTT, menor ecosistema de herramientas.
MQTT (Message Queuing Telemetry Transport)

Un protocolo de mensajería basado en "publish-subscribe", optimizado para conexiones de red con alta latencia o ancho de banda limitado.

  • Ventajas: Muy ligero, eficiente en ancho de banda, soporta comunicación asíncrona, escalable, funciona bien en redes poco confiables.
  • Desventajas: Requiere un broker central, no es ideal para comunicación punto a punto simple.

¿Por qué MQTT para IoT?

MQTT se ha convertido en uno de los protocolos más populares para aplicaciones IoT por varias razones clave:

  • Minimalismo: Su diseño es extremadamente ligero, ideal para microcontroladores como ESP32 o Arduino con conectividad.
  • Patrón Publish/Subscribe: Permite una arquitectura desacoplada donde los dispositivos no necesitan conocerse entre sí, solo necesitan saber dónde enviar/recibir mensajes (tópicos).
  • Fiabilidad: Ofrece diferentes niveles de calidad de servicio (QoS) para garantizar la entrega de mensajes según las necesidades de la aplicación.
  • Eficiencia en Redes: Funciona bien incluso en conexiones inestables o de bajo ancho de banda, como redes GSM o WiFi de mala calidad.

2. Fundamentos de MQTT

MQTT (Message Queuing Telemetry Transport) es un protocolo de mensajería ligero basado en el patrón publicar/suscribir (publish/subscribe). Fue creado por IBM en 1999 para monitorear oleoductos, y su simplicidad y eficiencia lo hicieron perfecto para el mundo del IoT.

2.1. Arquitectura Publish/Subscribe

A diferencia del modelo tradicional cliente-servidor (como HTTP), donde un cliente hace una solicitud directa a un servidor, en MQTT los dispositivos (llamados clientes) se comunican a través de un Broker central.

  • Cliente (Client): Cualquier dispositivo que se conecta al broker para publicar mensajes, suscribirse a tópicos o ambos. Puede ser un sensor, un actuador, una aplicación móvil, etc.
  • Broker: El servidor central que recibe todos los mensajes, filtra los clientes que están suscritos a cada tópico y envía los mensajes a los clientes suscritos. Es el corazón del sistema MQTT.
  • Tópico (Topic): Una cadena de texto que actúa como una dirección o canal. Los clientes publican mensajes en tópicos específicos y se suscriben a tópicos para recibir mensajes. Ejemplos: sensores/temperatura/sala1, actuadores/luz/cocina.
  • Mensaje (Message/Payload): Los datos reales que se envían. Pueden ser texto plano, JSON, binarios, etc.
Diagrama de la arquitectura MQTT con clientes, broker y tópicos
Arquitectura básica de MQTT mostrando clientes, un broker central y la comunicación basada en tópicos.

2.2. Flujo de Comunicación Básico

  1. Un cliente publicador se conecta al broker y envía un mensaje a un tópico específico, por ejemplo, sensores/temperatura/sala1 con el valor 22.5.
  2. El broker recibe el mensaje y lo almacena temporalmente.
  3. El broker verifica qué clientes suscriptores están interesados en ese tópico (en este caso, sensores/temperatura/sala1).
  4. El broker reenvía (publica) el mensaje a todos los clientes que se han suscrito a ese tópico.

Este modelo desacoplado significa que el publicador no necesita saber quién recibirá el mensaje, y el suscriptor no necesita saber quién lo envió. Solo necesitan conocer el tópico.

2.3. Calidad de Servicio (QoS - Quality of Service)

MQTT define tres niveles de QoS para garantizar la entrega de mensajes según las necesidades de la aplicación:

Nivel QoS Nombre Descripción Uso Típico
0 At most once El mensaje se entrega una vez, como máximo. Puede perderse. Es el más rápido y ligero. Datos que pueden perderse sin consecuencias, como lecturas de sensores frecuentes.
1 At least once El mensaje se entrega al menos una vez. Puede llegar duplicado. Es el nivel más común. Comandos importantes donde se prefiere un duplicado a una pérdida, como encender un relé.
2 Exactly once El mensaje se entrega exactamente una vez. Es el más seguro pero también el más lento y con más overhead. Datos críticos donde ni la pérdida ni el duplicado son aceptables, como transacciones financieras.

2.4. Conexión y Sesión

MQTT es un protocolo basado en conexiones persistentes. Los clientes se conectan al broker una vez y mantienen la conexión abierta. Esto permite:

  • Mensajería Asíncrona: Los mensajes pueden fluir en cualquier dirección en cualquier momento mientras la conexión esté activa.
  • Retención de Mensajes: El broker puede almacenar el último mensaje publicado en un tópico. Cuando un nuevo suscriptor se conecta, recibe inmediatamente este mensaje retenido, lo que es útil para valores iniciales o de estado.
  • Última Voluntad (Last Will and Testament - LWT): Un cliente puede dejar un mensaje de "última voluntad" al conectarse. Si el broker detecta que el cliente se ha desconectado inesperadamente, publica automáticamente este mensaje, informando a otros clientes sobre la desconexión.

3. El Broker: Corazón del Sistema MQTT

El broker es el componente central y más crítico de una red MQTT. Es responsable de recibir todos los mensajes, gestionar las suscripciones y enrutar los mensajes a los clientes correctos. La elección del broker puede afectar significativamente el rendimiento, la seguridad y la escalabilidad de tu sistema IoT.

3.1. Funciones Principales de un Broker

  • Autenticación y Autorización: Verificar la identidad de los clientes (nombre de usuario/contraseña) y controlar a qué tópicos pueden publicar o suscribirse.
  • Enrutamiento de Mensajes: Recibir mensajes de los publicadores y entregarlos a los suscriptores correctos basándose en los tópicos.
  • Gestión de Sesiones: Mantener el estado de las conexiones de los clientes, incluyendo sus suscripciones, especialmente para clientes que se reconectan.
  • Retención de Mensajes: Almacenar y entregar el último mensaje conocido para tópicos específicos.
  • Manejo del LWT: Procesar y enviar mensajes de última voluntad cuando un cliente se desconecta inesperadamente.

3.2. Características de un Broker Robusto

  • Escalabilidad: Capacidad de manejar miles o millones de conexiones simultáneas.
  • Seguridad: Soporte para TLS/SSL para encriptar la comunicación, y mecanismos de autenticación robustos.
  • Alta Disponibilidad: Configuración en clúster para evitar puntos únicos de falla.
  • Persistencia: Almacenamiento de mensajes en disco para garantizar su entrega incluso si el broker se reinicia.

3.3. Broker Mosquitto: El Estándar de Código Abierto

Eclipse Mosquitto es probablemente el broker MQTT más popular y ampliamente utilizado, especialmente para entornos de desarrollo, pruebas y despliegues de pequeña a mediana escala. Es un proyecto de código abierto mantenido por la Fundación Eclipse.

Características Clave de Mosquitto
  • Ligero y Rápido: Consume pocos recursos, ideal para Raspberry Pi, servidores pequeños o incluso contenedores Docker.
  • Multiplataforma: Disponible para Linux, Windows, macOS y sistemas embebidos.
  • Fácil de Configurar: Un archivo de configuración sencillo permite personalizar su comportamiento.
  • Soporte para QoS 0-2: Implementa todos los niveles de calidad de servicio definidos por el estándar MQTT.
  • Seguridad: Soporta autenticación por nombre de usuario/contraseña y encriptación TLS/SSL.
  • Comunidad Activa: Gran comunidad y abundante documentación.
Instalación de Mosquitto (Ejemplo en Ubuntu/Debian)
# Instalar el broker Mosquitto
sudo apt update
sudo apt install mosquitto mosquitto-clients

# (Opcional) Iniciar el servicio automáticamente en el arranque
sudo systemctl enable mosquitto

# Iniciar el servicio
sudo systemctl start mosquitto

# Verificar el estado
sudo systemctl status mosquitto
Configuración Básica de Mosquitto

El archivo de configuración principal suele estar en /etc/mosquitto/mosquitto.conf. Aquí hay algunos ejemplos de configuraciones comunes:

# Permitir conexiones anónimas (NO recomendado para producción)
allow_anonymous true

# Escuchar en un puerto específico (por defecto es 1883)
listener 1883

# --- Configuración de Seguridad (Recomendado) ---
# Deshabilitar conexiones anónimas
allow_anonymous false

# Especificar el archivo de contraseñas
password_file /etc/mosquitto/passwd

# (Opcional) Configuración para TLS/SSL
# listener 8883
# cafile /path/to/ca.crt
# certfile /path/to/server.crt
# keyfile /path/to/server.key
Creando Usuarios en Mosquitto

Para usar autenticación, necesitas crear usuarios y sus contraseñas:

# Crear un nuevo archivo de contraseñas y añadir un usuario
sudo mosquitto_passwd -c /etc/mosquitto/passwd mi_usuario

# Añadir más usuarios al archivo existente
sudo mosquitto_passwd /etc/mosquitto/passwd otro_usuario

# Reiniciar el servicio para aplicar cambios
sudo systemctl restart mosquitto
Probando Mosquitto Localmente

El paquete mosquitto-clients incluye herramientas de línea de comandos muy útiles para pruebas:

# Terminal 1: Suscribirse a un tópico
mosquitto_sub -h localhost -t "prueba/temperatura"

# Terminal 2: Publicar un mensaje en ese tópico
mosquitto_pub -h localhost -t "prueba/temperatura" -m "22.5"

En el primer terminal, deberías ver el mensaje "22.5" aparecer inmediatamente después de ejecutar el comando en el segundo terminal.


4. Conectando un Microcontrolador ESP32 a un Broker MQTT

Una de las aplicaciones más comunes de MQTT es conectar microcontroladores como el ESP32 a un broker para enviar datos de sensores o recibir comandos. A continuación, se muestra un ejemplo básico usando el ESP32 y la librería PubSubClient.

4.1. Materiales Necesarios

  • 1 Placa ESP32 (NodeMCU, DevKit, etc.)
  • 1 Sensor de temperatura DHT22 (opcional, para el ejemplo)
  • Protoboard y cables de conexión
  • Acceso a un broker MQTT (puedes usar un broker público de prueba o uno local como Mosquitto)

4.2. Conexión del Sensor DHT22 (Opcional)

Esquema de conexión del sensor DHT22 al ESP32
Conexión del sensor DHT22 al ESP32 para el ejemplo de MQTT.

Conexiones:

  • VCC del DHT22 al pin 3V3 del ESP32.
  • GND del DHT22 al pin GND del ESP32.
  • DATA del DHT22 al pin GPIO 4 del ESP32.

4.3. Código del Sketch

Primero, necesitas instalar las librerías requeridas desde el Gestor de Librerías del Arduino IDE: PubSubClient (por Nick O'Leary) y DHT sensor library (por Adafruit).

/*
 * Cliente MQTT para ESP32
 * Publica datos de temperatura y humedad de un sensor DHT22 a un broker MQTT.
 */

#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>

// --- Configuración de WiFi ---
const char* ssid = "TU_SSID";
const char* password = "TU_CONTRASEÑA";

// --- Configuración de MQTT ---
// Puedes usar un broker público de prueba como: broker.hivemq.com (puerto 1883)
// O tu propio broker Mosquitto en la misma red, por ejemplo: 192.168.1.100
const char* mqtt_server = "broker.hivemq.com";
const int mqtt_port = 1883;

// --- Configuración del Sensor DHT ---
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);

// --- Cliente WiFi y MQTT ---
WiFiClient espClient;
PubSubClient client(espClient);

// --- Variables ---
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {
  delay(10);
  // Conectamos a la red WiFi
  Serial.println();
  Serial.print("Conectando a ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("¡Conectado a la red WiFi!");
  Serial.print("Dirección IP: ");
  Serial.println(WiFi.localIP());
}


void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Mensaje recibido [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Aquí puedes añadir lógica para manejar comandos recibidos
  // Por ejemplo, si el tópico es "actuadores/led" y el payload es "ON", enciende un LED.
}

void reconnect() {
  // Bucle hasta que se restablezca la conexión
  while (!client.connected()) {
    Serial.print("Intentando conexión MQTT...");
    // Creamos un ID de cliente aleatorio
    String clientId = "ESP32Client-" + String(random(0xffff), HEX);
    
    // Intentamos conectar
    if (client.connect(clientId.c_str())) {
      Serial.println("¡Conectado!");
      // Una vez conectado, se pueden suscribir a tópicos
      client.subscribe("actuadores/led");
    } else {
      Serial.print("falló, rc=");
      Serial.print(client.state());
      Serial.println(" reintentando en 5 segundos");
      // Esperamos 5 segundos antes de reintentar
      delay(5000);
    }
  }
}

void setup() {
  Serial.begin(115200);
  dht.begin();
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 5000) { // Publicar cada 5 segundos
    lastMsg = now;
    
    // Leemos datos del sensor
    float h = dht.readHumidity();
    float t = dht.readTemperature();
    
    // Verificamos si las lecturas son válidas
    if (isnan(h) || isnan(t)) {
      Serial.println("¡Error leyendo el sensor DHT!");
      return;
    }

    // Preparamos los mensajes
    String temp_str = String(t, 2); // 2 decimales
    String hum_str = String(h, 2);

    // Publicamos temperatura
    String topic_temp = "sensores/" + WiFi.macAddress() + "/temperatura";
    client.publish(topic_temp.c_str(), temp_str.c_str());
    Serial.print("Publicado en ");
    Serial.print(topic_temp);
    Serial.print(": ");
    Serial.println(temp_str);

    // Publicamos humedad
    String topic_hum = "sensores/" + WiFi.macAddress() + "/humedad";
    client.publish(topic_hum.c_str(), hum_str.c_str());
    Serial.print("Publicado en ");
    Serial.print(topic_hum);
    Serial.print(": ");
    Serial.println(hum_str);
  }
}

4.4. Explicación del Código

  • Librerías: Incluimos WiFi.h para conectividad, PubSubClient.h para MQTT y DHT.h para el sensor.
  • Configuración: Definimos las credenciales de WiFi y la dirección del broker MQTT. En este ejemplo usamos el broker público de HiveMQ.
  • setup_wifi(): Una función auxiliar para conectar el ESP32 a la red WiFi.
  • callback(): Esta función se ejecuta cada vez que se recibe un mensaje en un tópico al que estamos suscritos. Aquí es donde se procesarían comandos entrantes.
  • reconnect(): Maneja la reconexión automática al broker MQTT si se pierde la conexión.
  • setup(): Inicializa el puerto serial, el sensor DHT, la conexión WiFi, y configura el cliente MQTT con el servidor y la función callback.
  • loop():
    • client.connected() y reconnect() aseguran que siempre estemos conectados al broker.
    • client.loop() es crucial; permite que la librería procese mensajes entrantes y mantenga la conexión.
    • Cada 5 segundos, se leen los valores del sensor.
    • Se forman tópicos únicos basados en la dirección MAC del ESP32 (ej. sensores/A4:B1:C1:23:45:67/temperatura).
    • Se publican los valores de temperatura y humedad usando client.publish().

Este ejemplo demuestra cómo un dispositivo puede enviar datos de forma autónoma a un broker, desde donde otras aplicaciones pueden consumirlos.


5. Galería de Herramientas MQTT

Existen numerosas herramientas que facilitan el desarrollo, prueba y monitoreo de sistemas MQTT. Aquí tienes algunas de las más populares y útiles:

Eclipse Mosquitto

El broker MQTT de código abierto más popular. Ligero, confiable y fácil de instalar. Ideal para desarrollo y pequeñas instalaciones.

Sitio Oficial
MQTTX

Cliente MQTT de escritorio multiplataforma (Windows, macOS, Linux) con una interfaz gráfica intuitiva. Perfecto para desarrolladores y testers.

Sitio Oficial
HiveMQ

Plataforma MQTT empresarial con broker en la nube, herramientas de monitoreo y análisis. Ofrece un broker público gratuito para pruebas.

Sitio Oficial
EMQX

Broker MQTT de código abierto altamente escalable, capaz de manejar millones de conexiones. Muy popular en entornos de producción de gran escala.

Sitio Oficial

5.1. Usando MQTTX para Probar tu Sistema

MQTTX es una excelente herramienta para probar tu broker y clientes. Aquí te mostramos cómo usarla:

  1. Descarga e Instala: Ve al sitio oficial de MQTTX (https://mqttx.app/) y descarga la versión para tu sistema operativo.
  2. Crea una Nueva Conexión: Abre MQTTX y haz clic en el botón "+" para crear una nueva conexión.
    • Name: Dale un nombre descriptivo, como "Test Broker".
    • Host: Ingresa la dirección IP o nombre de host de tu broker (ej. localhost, broker.hivemq.com).
    • Port: Ingresa el puerto (ej. 1883 para no encriptado, 8883 para TLS).
    • Username/Password: Si tu broker requiere autenticación, ingrésalos aquí.
  3. Conéctate: Haz clic en "Connect". Si todo está bien configurado, verás el estado cambiar a "Connected".
  4. Suscríbete a Tópicos: En el panel izquierdo, haz clic en "New Subscription". Ingresa el tópico al que quieres suscribirte (ej. sensores/# para todos los sub-tópicos de sensores) y haz clic en "Subscribe".
  5. Publica Mensajes: En la parte inferior de la ventana principal, ingresa el tópico y el mensaje que quieres publicar, luego haz clic en el botón de enviar (flecha).

MQTTX te permitirá ver en tiempo real los mensajes que publica tu ESP32 y también te permitirá enviar comandos de vuelta.


6. Seguridad en MQTT

Aunque MQTT es eficiente, su uso en entornos de producción requiere una seria consideración de la seguridad.

6.1. Amenazas Comunes

  • Interceptación de Datos: Sin encriptación, los mensajes pueden ser leídos por cualquiera en la red.
  • Acceso No Autorizado: Clientes no autenticados pueden conectarse y publicar/suscribirse a tópicos sensibles.
  • Suplantación de Identidad: Un cliente puede pretender ser otro si no hay mecanismos de autenticación fuertes.

6.2. Mejores Prácticas de Seguridad

  • Usar TLS/SSL: Encripta toda la comunicación entre clientes y broker. Esto es fundamental, especialmente si el broker es accesible desde internet.
  • Autenticación Fuerte: Nunca uses conexiones anónimas en producción. Siempre requiere nombre de usuario y contraseña, o mejor aún, certificados X.509.
  • Control de Acceso (ACL): Configura listas de control de acceso en el broker para definir qué usuarios pueden publicar o suscribirse a qué tópicos.
  • Usar Tópicos con Prefijos de Usuario: Como se hizo en el ejemplo del ESP32 (sensores/MAC_ADDRESS/...), esto puede ayudar a aislar los datos de diferentes dispositivos.
  • Mantener el Software Actualizado: Asegúrate de usar siempre la última versión estable de tu broker y librerías cliente para beneficiarte de las últimas correcciones de seguridad.

7. Galería de Videos Recomendados

Qué es MQTT y cómo funciona

Una explicación clara y visual del protocolo MQTT, su arquitectura y beneficios.

MQTT con ESP32 y Mosquitto

Tutorial práctico sobre cómo conectar un ESP32 a un broker Mosquitto usando la librería PubSubClient.


8. Referencias y Lecturas Recomendadas