Syncing RTC To Network Time



  • @thefebruaryman

    what you got when you do?:
    print(str(ustruct.unpack("!12I", msg)[10]))



  • I have been looking at the same issue tonight and came up with this script

    # imports
    from machine import Pin
    import pycom
    import time
    import ustruct
    from machine import RTC
    import socket
    from socket import AF_INET, SOCK_DGRAM
    
    pycom.heartbeat(False)
    
    rtc = RTC()
    rtc.init((1970, 0, 0, 0, 0, 0, 0, 0))
    
    def getNTPTime(host = "pool.ntp.org"):
        port = 123
        buf = 1024
        address = socket.getaddrinfo(host,  port)[0][-1]
        msg = '\x1b' + 47 * '\0'
        msg = msg.encode()
        TIME1970 = 2208988800 # 1970-01-01 00:00:00
    
        # connect to server
        client = socket.socket(AF_INET, SOCK_DGRAM)
        client.sendto(msg, address)
        msg, address = client.recvfrom(buf)
        t = ustruct.unpack("!12I", msg)[10]
        t -= TIME1970
        rtc.calibration(t)
        return t
    
    def pin_handler(arg):
        print("Got an interrupt in pin %s" % (arg.id()))
        pycom.rgbled(0x0000ff)
        time.sleep(1)
        pycom.rgbled(0x000000)
        print(getNTPTime())
        print(rtc.now())
    
    # use the button on the expansion board  P10
    p_in = Pin('G17',  mode=Pin.IN,  pull=Pin.PULL_UP)
    # on button push trigger pin_handler
    p_in.callback(Pin.IRQ_FALLING,  pin_handler)
    

    however the calibration method doesn't like it

    >>> Got an interrupt in pin P10
    Unhandled exception in interrupt handler
    Traceback (most recent call last):
    File "<stdin>", line 36, in pin_handler
    File "<stdin>", line 28, in getNTPTime
    OverflowError: overflow converting long int to machine word


  • @dchappel - to communicate with a ntp server you need the socket.sendto(), however I believe this is not implemented yet.

    Also, the rtc interrupts is not implemented yet, so you can't really power down the device int low power mode and wake it up again.

    The RTC module is there, but in my opinion it is not yet usable.



  • @dchappel
    In my boot.py after connecting to WiFi, I open up a socket and query the NIST servers, they provide UTC time accurate to the second. You can the parse the string and initialize your RTC from there.
    This is all you have to do. However, time will differ, unless you live on the prime meridian.

    >>import socket
    >>s=socket.socket()
    >>s.connect(socket.getaddrinfo("time.nist.gov",13)[0][-1])
    >>s.recv(1024)
    >>'\n57777 17-01-24 16:42:49 00 0 0 595.8 UTC(NIST) * \n'
    

    Im using an older firmware that doesn`t include the RTC class, so I have a formula to calculate the epoch time during boot and save it to a variable. This works for most applications as epoch time is more common.

    Hope this helps.


Log in to reply
 

Pycom on Twitter