Set the time of Raspberry Pi Pico W using NTP

 While the new RPi Pico W does not have a battery to keep the RTC, it does have something the previous model was lacking, network connectivity. So using the built-in Wifi module it can figure out the time and date from a network server using the Network Time Protocol (NTP). 


It can work with it but the MicroPython binary I am using does not include a module for that at the moment (as the binary for ESP32 does) but it should not be a big deal to use that.

As usual, it was easier to say than to do, but now I have it working. Please note that if you use the Thonny program, it will adjust the Pico real-time clock without warning you. So for a while, you may think it was your code that did it when it may well it is not the case.

I just recycled some code I found but I was getting errors till I figured out the right offset for my board and timezone. You may need to tweak that to adjust it to yours.

try:
    import usocket as socket
except:
    import socket
try:
    import ustruct as struct
except:
    import struct

# (date(2000, 1, 1) - date(1900, 1, 1)).days * 24*60*60 = 3155673600
NTP_DELTA = 2208981600 #=1609459200+599522400   


# The NTP host can be configured at runtime by doing: ntptime.host = 'myhost.org'
host = "pool.ntp.org"


def time():
    NTP_QUERY = bytearray(48)
    NTP_QUERY[0] = 0x1B
    addr = socket.getaddrinfo(host, 123)[0][-1]
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        s.settimeout(1)
        res = s.sendto(NTP_QUERY, addr)
        msg = s.recv(48)
    finally:
        s.close()
    val = struct.unpack("!I", msg[40:44])[0]
    return val - NTP_DELTA


# There's currently no timezone support in MicroPython, and the RTC is set in UTC time.
def settime():
    t = time()
    import machine
    import utime

    tm = utime.gmtime(t)
    machine.RTC().datetime((tm[0], tm[1], tm[2], tm[6] + 1, tm[3], tm[4], tm[5], 0))

This is only useful once you have connected your board to the Internet, of course. In my case, I just do:

import ntptime
ntptime.settime()

and this sets the time on the Pico's RTC properly. 

Comments

Popular posts from this blog

VFD control with Arduino using RS485 link

Importing OpenSCAD designs into Onshape

How to get sinusoidal s-curve for a stepper motor