Conectar Sensores Industriales a BD con Python
Tutorial completo para conectar sensores industriales a PostgreSQL con Python y Raspberry Pi. Modbus, 4-20mA, I2C, código y dashboard con Grafana.
Todo empezó con una pregunta que me hizo un cliente: “¿Podemos saber la temperatura de los hornos sin estar en planta?”. Tenían 4 hornos industriales con sensores analógicos 4-20mA conectados a un PLC que mostraba los valores en una pantalla local. Querían históricos, tendencias y acceso remoto. El presupuesto: prácticamente cero.
La solución: una Raspberry Pi, un par de módulos de adquisición, Python, PostgreSQL y Grafana. Coste total: menos de 200€. Lleva funcionando más de un año sin fallos.
En este tutorial se muestra paso a paso cómo conectar sensores industriales a una base de datos con Python y Raspberry Pi. Desde los tipos de sensores hasta el dashboard final en Grafana, pasando por todo el código necesario.
Tipos de Sensores Industriales: Qué Puedes Conectar
Antes de escribir una sola línea de código, necesitas entender qué tipo de señal genera tu sensor. En el mundo industrial hay tres grandes familias:
Sensores analógicos (4-20mA y 0-10V)
La señal estándar en la industria. Un transmisor de presión, temperatura o caudal genera una corriente proporcional entre 4 y 20 miliamperios. ¿Por qué 4-20mA y no 0-20mA? Porque si la corriente cae a 0mA, sabes que hay un cable roto (una señal de 4mA significa “valor mínimo del rango”, 0mA significa “algo va mal”).
- Ejemplos: transmisores de presión, temperatura (PT100/PT1000 con transmisor), nivel, caudal.
- Ventajas: señal robusta, inmune a interferencias, distancias largas (hasta 1km).
- Para conectar a Raspberry Pi: necesitas un conversor ADC con entrada 4-20mA (como el módulo MCP3008 con resistencia shunt, o directamente un módulo industrial como el Waveshare Industrial 8-CH).
Sensores con comunicación digital (Modbus RTU/TCP)
Muchos sensores industriales modernos hablan Modbus, el protocolo más extendido en automatización. Pueden ser Modbus RTU (serial RS-485) o Modbus TCP (Ethernet).
- Ejemplos: medidores de energía, analizadores de redes, sensores de temperatura/humedad industriales, variadores de frecuencia.
- Ventajas: múltiples variables en un solo cable, autodiagnóstico, configuración remota.
- Para conectar a Raspberry Pi: un conversor USB-RS485 para Modbus RTU (~10€) o directamente por Ethernet para Modbus TCP.
Si ya tienes experiencia con comunicación Modbus TCP con Python, la mitad del trabajo está hecho.
Sensores I2C/SPI (más hobby, menos industrial)
Sensores de prototipado como el BME280 (temperatura/humedad/presión) o el ADS1115 (ADC de 16 bits). No son de grado industrial, pero funcionan bien para proyectos de monitorización no crítica.
- Ejemplos: BME280, DHT22, ADS1115, sensores de gas MQ.
- Ventajas: baratos (2-15€), fáciles de conectar, documentación abundante.
- Limitaciones: no aptos para entornos duros (temperatura extrema, vibraciones, humedad). Sin certificaciones industriales.
- Para conectar a Raspberry Pi: directamente a los pines GPIO.
Preparar la Raspberry Pi para Adquisición de Datos
Hardware necesario
Para un proyecto básico pero funcional:
- Raspberry Pi 4 o 5 (4GB RAM mínimo): ~70€
- Tarjeta microSD industrial (tipo SanDisk Industrial o similar, con mayor durabilidad): ~20€
- Fuente de alimentación oficial: ~10€
- Carcasa industrial DIN-rail (tipo Sixfab o impresa en 3D): ~15-30€
- Conversor USB-RS485 (para Modbus RTU): ~10€
- Módulo ADC industrial (para señales 4-20mA): ~30-60€
Total: 155-200€ por nodo de adquisición.
Instalación del sistema operativo
# Instalar Raspberry Pi OS Lite (sin escritorio — es un servidor)
# Usar Raspberry Pi Imager para flashear la SD
# Tras el primer arranque, actualizar
sudo apt update && sudo apt upgrade -y
# Instalar dependencias
sudo apt install -y python3-pip python3-venv postgresql-client git
# Crear entorno virtual
python3 -m venv ~/datalogger
source ~/datalogger/bin/activate
# Instalar librerías Python
pip install pymodbus psycopg2-binary paho-mqtt influxdb-client schedule
Configuración de la interfaz serial (para Modbus RTU)
# Habilitar interfaz serial
sudo raspi-config
# → Interface Options → Serial Port → Login shell: No → Serial port hardware: Yes
# Verificar que el conversor USB-RS485 se detecta
ls /dev/ttyUSB*
# Debería mostrar /dev/ttyUSB0
# Dar permisos al usuario
sudo usermod -a -G dialout $USER
Leer Sensores Modbus RTU con Python
Vamos con el primer caso real: leer un sensor de temperatura/humedad industrial Modbus RTU. Usaremos la librería pymodbus.
"""
read_modbus_sensor.py
Lee un sensor Modbus RTU (ejemplo: transmisor de temperatura).
"""
from pymodbus.client import ModbusSerialClient
from pymodbus.exceptions import ModbusException
import time
# Configuración del puerto serial
client = ModbusSerialClient(
port='/dev/ttyUSB0',
baudrate=9600,
parity='N',
stopbits=1,
bytesize=8,
timeout=3
)
# Configuración del sensor
SLAVE_ID = 1 # Dirección Modbus del sensor
TEMP_REGISTER = 0 # Registro de temperatura (consultar manual del sensor)
HUM_REGISTER = 1 # Registro de humedad
def read_sensor():
"""Lee temperatura y humedad del sensor Modbus."""
if not client.connect():
print("Error: no se puede conectar al puerto serial")
return None, None
try:
# Leer registros holding (función 03)
result = client.read_holding_registers(
address=TEMP_REGISTER,
count=2,
slave=SLAVE_ID
)
if result.isError():
print(f"Error Modbus: {result}")
return None, None
# Los valores suelen venir multiplicados x10 o x100
# Consultar la documentación de tu sensor específico
temperature = result.registers[0] / 10.0 # Ej: 234 → 23.4°C
humidity = result.registers[1] / 10.0 # Ej: 567 → 56.7%
return temperature, humidity
except ModbusException as e:
print(f"Excepción Modbus: {e}")
return None, None
finally:
client.close()
# Test rápido
if __name__ == "__main__":
temp, hum = read_sensor()
if temp is not None:
print(f"Temperatura: {temp}°C")
print(f"Humedad: {hum}%")
else:
print("No se pudo leer el sensor")
Leer Señales Analógicas 4-20mA
Para señales 4-20mA necesitas un módulo ADC (conversor analógico-digital). Usaré el ADS1115, que es de 16 bits y se conecta por I2C:
"""
read_4_20ma.py
Lee una señal 4-20mA a través de un ADS1115 con resistencia shunt de 250Ω.
El sensor mide presión: 4mA = 0 bar, 20mA = 10 bar.
"""
import board
import busio
import adafruit_ads1x15.ads1115 as ADS
from adafruit_ads1x15.analog_in import AnalogIn
# Configuración I2C
i2c = busio.I2C(board.SCL, board.SDA)
ads = ADS.ADS1115(i2c)
ads.gain = 2/3 # Rango ±6.144V (para leer hasta 5V)
# Canal 0 del ADS1115
channel = AnalogIn(ads, ADS.P0)
# Configuración del sensor
SHUNT_RESISTANCE = 250 # Ohmios (resistencia shunt: V = I × R)
SENSOR_MIN_MA = 4.0 # 4mA = valor mínimo
SENSOR_MAX_MA = 20.0 # 20mA = valor máximo
MEASURE_MIN = 0.0 # 0 bar a 4mA
MEASURE_MAX = 10.0 # 10 bar a 20mA
def read_pressure():
"""Lee la presión del transmisor 4-20mA."""
# Leer voltaje del ADC
voltage = channel.voltage
# Calcular corriente: I = V / R
current_ma = (voltage / SHUNT_RESISTANCE) * 1000
# Verificar si el sensor está conectado
if current_ma < 3.5: # Debería ser mínimo 4mA
print(f"⚠️ Corriente muy baja ({current_ma:.2f}mA) — posible cable roto")
return None
if current_ma > 21.0: # No debería superar 20mA
print(f"⚠️ Corriente muy alta ({current_ma:.2f}mA) — posible cortocircuito")
return None
# Escalar al rango de medida
pressure = ((current_ma - SENSOR_MIN_MA) / (SENSOR_MAX_MA - SENSOR_MIN_MA)) * \
(MEASURE_MAX - MEASURE_MIN) + MEASURE_MIN
return round(pressure, 3)
# Test
if __name__ == "__main__":
pressure = read_pressure()
if pressure is not None:
print(f"Presión: {pressure} bar")
Almacenar Datos en PostgreSQL
Ahora conectamos la lectura de sensores con una base de datos PostgreSQL. Puedes instalar PostgreSQL en la propia Raspberry Pi o usar un servidor externo.
Crear la base de datos y tabla
-- Ejecutar en PostgreSQL
CREATE DATABASE sensor_data;
\c sensor_data
CREATE TABLE measurements (
id BIGSERIAL PRIMARY KEY,
timestamp TIMESTAMPTZ NOT NULL DEFAULT NOW(),
sensor_id VARCHAR(50) NOT NULL,
sensor_type VARCHAR(30) NOT NULL,
value DOUBLE PRECISION NOT NULL,
unit VARCHAR(20) NOT NULL,
quality VARCHAR(10) DEFAULT 'GOOD'
);
-- Índice para consultas por tiempo (fundamental para rendimiento)
CREATE INDEX idx_measurements_time ON measurements (timestamp DESC);
CREATE INDEX idx_measurements_sensor ON measurements (sensor_id, timestamp DESC);
-- Particionar por mes para tablas grandes (opcional, recomendado si >1M filas/mes)
-- CREATE TABLE measurements (
-- ...
-- ) PARTITION BY RANGE (timestamp);
Script de adquisición continua
"""
datalogger.py
Adquisición continua de datos industriales con almacenamiento en PostgreSQL.
"""
import psycopg2
from psycopg2.extras import execute_batch
from datetime import datetime, timezone
import time
import logging
from collections import deque
# Importar funciones de lectura de sensores
from read_modbus_sensor import read_sensor as read_modbus
from read_4_20ma import read_pressure
# Configuración
DB_CONFIG = {
"host": "192.168.1.100", # IP del servidor PostgreSQL
"port": 5432,
"dbname": "sensor_data",
"user": "datalogger",
"password": "secure_password" # En producción: usar variables de entorno
}
SAMPLE_INTERVAL = 5 # Leer cada 5 segundos
BATCH_SIZE = 12 # Insertar en lotes de 12 (1 minuto de datos)
MAX_RETRIES = 3
# Buffer para inserción por lotes
buffer = deque()
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s [%(levelname)s] %(message)s',
handlers=[
logging.FileHandler('/var/log/datalogger.log'),
logging.StreamHandler()
]
)
def get_db_connection():
"""Obtiene conexión a PostgreSQL con reintentos."""
for attempt in range(MAX_RETRIES):
try:
conn = psycopg2.connect(**DB_CONFIG)
conn.autocommit = False
return conn
except psycopg2.OperationalError as e:
logging.warning(f"Intento {attempt+1}/{MAX_RETRIES} de conexión fallido: {e}")
time.sleep(5)
raise Exception("No se pudo conectar a PostgreSQL")
def insert_batch(measurements: list):
"""Inserta un lote de mediciones en PostgreSQL."""
conn = get_db_connection()
try:
with conn.cursor() as cur:
execute_batch(cur, """
INSERT INTO measurements (timestamp, sensor_id, sensor_type, value, unit, quality)
VALUES (%s, %s, %s, %s, %s, %s)
""", measurements)
conn.commit()
logging.info(f"Insertadas {len(measurements)} mediciones")
except Exception as e:
conn.rollback()
logging.error(f"Error insertando datos: {e}")
raise
finally:
conn.close()
def read_all_sensors() -> list:
"""Lee todos los sensores configurados y devuelve mediciones."""
now = datetime.now(timezone.utc)
measurements = []
# Sensor Modbus: temperatura y humedad
try:
temp, hum = read_modbus()
if temp is not None:
measurements.append((now, "HORNO_01_TEMP", "modbus", temp, "°C", "GOOD"))
if hum is not None:
measurements.append((now, "HORNO_01_HUM", "modbus", hum, "%", "GOOD"))
except Exception as e:
logging.error(f"Error leyendo Modbus: {e}")
measurements.append((now, "HORNO_01_TEMP", "modbus", 0, "°C", "BAD"))
# Sensor analógico: presión
try:
pressure = read_pressure()
if pressure is not None:
measurements.append((now, "LINEA_01_PRESION", "4-20mA", pressure, "bar", "GOOD"))
except Exception as e:
logging.error(f"Error leyendo 4-20mA: {e}")
measurements.append((now, "LINEA_01_PRESION", "4-20mA", 0, "bar", "BAD"))
return measurements
def main():
"""Bucle principal de adquisición de datos."""
logging.info("Datalogger iniciado")
while True:
try:
# Leer sensores
readings = read_all_sensors()
buffer.extend(readings)
# Insertar cuando el buffer está lleno
if len(buffer) >= BATCH_SIZE:
batch = [buffer.popleft() for _ in range(min(BATCH_SIZE, len(buffer)))]
insert_batch(batch)
time.sleep(SAMPLE_INTERVAL)
except KeyboardInterrupt:
# Insertar datos restantes antes de salir
if buffer:
insert_batch(list(buffer))
logging.info("Datalogger detenido por el usuario")
break
except Exception as e:
logging.error(f"Error en bucle principal: {e}")
time.sleep(10) # Esperar antes de reintentar
if __name__ == "__main__":
main()
Ejecutar como servicio systemd
Para que el datalogger arranque automáticamente con la Raspberry Pi:
# Crear servicio systemd
sudo tee /etc/systemd/system/datalogger.service << 'EOF'
[Unit]
Description=Industrial Sensor Datalogger
After=network.target postgresql.service
[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/datalogger
ExecStart=/home/pi/datalogger/venv/bin/python datalogger.py
Restart=always
RestartSec=10
StandardOutput=journal
StandardError=journal
[Install]
WantedBy=multi-user.target
EOF
# Habilitar e iniciar
sudo systemctl enable datalogger
sudo systemctl start datalogger
# Verificar estado
sudo systemctl status datalogger
Crear un Dashboard en Grafana
Con los datos en PostgreSQL, montar un dashboard en Grafana es directo. Grafana se puede instalar en la misma Raspberry Pi o en un servidor separado.
Instalar Grafana en Raspberry Pi
# Añadir repositorio de Grafana
sudo apt install -y adduser libfontconfig1
wget https://dl.grafana.com/oss/release/grafana_11.1.0_armhf.deb
sudo dpkg -i grafana_11.1.0_armhf.deb
# Habilitar e iniciar
sudo systemctl enable grafana-server
sudo systemctl start grafana-server
# Acceder en http://<IP_RASPBERRY>:3000
# Usuario: admin / Password: admin (cambiar en primer acceso)
Configurar el datasource PostgreSQL
En Grafana → Configuration → Data Sources → Add → PostgreSQL:
- Host:
localhost:5432(o la IP de tu servidor PostgreSQL) - Database:
sensor_data - User:
datalogger - TLS: desactivar si es red local
Queries de ejemplo para paneles
Temperatura en tiempo real (últimas 6 horas):
SELECT
timestamp AS time,
value AS "Temperatura (°C)"
FROM measurements
WHERE sensor_id = 'HORNO_01_TEMP'
AND quality = 'GOOD'
AND timestamp > NOW() - INTERVAL '6 hours'
ORDER BY timestamp
Presión con umbrales de alarma:
SELECT
timestamp AS time,
value AS "Presión (bar)",
8.0 AS "Límite alto",
2.0 AS "Límite bajo"
FROM measurements
WHERE sensor_id = 'LINEA_01_PRESION'
AND quality = 'GOOD'
AND timestamp > NOW() - INTERVAL '24 hours'
ORDER BY timestamp
Media horaria para tendencias largas:
SELECT
date_trunc('hour', timestamp) AS time,
AVG(value) AS "Temp media",
MAX(value) AS "Temp máxima",
MIN(value) AS "Temp mínima"
FROM measurements
WHERE sensor_id = 'HORNO_01_TEMP'
AND quality = 'GOOD'
AND timestamp > NOW() - INTERVAL '7 days'
GROUP BY date_trunc('hour', timestamp)
ORDER BY time
Con estas queries tienes un dashboard funcional con gráficas de tiempo real, tendencias históricas y límites de alarma visibles. Si quieres ir más allá, puedes añadir alertas en Grafana para que te avise por email o Telegram cuando un valor supere un umbral.
Publicar Datos por MQTT para Integración
Si además de almacenar localmente quieres integrar con otros sistemas (SCADA, MES, dashboards n8n/), publica los datos por MQTT:
"""
mqtt_publisher.py
Publica datos de sensores por MQTT además de almacenarlos.
Añadir al datalogger.py principal.
"""
import paho.mqtt.client as mqtt
import json
MQTT_BROKER = "localhost" # o la IP de tu broker
MQTT_PORT = 1883
MQTT_TOPIC_BASE = "plant/sensors"
mqtt_client = mqtt.Client()
mqtt_client.connect(MQTT_BROKER, MQTT_PORT)
mqtt_client.loop_start()
def publish_reading(sensor_id: str, value: float, unit: str):
"""Publica una lectura por MQTT."""
payload = json.dumps({
"sensor_id": sensor_id,
"value": value,
"unit": unit,
"timestamp": datetime.now(timezone.utc).isoformat()
})
topic = f"{MQTT_TOPIC_BASE}/{sensor_id}"
mqtt_client.publish(topic, payload, qos=1)
Consideraciones de Fiabilidad en Producción
Una Raspberry Pi en un entorno industrial necesita cuidados extra:
Protección de la tarjeta SD
Las SD tienen escrituras limitadas. Para reducir el desgaste:
# Montar /tmp y /var/log en RAM
echo "tmpfs /tmp tmpfs defaults,noatime,nosuid,size=100m 0 0" | sudo tee -a /etc/fstab
echo "tmpfs /var/log tmpfs defaults,noatime,nosuid,size=50m 0 0" | sudo tee -a /etc/fstab
# Reducir escrituras de swap
echo "vm.swappiness=1" | sudo tee -a /etc/sysctl.conf
UPS para Raspberry Pi
Un apagón brusco puede corromper la SD. Usa un UPS tipo PiJuice (~40€) o similar para apagado limpio.
Watchdog hardware
La Raspberry Pi tiene un watchdog hardware integrado. Actívalo para reinicio automático si el sistema se cuelga:
# Activar watchdog
sudo apt install watchdog
echo "bcm2835_wdt" | sudo tee -a /etc/modules
Monitorización remota
Configura el datalogger para que publique su propio estado de salud:
def publish_health():
"""Publica estado de salud del nodo."""
import psutil
health = {
"cpu_percent": psutil.cpu_percent(),
"memory_percent": psutil.virtual_memory().percent,
"disk_percent": psutil.disk_usage('/').percent,
"temperature": psutil.sensors_temperatures().get('cpu_thermal', [{}])[0].current
if psutil.sensors_temperatures().get('cpu_thermal') else None,
"uptime_hours": (time.time() - psutil.boot_time()) / 3600
}
mqtt_client.publish("plant/nodes/rpi01/health", json.dumps(health), qos=1)
Preguntas Frecuentes
¿Puedo usar una Raspberry Pi en un entorno industrial real?
Para monitorización no crítica, sí. Para control de procesos, no — usa un PLC certificado. La Raspberry Pi es excelente como gateway de datos, datalogger o edge node, pero no tiene las certificaciones ni la fiabilidad de un equipo industrial. Dicho esto, con las precauciones adecuadas (UPS, carcasa industrial, SD de calidad), puede funcionar durante años.
¿Cuántos sensores puedo conectar a una sola Raspberry Pi?
Depende del tipo. Por Modbus RTU a un bus RS-485 puedes conectar hasta 247 dispositivos (teóricamente). Por I2C, hasta 127 direcciones. En la práctica, con muestreo cada 5 segundos, una Raspberry Pi 4 maneja cómodamente 50-100 variables sin problemas de rendimiento.
¿PostgreSQL o InfluxDB para datos de sensores?
InfluxDB está optimizada para series temporales y consultas de tipo “dame la media de los últimos 30 minutos”. PostgreSQL con la extensión TimescaleDB te da lo mejor de ambos mundos: series temporales optimizadas + SQL completo. Para empezar, PostgreSQL estándar es más que suficiente.
¿Cómo gestiono la pérdida de conectividad con la base de datos?
El script de datalogger ya incluye un buffer local. Para mayor resiliencia, puedes almacenar en un SQLite local cuando PostgreSQL no esté disponible y sincronizar cuando se recupere la conexión. Es el patrón store-and-forward.
¿Qué alternativas hay a la Raspberry Pi para esto?
El Siemens IOT2050 (~300€) es un gateway industrial certificado que corre Debian. El MOXA UC-8100 es otra opción robusta. Si necesitas más potencia, un mini PC industrial (tipo Advantech o Dell Edge Gateway). La Raspberry Pi es la opción más económica para empezar.
Conclusión: Tu Primera Plataforma IoT Industrial por Menos de 200€
Conectar sensores industriales a una base de datos con Python y Raspberry Pi es un proyecto accesible que te da resultados reales: datos históricos, tendencias, alertas y un dashboard profesional. No necesitas un presupuesto de seis cifras ni un equipo de IT dedicado.
Lo que has aprendido en este tutorial te sirve tanto para un proyecto personal de monitorización de tu taller como para un prototipo rápido en una planta real. Cuando el concepto esté probado y necesites escalar, migras a hardware industrial manteniendo la misma lógica en Python y la misma base de datos PostgreSQL.
Mi recomendación: empieza con un sensor Modbus y la base de datos. Cuando tengas datos fluyendo, monta Grafana y sorpréndete con lo que puedes ver. Una vez que pruebas a tomar decisiones con datos en vez de con intuición, no hay vuelta atrás.
¿Tienes un proyecto de adquisición de datos con Raspberry Pi? ¿Has conectado sensores industriales a tu propia plataforma? Cuéntame tu experiencia — me encanta ver cómo cada uno resuelve estos retos a su manera.
Preguntas frecuentes
¿Qué sensores industriales puedo conectar a una Raspberry Pi?
La Raspberry Pi puede leer sensores de temperatura (PT100/PT1000 vía MAX31865, termopares vía MAX6675), humedad (DHT22, BME280), presión (BMP280), vibración (ADXL345), corriente (ACS712), nivel y caudal. Para señales 4-20mA o 0-10V industriales necesitas un conversor ADC como ADS1115 o MCP3008.
¿Qué base de datos es mejor para almacenar datos de sensores industriales?
Para series temporales, las más recomendadas son InfluxDB (optimizada para datos de sensores, con retención automática) y TimescaleDB (extensión de PostgreSQL). Para volúmenes menores o si ya tienes PostgreSQL, este es suficiente. SQLite funciona para prototipos pero no para producción con múltiples sensores escribiendo concurrentemente.
¿Con qué frecuencia debería leer los sensores industriales?
Depende del proceso: temperaturas y presiones lentas cada 1-10 segundos, vibración cada 100ms-1s, corriente para protección cada 10-50ms. Para monitorización general, 1 lectura por segundo por sensor es un buen punto de partida. Almacena promedios cada minuto para reducir volumen de datos a largo plazo.
¿Puedo usar una Raspberry Pi en un entorno industrial real?
Para prototipos y monitorización no crítica, sí. Para producción, usa una carcasa industrial con riel DIN (como las de Sequent Microsystems), fuente de alimentación redundante y almacenamiento en SSD en vez de SD. Para aplicaciones críticas de control, un PLC sigue siendo más fiable; la Raspberry Pi es mejor como gateway de datos.
¿Cómo envío los datos de sensores desde la Raspberry Pi a la nube?
Las opciones más comunes son MQTT (publicar en un broker como Mosquitto o HiveMQ Cloud), HTTP/REST (enviar a una API), o protocolo nativo del cloud (AWS IoT Core, Azure IoT Hub). MQTT es el más eficiente en ancho de banda y soporta conexiones intermitentes. Python con la librería paho-mqtt es la combinación más usada.
Sigue leyendo
Edge Computing Industrial: Procesar Datos en Planta
Descubre cómo el edge computing industrial permite procesar datos en planta sin depender de la nube. Arquitectura, hardware, MQTT y casos de uso reales.
Leer artículoIoT Industrial con MQTT y AWS: Datos a la Nube
Aprende a conectar sensores industriales a AWS IoT Core con MQTT. Tutorial paso a paso con código Python, arquitectura IIoT y buenas prácticas de seguridad.
Leer artículo