🛠 Heure exacte via NTP : l'horloge temps réel des projets connectés
Objetivos
El RP2040 no tiene reloj de tiempo real (RTC): sin una fuente de tiempo, time.time vuelve a empezar desde cero (o desde el año 2000) en cada reinicio, lo cual es un inconveniente grave para registrar la hora de las mediciones o realizar conexiones HTTPS. El SDK oficial proporciona un ejemplo NTP completo en pico_w/wifi/ (carpeta ntp); en MicroPython, unas pocas líneas de socket UDP son suficientes. Vas a entender el paquete NTP v3 de 48 bytes, el desplazamiento de época 1900→1970, y por qué el modo SNTP del SDK es más limpio en C.
Material
- 1 × Raspberry Pi Pico W + firmware MicroPython
_picow - Acceso a Internet (salida UDP puerto 123 permitida — algunos routers empresariales la bloquean)
- Consola serie a 115200 baudios
Código completo
# ntp.py — synchronisation NTP en MicroPython (UDP brut, paquet 48 octets)
import machine, network, socket, time
wlan = network.WLAN; wlan.active(True)
if not wlan.isconnected:
wlan.connect('my_ssid', 'my_password')
while not wlan.isconnected:
machine.idle
NTP_EPOCH_OFFSET = 2208988800 # secondes entre 1900 et 1970
def sync_time(server='pool.ntp.org'):
addr = socket.getaddrinfo(server, 123)[0][-1]
s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
s.settimeout(5)
pkt = bytearray(48)
pkt[0] = 0x1B # LI=0, VN=3, mode=3 (client)
s.sendto(pkt, addr)
data = s.recv(48)[0]
secs = int.from_bytes(data[40:44], 'big') - NTP_EPOCH_OFFSET
machine.RTC.datetime((1970, 1, 1, 0, 0, 0, 0, 0)[:3] +
time.gmtime(secs)[3:6] + (0,))
return secs
t = sync_time
print('UTC :', time.strftime('%Y-%m-%d %H:%M:%S', time.gmtime(t)))
# En C SDK : exemple officiel pico_w/wifi/ntp (lwIP) ; lwIP expose aussi
# une API SNTP — >
# de lwIP embarquee dans le Pico SDK (sntp_setserver vs sntp_set_server).
Verificación esperada
La consola muestra la fecha/hora UTC actual, coherente con la de tu PC. Tras la sincronización, time.time devuelve segundos POSIX reales: tus registros de sensores quedan con marca de tiempo, y el HTTPS con validación de certificado se vuelve posible. Ejecuta un script sin sincronización: la hora vuelve a empezar desde cero — la prueba de que el RP2040 no retiene nada sin NTP (sin RTC, sin batería).
Errores frecuentes
- Olvidar el desplazamiento de época: sin los 2 208 988 800 segundos, acabarás en el año 2039 — NTP cuenta desde 1900, Unix desde 1970.
- UDP 123 bloqueado por el router/ruteador: el
recvexpira; prueba con otra red o un servidor NTP en otro puerto (algunas implementaciones usan el 123 en salida, generalmente aceptado). - Creer que la hora es persistente: cada reinicio borra el reloj — vuelve a sincronizar al arrancar en
main.py, o añade un RTC externo (I²C DS3231 en los GPIO libres GP0–GP22/GP26–GP28). - Paquete demasiado corto:
recv(48)debe leer los 48 bytes completos; un servidor que responde en IPv6 mediantegetaddrinfopuede sorprender — fuerzaAF_INET. - En el SDK de C, mezclar variantes de arquitectura: con
pico_cyw43_arch_lwip_threadbackground, las llamadas a lwIP deben estar rodeadas por el bloqueo de arquitectura (cyw43_arch_lwip_begin/end) — consulta el tutorial avanzado del 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
- Client MQTT : télémétrie IoT légère sur la Pico W
Ejemplos de código para esta placa
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython