🛠 Client MQTT : télémétrie IoT légère sur la Pico W
Objetivos
MQTT es EL protocolo de los objetos conectados: ligero (cabecera de 2 bytes), pub/sub, adaptado a enlaces de radio inestables. El ejemplo oficial cliente MQTT figura en pico_w/wifi/ del repositorio pico-examples (C SDK); en MicroPython, puedes hablar MQTT sin dependencias construyendo los paquetes a mano sobre un socket TCP — excelente para entender el protocolo. Implementarás CONNECT + PUBLISH QoS 0, el patrón de toda la telemetría de sensores.
Material
- 1 × Raspberry Pi Pico W + firmware MicroPython
_picow - Un broker MQTT accesible en la LAN (Mosquitto en un NAS/Raspberry Pi 5, o broker público de prueba — cuidado con los datos enviados)
- Consola serie 115200 baudios; puerto TCP 1883 abierto en el broker
Código completo
# mqtt_pub.py — MQTT 3.1.1 minimal (CONNECT + PUBLISH QoS 0) sur socket
import machine, network, socket, time, struct
wlan = network.WLAN; wlan.active(True)
if not wlan.isconnected:
wlan.connect('my_ssid', 'my_password')
while not wlan.isconnected:
machine.idle
def remaining_length(n): # encodage varint MQTT
out = b''
while True:
b = n % 128; n //= 128
if n: b |= 0x80
out += bytes([b])
if not n: return out
def connect(sock, client_id):
proto = b'\x00\x04MQTT\x04\x02\x00\x3c' # level 4, clean session,
cid = struct.pack('>H', len(client_id)) + client_id.encode # keepalive 60s
body = proto + cid
sock.send(b'\x10' + remaining_length(len(body)) + body)
return sock.recv(4) # CONNACK 0x20 0x02 0x00 = accepté
def publish(sock, topic, payload):
t = struct.pack('>H', len(topic)) + topic.encode
p = payload.encode if isinstance(payload, str) else payload
body = t + p
sock.send(b'\x30' + remaining_length(len(body)) + body) # QoS 0
s = socket.socket
s.connect(('192.168.1.10', 1883)) # IP de ton broker
print('CONNACK:', connect(s, 'picow-01'))
while True:
publish(s, 'maison/picow/temperature', '21.5')
time.sleep(10)
# En C SDK : exemple officiel pico_w/wifi/mqtt (lwIP). En MicroPython, la
# lib umqtt.simple existe aussi dans micropython-lib.
# >
# n'a pas été vérifiée (hors base documentaire) — le code ci-dessus s'en passe.
Verificación esperada
CONNACK: b'\\x20\\x02\\x00' (código de retorno 0 = aceptado), luego en el broker: mosquitto_sub -t 'maison/picow/#' muestra un mensaje cada 10 s. Cortes de Wi-Fi: el socket se rompe — reinicia la conexión dentro de un try/except alrededor del bucle para un comportamiento real en campo.
Errores frecuentes
- Codificación incorrecta de la longitud restante: los campos «remaining length» son varints de 7 bits — un paquete mal formateado hace que el broker expulse al cliente sin mensaje de error.
- Mantenerse conectado sin
ping: el keepalive anunciado (60 s aquí) obliga al cliente a enviar PINGREQ (0xC0), de lo contrario el broker lo desconecta — añade un ping periódico para sesiones largas. - Conflicto de
client_id: dos clientes con el mismo identificador se expulsan mutuamente en bucle — único por tarjeta. - QoS 1/2 esperados: este ejemplo solo hace QoS 0 (fire and forget); el PUBACK de QoS 1 no se gestiona.
- Broker en la WAN sin TLS: MQTT 1883 en claro en Internet = credenciales legibles; quédate en la LAN o añade un túnel.
- En C SDK lwIP threadbackground: olvidar el bloqueo de arquitectura alrededor de las llamadas socket — ver el tutorial SDK.
Otros tutoriales para esta placa
- Faire clignoter la LED embarquée (elle est derrière la puce Wi-Fi !)
- Se connecter à un réseau Wi-Fi (station, WPA2/WPA3)
- Bouton et potentiomètre sans marcher sur le sans-fil (GPIO libres & ADC)
- Servir une page web depuis la Pico W (socket TCP + HTTP)
- Client HTTP : consommer une API depuis la Pico W
- Heure exacte via NTP : l'horloge temps réel des projets connectés
Ejemplos de código para esta placa
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython