🛠 Heure exacte via NTP : l'horloge temps réel des projets connectés
Objectives
The RP2040 has no real-time clock: without a time source, time.time restarts from zero (or 2000) on every reset — unacceptable for timestamping measurements or using HTTPS. The official SDK provides a complete NTP example in pico_w/wifi/ (the ntp folder); in MicroPython, a few lines of UDP socket code are sufficient. You will understand the 48-byte NTP v3 packet, the 1900→1970 epoch offset, and why the SDK's SNTP mode is cleaner in C.
Hardware
- 1 × Raspberry Pi Pico W + MicroPython
_picowfirmware - Internet access (UDP port 123 outbound allowed — some corporate routers block it)
- Serial console at 115200 baud
Complete code
# 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).
Expected verification
The console displays the current UTC date/time, consistent with your PC. After synchronization, time.time returns real POSIX seconds: your sensor logs are timestamped, and HTTPS with certificate validation becomes possible. Run a script without sync: the time restarts from zero — proof that the RP2040 retains nothing without NTP (no RTC, no battery).
Common errors
- Forgetting the epoch offset: without the 2,208,988,800 seconds, you end up in 2039 — NTP counts from 1900, Unix from 1970.
- UDP 123 blocked by the router/modem:
recvtimes out; test on another network or use an NTP server on a different port (some implementations use 123 for outbound traffic, which is generally accepted). - Believing the time is persistent: every reset clears the clock — resynchronize at boot in
main.py, or add an external RTC (I²C DS3231 on free GPIOs GP0–GP22/GP26–GP28). - Packet too short:
recv(48)must read the full 48 bytes; a server responding via IPv6 ongetaddrinfocan be surprising — forceAF_INET. - In C SDK, mixing architecture variants: with
pico_cyw43_arch_lwip_threadbackground, lwIP calls must be surrounded by the architecture lock (cyw43_arch_lwip_begin/end) — see the advanced SDK tutorial.
Other tutorials for this board
- 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
Code examples for this board
clignotante.pyPythonbouton-interruption.pyPythonpwm-servo.pyPythonlecture-adc.pyPythonneopixel.pyPythonoled-i2c.pyPython