Introducción
El Internet de las Cosas (IoT) representa una revolución tecnológica que conecta objetos físicos a Internet, permitiendo la recopilación, análisis y actuación sobre datos en tiempo real. En esta clase exploraremos los fundamentos del IoT y sus aplicaciones industriales, utilizando un stack tecnológico moderno compuesto por ESP32, sensores DHT11, protocolo MQTT con Mosquitto y Flask para el desarrollo de aplicaciones web.
Objetivos de aprendizaje
- Comprender los conceptos fundamentales del IoT
- Analizar aplicaciones industriales y comerciales del IoT
- Implementar un sistema IoT completo usando ESP32, MQTT y Flask
- Identificar tendencias actuales y futuras del IoT
Conceptos Fundamentales
¿Qué es el Internet de las Cosas (IoT)?
El IoT es una red de dispositivos físicos interconectados que pueden recopilar e intercambiar datos a través de Internet. Estos dispositivos, equipados con sensores, software y conectividad, pueden monitorear, controlar y optimizar procesos sin intervención humana directa.
Componentes principales de un sistema IoT:
- Dispositivos/Sensores: Hardware que recopila datos del entorno (temperatura, humedad, presión, etc.)
- Conectividad: Tecnologías de comunicación (WiFi, Bluetooth, LoRaWAN, 4G/5G)
- Procesamiento de datos: Análisis local (Edge Computing) o en la nube
- Interfaz de usuario: Aplicaciones web o móviles para visualización y control
Arquitectura IoT por Capas
1. Capa de Percepción
Sensores y actuadores que interactúan con el mundo físico (DHT11, ESP32)
2. Capa de Red
Protocolos de comunicación y conectividad (MQTT, HTTP, CoAP)
3. Capa de Middleware
Procesamiento y gestión de datos (Mosquitto MQTT Broker)
4. Capa de Aplicación
Interfaces de usuario y servicios (Flask Web Application)
Stack Tecnológico de Nuestro Proyecto:
- Hardware: ESP32 + DHT11
- Protocolo: MQTT
- Broker: Mosquitto
- Backend: Python Flask
- Frontend: HTML/CSS/JavaScript
Aplicaciones del IoT en la Industria
1. Industria 4.0 y Manufactura Inteligente
- Monitoreo de equipos: Mantenimiento predictivo basado en vibración, temperatura y consumo energético
- Control de calidad: Sensores que detectan defectos en tiempo real
- Optimización de la cadena de suministro: Tracking de materiales y productos
2. Agricultura Inteligente
- Monitoreo de cultivos: Sensores de humedad del suelo, pH y nutrientes
- Riego automatizado: Sistemas que ajustan el riego según condiciones ambientales
- Ganado inteligente: Monitoreo de salud y ubicación del ganado
3. Smart Cities
- Gestión de tráfico: Semáforos inteligentes y monitoreo de congestión
- Gestión de residuos: Contenedores inteligentes que reportan su nivel de llenado
- Iluminación inteligente: Alumbrado público que se ajusta según condiciones
4. Sector Energético
- Smart Grids: Redes eléctricas inteligentes que optimizan la distribución
- Monitoreo de consumo: Medidores inteligentes para hogares e industrias
- Energías renovables: Optimización de paneles solares y turbinas eólicas
Implementación Práctica
Vamos a implementar un sistema IoT completo que monitorea temperatura y humedad usando nuestro stack tecnológico. El sistema constará de un ESP32 con sensor DHT11 que enviará datos vía MQTT a un broker Mosquitto, y una aplicación Flask que mostrará los datos en tiempo real.
Configuración del Hardware
Conexiones ESP32 + DHT11:
- VCC (DHT11) → 3.3V (ESP32)
- GND (DHT11) → GND (ESP32)
- DATA (DHT11) → GPIO 4 (ESP32)
- Resistor pull-up 10kΩ entre VCC y DATA del DHT11
Importante
En los ejemplos de código, sustituye SSID, contraseñas, IP del broker y credenciales MQTT por tus valores reales.
#include <WiFi.h>
#include <PubSubClient.h>
#include <DHT.h>
#include <ArduinoJson.h>
// Configuración WiFi
const char* ssid = "TU_RED_WIFI";
const char* password = "TU_PASSWORD";
// Configuración MQTT
const char* mqtt_server = "192.168.1.100"; // IP del broker Mosquitto
const int mqtt_port = 1883;
const char* mqtt_user = "iot_user";
const char* mqtt_password = "iot_pass";
const char* client_id = "ESP32_DHT11_001";
// Configuración DHT11
#define DHT_PIN 4
#define DHT_TYPE DHT11
DHT dht(DHT_PIN, DHT_TYPE);
// Tópicos MQTT
const char* topic_temperature = "sensors/temperature";
const char* topic_humidity = "sensors/humidity";
const char* topic_status = "sensors/status";
WiFiClient espClient;
PubSubClient client(espClient);
unsigned long lastMsg = 0;
const long interval = 5000; // Enviar datos cada 5 segundos
void setup() {
Serial.begin(115200);
dht.begin();
// Conectar a WiFi
setup_wifi();
// Configurar MQTT
client.setServer(mqtt_server, mqtt_port);
client.setCallback(callback);
Serial.println("Sistema IoT ESP32+DHT11 iniciado");
}
void setup_wifi() {
delay(10);
Serial.println();
Serial.print("Conectando a ");
Serial.println(ssid);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
randomSeed(micros());
Serial.println("");
Serial.println("WiFi conectado");
Serial.print("IP asignada: ");
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();
}
void reconnect() {
while (!client.connected()) {
Serial.print("Intentando conexión MQTT...");
if (client.connect(client_id, mqtt_user, mqtt_password)) {
Serial.println("conectado");
// Publicar mensaje de estado
client.publish(topic_status, "ESP32 conectado");
// Suscribirse a tópicos de control (opcional)
client.subscribe("control/esp32");
} else {
Serial.print("falló, rc=");
Serial.print(client.state());
Serial.println(" intentando de nuevo en 5 segundos");
delay(5000);
}
}
}
void publishSensorData() {
float humidity = dht.readHumidity();
float temperature = dht.readTemperature();
// Verificar si las lecturas son válidas
if (isnan(humidity) || isnan(temperature)) {
Serial.println("Error al leer el sensor DHT11!");
return;
}
// Crear JSON con los datos
StaticJsonDocument<200> doc;
doc["device_id"] = client_id;
doc["timestamp"] = millis();
doc["temperature"] = temperature;
doc["humidity"] = humidity;
char jsonBuffer[256];
serializeJson(doc, jsonBuffer);
// Publicar datos individuales
char tempString[8];
char humString[8];
dtostrf(temperature, 1, 2, tempString);
dtostrf(humidity, 1, 2, humString);
client.publish(topic_temperature, tempString);
client.publish(topic_humidity, humString);
// Publicar JSON completo
client.publish("sensors/data", jsonBuffer);
// Mostrar en Serial
Serial.printf("Datos enviados - Temperatura: %.2f°C, Humedad: %.2f%%\n",
temperature, humidity);
}
void loop() {
if (!client.connected()) {
reconnect();
}
client.loop();
unsigned long now = millis();
if (now - lastMsg > interval) {
lastMsg = now;
publishSensorData();
}
delay(100);
}
# Instalar Mosquitto en Ubuntu/Debian
sudo apt update
sudo apt install mosquitto mosquitto-clients
# Crear archivo de configuración /etc/mosquitto/conf.d/default.conf
echo "listener 1883
allow_anonymous false
password_file /etc/mosquitto/passwd
log_type error
log_type warning
log_type notice
log_type information
connection_messages true
log_timestamp true" | sudo tee /etc/mosquitto/conf.d/default.conf
# Crear usuario MQTT
sudo mosquitto_passwd -c /etc/mosquitto/passwd iot_user
# Reiniciar servicio
sudo systemctl restart mosquitto
sudo systemctl enable mosquitto
# Verificar funcionamiento
mosquitto_sub -h localhost -t "sensors/#" -u iot_user -P iot_pass
from flask import Flask, jsonify
from flask_socketio import SocketIO
import paho.mqtt.client as mqtt
import json
import sqlite3
from datetime import datetime
app = Flask(__name__)
app.config['SECRET_KEY'] = 'iot_secret_key'
socketio = SocketIO(app, cors_allowed_origins="*")
# Configuración MQTT
MQTT_BROKER = "localhost"
MQTT_PORT = 1883
MQTT_USERNAME = "iot_user"
MQTT_PASSWORD = "iot_pass"
MQTT_TOPICS = [("sensors/#", 0)]
# Estado en memoria
sensor_data = {
"temperature": 0.0,
"humidity": 0.0,
"last_update": None,
"device_status": "offline",
"device_id": None,
}
# Base de datos SQLite
def init_db():
conn = sqlite3.connect('iot_data.db')
cur = conn.cursor()
cur.execute(
'''CREATE TABLE IF NOT EXISTS sensor_readings (
id INTEGER PRIMARY KEY AUTOINCREMENT,
timestamp TEXT,
temperature REAL,
humidity REAL,
device_id TEXT
)'''
)
conn.commit()
conn.close()
def save_to_db(temperature: float, humidity: float, device_id: str):
conn = sqlite3.connect('iot_data.db')
cur = conn.cursor()
cur.execute(
'INSERT INTO sensor_readings (timestamp, temperature, humidity, device_id) VALUES (?, ?, ?, ?)',
(datetime.utcnow().isoformat(), float(temperature), float(humidity), device_id or 'unknown')
)
conn.commit()
conn.close()
mqtt_client = mqtt.Client()
def on_connect(client, userdata, flags, rc):
if rc == 0:
print("Conectado al broker MQTT")
client.subscribe(MQTT_TOPICS)
sensor_data["device_status"] = "online"
socketio.emit("status", {"status": "online"})
else:
print(f"Error de conexión MQTT: rc={rc}")
def on_message(client, userdata, msg):
try:
payload = msg.payload.decode('utf-8')
device_id = 'unknown'
temperature = sensor_data.get('temperature', 0.0)
humidity = sensor_data.get('humidity', 0.0)
if msg.topic.endswith('/data'):
data = json.loads(payload)
temperature = float(data.get('temperature', temperature))
humidity = float(data.get('humidity', humidity))
device_id = data.get('device_id', device_id)
elif msg.topic.endswith('/temperature'):
temperature = float(payload)
elif msg.topic.endswith('/humidity'):
humidity = float(payload)
else:
# Otros tópicos no se procesan en este ejemplo
return
sensor_data.update({
'temperature': temperature,
'humidity': humidity,
'device_id': device_id,
'last_update': datetime.utcnow().isoformat(),
})
save_to_db(temperature, humidity, device_id)
socketio.emit('sensor_update', sensor_data)
print(f"Datos recibidos -> T={temperature} H={humidity} ({msg.topic})")
except Exception as e:
print(f"Error procesando mensaje: {e}")
mqtt_client.username_pw_set(MQTT_USERNAME, MQTT_PASSWORD)
mqtt_client.on_connect = on_connect
mqtt_client.on_message = on_message
@app.get("/")
def root():
# Simple para demo; en proyecto real, renderiza una plantilla
return jsonify({"message": "Dashboard IoT activo"})
@app.get("/api/latest")
def api_latest():
return jsonify(sensor_data)
def start_mqtt():
mqtt_client.connect(MQTT_BROKER, MQTT_PORT, 60)
mqtt_client.loop_start()
if __name__ == "__main__":
init_db()
start_mqtt()
socketio.run(app, host="0.0.0.0", port=5000, debug=True)