Un nodo Raspberry Pi Zero 2 W MQTT te da un ordenador Linux completo del tamaño de un chicle, lo que lo hace ideal para nodos sensores que necesitan Python, TLS y acceso remoto, pero no una placa de tamaño completo. En esta guía configurarás una Zero 2 W sin pantalla, recortarás su consumo, leerás un sensor ambiental BME280 y publicarás las lecturas y la salud del dispositivo por MQTT 5, con el blindaje necesario para funcionar desatendida durante meses.
Por qué la Zero 2 W es un buen nodo sensor
La Zero 2 W tiene un Arm Cortex-A53 de cuatro núcleos y 64 bits, 512 MB de RAM, Wi-Fi de 2,4 GHz y Bluetooth, y el conector GPIO estándar de 40 pines. Es suficiente para ejecutar Python, paho-mqtt con TLS y un par de sensores con margen de sobra, consumiendo bastante menos que una Pi 4 o una Pi 5.
Sin embargo, no es un microcontrolador. No puede entrar en deep sleep entre lecturas y arranca Linux desde una tarjeta SD. Si tu nodo tiene que funcionar con baterías durante meses, un ESP32 es la mejor herramienta; nuestra comparativa Raspberry Pi vs ESP32 explica las ventajas y desventajas. La Zero 2 W brilla donde hay alimentación de red o USB y valoras las herramientas de Linux, el acceso por SSH y Python por encima del último milivatio.
Lista de componentes
| Componente | Propósito |
|---|---|
| Raspberry Pi Zero 2 W | El propio nodo |
| Fuente micro USB de 5 V y 2,5 A de calidad | La subtensión es la causa más común de cuelgues |
| Tarjeta microSD clase A2, de 16 GB o más | Sistema operativo y aplicación |
| Placa BME280 (I2C) | Temperatura, humedad, presión |
| Conector de 40 pines soldado o cables soldados | La Zero 2 W viene sin conector |
Configuración sin pantalla con Raspberry Pi OS Lite
Usa Raspberry Pi Imager para grabar Raspberry Pi OS Lite (64-bit). En las opciones avanzadas define el hostname, activa SSH con una clave pública, introduce tu red Wi-Fi y el país, y crea tu usuario. La imagen Lite no tiene escritorio, lo que ahorra RAM, escrituras en el almacenamiento y energía. Arranca la Zero, espera un minuto y conéctate:
ssh pi@zero-node-01.local
sudo apt update && sudo apt full-upgrade -y
sudo raspi-config nonint do_i2c 0
sudo apt install -y python3-venv i2c-tools
Recuerda que la Zero 2 W solo admite Wi-Fi de 2,4 GHz. Si nunca aparece en la red, comprueba que tu punto de acceso emite en la banda de 2,4 GHz y que el país del Wi-Fi está bien configurado.
Reducir el consumo y el desgaste de la tarjeta SD
Añade estas líneas a /boot/firmware/config.txt y reinicia:
# Desactiva Bluetooth si no lo necesitas
dtoverlay=disable-bt
# Apaga el LED de actividad
dtparam=act_led_trigger=none
Después mantén el journal del sistema en RAM para que los logs rutinarios no desgasten la tarjeta SD:
sudo mkdir -p /etc/systemd/journald.conf.d
printf "[Journal]\nStorage=volatile\nRuntimeMaxUse=16M\n" | \
sudo tee /etc/systemd/journald.conf.d/volatile.conf
sudo systemctl restart systemd-journald
sudo systemctl disable --now bluetooth hciuart 2>/dev/null || true
Hay un ajuste de energía que es un compromiso deliberado. El ahorro de energía del Wi-Fi reduce el consumo, pero puede retrasar los paquetes entrantes lo suficiente como para provocar timeouts de keepalive y reconexiones. Si ves desconexiones frecuentes en tus logs, desactívalo con sudo iw wlan0 set power_save off y hazlo permanente mediante NetworkManager. Para un nodo que solo publica, dejar activado el ahorro de energía suele estar bien.
Cableado del BME280
| BME280 | Zero 2 W |
|---|---|
| VIN | 3,3 V (pin físico 1) |
| GND | GND (pin físico 6) |
| SCL | GPIO3 / SCL (pin físico 5) |
| SDA | GPIO2 / SDA (pin físico 3) |
Ejecuta i2cdetect -y 1. Deberías ver el sensor en la dirección 0x76 o 0x77. Anota cuál; el script usa 0x76 por defecto.
Instalación del entorno de Python
mkdir -p ~/node && cd ~/node
python3 -m venv .venv
source .venv/bin/activate
pip install "paho-mqtt>=2.0" adafruit-circuitpython-bme280
El script Raspberry Pi Zero 2 W MQTT
Este script usa MQTT 5 para que cada lectura lleve un intervalo de caducidad del mensaje: si un suscriptor con sesión persistente está desconectado más de cinco minutos, las lecturas obsoletas se descartan en lugar de entregarse tarde. También publica un mensaje de salud con la temperatura de la CPU, la señal Wi-Fi y el tiempo en marcha, algo de un valor incalculable cuando el nodo está escondido en un armario. Guárdalo como node.py:
#!/usr/bin/env python3
"""Pi Zero 2 W sensor node: BME280 + health metrics over MQTT 5."""
import json
import os
import time
import uuid
import board
import paho.mqtt.client as mqtt
from adafruit_bme280 import basic as adafruit_bme280
from paho.mqtt.packettypes import PacketTypes
from paho.mqtt.properties import Properties
BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"zero2w-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/4b9e27/zero-node-01")
INTERVAL = int(os.getenv("PUBLISH_INTERVAL", "60"))
BME_ADDRESS = int(os.getenv("BME280_ADDRESS", "0x76"), 16)
i2c = board.I2C()
bme = adafruit_bme280.Adafruit_BME280_I2C(i2c, address=BME_ADDRESS)
expiry = Properties(PacketTypes.PUBLISH)
expiry.MessageExpiryInterval = 300
def cpu_temp():
with open("/sys/class/thermal/thermal_zone0/temp") as f:
return round(int(f.read()) / 1000, 1)
def wifi_rssi():
try:
with open("/proc/net/wireless") as f:
for line in f:
if line.strip().startswith("wlan0:"):
return float(line.split()[3].rstrip("."))
except (OSError, ValueError, IndexError):
pass
return None
def uptime_s():
with open("/proc/uptime") as f:
return int(float(f.read().split()[0]))
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print(f"Connection refused: {reason_code}")
return
print(f"Connected as {CLIENT_ID}")
client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
client = mqtt.Client(
mqtt.CallbackAPIVersion.VERSION2,
client_id=CLIENT_ID,
protocol=mqtt.MQTTv5,
)
client.on_connect = on_connect
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=2, max_delay=120)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
client.tls_set()
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()
try:
while True:
now = int(time.time())
reading = {
"temperature": round(bme.temperature, 2),
"humidity": round(bme.relative_humidity, 1),
"pressure": round(bme.pressure, 1),
"ts": now,
}
health = {
"cpu_temp": cpu_temp(),
"rssi": wifi_rssi(),
"uptime": uptime_s(),
"ts": now,
}
client.publish(f"{PREFIX}/env", json.dumps(reading), qos=1, properties=expiry)
client.publish(f"{PREFIX}/health", json.dumps(health), qos=0, properties=expiry)
print(reading, health)
time.sleep(INTERVAL)
except KeyboardInterrupt:
pass
finally:
client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
client.loop_stop()
client.disconnect()
Pruébalo en primer plano con python node.py y observa desde otro equipo:
mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-4b9e27 -V mqttv5 \
-t 'connectmq/demo/4b9e27/#' -v
El servidor MQTT público gratuito admite MQTT 5 y sirve para esta comprobación, pero todo lo que hay en él es legible públicamente, así que usa un prefijo aleatorio como 4b9e27 y no lo uses con datos de producción.
Funcionamiento desatendido
Un nodo sensor solo es útil si se recupera solo tras un corte de luz o un fallo. Crea /etc/systemd/system/sensor-node.service:
[Unit]
Description=Zero 2 W MQTT sensor node
After=network-online.target
Wants=network-online.target
[Service]
User=pi
WorkingDirectory=/home/pi/node
EnvironmentFile=/home/pi/node/node.env
ExecStart=/home/pi/node/.venv/bin/python node.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target
Pon tu configuración de conexión en /home/pi/node/node.env y restríngela con chmod 600:
MQTT_HOST=broker.connectmq.com
MQTT_PORT=8883
MQTT_USERNAME=YOUR_USERNAME
MQTT_PASSWORD=YOUR_PASSWORD
MQTT_CLIENT_ID=YOUR_CLIENT_ID
MQTT_PREFIX=site1/office/zero-node-01
Actívalo con sudo systemctl enable --now sensor-node. Para saber más sobre archivos de servicio y logs, consulta ejecutar un script MQTT de Python al arrancar.
Actualizar nodos en campo
Aunque el nodo esté montado en una pared, seguirás queriendo cambiar su código. Mantén la aplicación en un repositorio git y actualiza con git pull seguido de sudo systemctl restart sensor-node por SSH. Como la configuración de conexión vive en node.env y no en el script, el mismo código se ejecuta en todos los nodos y solo cambia el archivo de entorno. Antes de desplegar un cambio en todos los nodos, pruébalo en uno y vigila sus topics health y status durante un día. Un nodo que deja de publicar mensajes de salud pero sigue mostrando online suele estar atascado en una lectura del sensor, lo que es una pista para añadir timeouts al acceso al hardware.
Lista de blindaje
- Usa una fuente oficial o de alta calidad; ejecuta
vcgencmd get_throttledy esperathrottled=0x0. - Mantén el journal en RAM y evita escribir archivos en el bucle de publicación.
- Activa el watchdog de hardware con
RuntimeWatchdogSec=15en/etc/systemd/system.confpara que un kernel congelado se reinicie. - Monta el BME280 con un cable corto, alejado de la placa; la Zero calienta el aire a su alrededor.
- Publica datos de salud y define el last will para que el topic de estado muestre
offlinecuando el nodo desaparezca. - Usa TLS y credenciales por dispositivo antes de que el nodo salga de tu mesa.
Escalar a muchos nodos
Una Zero 2 W es un proyecto; veinte son una flota. Da a cada nodo sus propias credenciales y su client ID, un topic predecible como site1/<room>/<node>/env y la misma imagen. Un broker MQTT gestionado elimina la necesidad de ejecutar y proteger tu propio servidor. Con ConnectMQ, el client ID de cada nodo está vinculado a sus credenciales, la vista de dispositivos del portal lista los nodos según su jerarquía de topics y una regla de alerta por umbral puede avisarte cuando una sala tiene demasiada humedad. El plan gratuito Serverless permite hasta 25 conexiones, lo que cubre una flota pequeña más un dashboard.
Si prefieres sensores más sencillos, la guía de Raspberry Pi con DS18B20 y MQTT funciona sin cambios en la Zero 2 W, y el tutorial de MQTT con Raspberry Pi cubre los fundamentos de publicación y suscripción en los que se basa este nodo.
Empieza con ConnectMQ
Pon tus nodos Zero 2 W en un broker MQTT en la nube al que puedan llegar desde cualquier red. Regístrate gratis en ConnectMQ, sin tarjeta de crédito, crea un broker y pega el nombre de usuario, la contraseña y el client ID generados en node.env. Tu nodo se conecta por TLS en el puerto 8883 con MQTT 5, y cada lectura aparece en el explorador de topics en vivo.
Preguntas frecuentes
¿Puede una Raspberry Pi Zero 2 W funcionar con baterías?
Solo durante periodos cortos, porque no puede entrar en deep sleep y consume energía continuamente. Para una batería de larga duración usa un microcontrolador como el ESP32 y reserva la Zero 2 W para ubicaciones con alimentación.
¿Bastan 512 MB de RAM para un nodo sensor MQTT?
Sí. Un script de Python con paho-mqtt, TLS y una librería de sensor usa una pequeña fracción en Raspberry Pi OS Lite, y deja espacio para un segundo servicio.
¿Por qué mi Zero 2 W se desconecta continuamente de MQTT?
Las causas habituales son una fuente de alimentación débil, una señal de 2,4 GHz pobre o un ahorro de energía del Wi-Fi demasiado agresivo. Revisa vcgencmd get_throttled, el RSSI del mensaje de salud y prueba a desactivar el ahorro de energía.
¿La Zero 2 W admite MQTT 5?
Sí. MQTT 5 es una función de la librería cliente, y paho-mqtt 2.x lo admite por completo, incluidas la caducidad de mensajes y las user properties.



