Welcome to the Pycom forum Forum
    • \[\[global:header.categories\]\]
    • \[\[global:header.recent\]\]
    • \[\[global:header.tags\]\]
    • \[\[global:header.popular\]\]
    • Login

    Explore Pybytes | Official Documentation | Report a Firmware Bug/Issue | GitHub

    Syncing RTC To Network Time

    Scheduled Pinned Locked Moved LoPy
    24 Posts 8 Posters 13.8k Views 10 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • T Offline
      thefebruaryman
      last edited by

      t = ustruct.unpack("!12I", msg)[10]
      

      returns

      1485764691
      

      which in python I can normally

      >>> time.ctime(1485764691)
      'Mon Jan 30 08:24:51 2017'
      
      L 1 Reply Last reply Reply Quote 0
      • L Offline
        livius @thefebruaryman
        last edited by

        @thefebruaryman
        ok - then you succesfully got value
        but issue is in calibration procedure
        but i suppose you can fix problem by setting time by

        ct = time.ctime(t)
        rtc.init((ct[0], ct[1], ct[2], ct[3], ct[4], ct[5], 0, 0))
        

        think about people first, then computers

        1 Reply Last reply Reply Quote 0
        • D Offline
          dchappel
          last edited by dchappel

          Here is what I came up with (builds on Knoahlr contribution below):

          import socket
          import machine
          
          s=socket.socket()
          s.connect(socket.getaddrinfo("66.199.22.67",13)[0][-1])
          r=s.recv(1024).decode()
          s.close()
          
          year = 2000 + int(r[6:9])
          month = int(r[10:12])
          day = int(r[13:15])
          hour = int(r[16:18])
          min = int(r[19:21])
          sec = int(r[22:24])
          rtc = machine.RTC()
          rtc.init((year, month, day, hour, min, sec, 0, 0))
          print(rtc.now())
          

          Current time (in seconds since 1970 / UNIX time) is now available using utime.time().

          I found that I needed to use the numeric IP address for NIST. Alpha URL gave me a timeout. Since I got it to work with numeric I didn't go back and try to understand why...

          K 1 Reply Last reply Reply Quote 0
          • K Offline
            Knoahlr @dchappel
            last edited by Knoahlr

            @dchappel You might want to use RegEX,
            Assuming Current time is your response from the NIST server.

            >>import re
            >>CurrentTime='\n57783 17-01-30 16:14:50 00 0 0  37.8 UTC(NIST) * \n'
            >>DateList=re.search("[0-9]+-[0-9]+-[0-9]+",CurrentTime).group(0).split("-")
            >>DateList
            ['17', '01', '30']
            >>TimeList=re.search("[0-9]+:[0-9]+:([0-9]+.[0-9]+)",CurrentTime).group(0).split(":")
            >>TimeList
            ['16', '14', '50 00']
            

            Cheers.

            1 Reply Last reply Reply Quote 0
            • T Offline
              thefebruaryman
              last edited by

              Ok I got it. I have to use utime for localtime method to work with the large int else you get an error.

              from machine import Pin
              import pycom
              import utime
              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
                  tuple_time = utime.localtime(t)
                  rtc.init((tuple_time))
                  client.close()
              
              
              def pin_handler(arg):
                  print("Got an interrupt in pin %s" % (arg.id()))
                  pycom.rgbled(0x0000ff)
                  utime.sleep(1)
                  pycom.rgbled(0x000000)
                  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)
              
              1 Reply Last reply Reply Quote 1
              • A Offline
                abilio
                last edited by abilio

                We've just finished adding support for a NTP (SNTP) client. Syncing time will be as easy as:

                import machine
                rtc = machine.RTC()
                rtc.ntp_sync("pool.ntp.org") # select an appropriate server
                

                By default it will resync every hour, but you can change the period by passing it as a parameter: rtc.ntp_sync("pool.ntp.org", 1200) # do it every 20 minutes

                This feature will probably be included in the next release. Hope you'll find it useful.

                T K R 3 Replies Last reply Reply Quote 4
                • T Offline
                  thefebruaryman @abilio
                  last edited by

                  @abilio that's great news and much easier to use. Cheers for the good work!

                  1 Reply Last reply Reply Quote 0
                  • K Offline
                    Knoahlr @abilio
                    last edited by

                    @abilio Will the method sync the RTC to local time or UTC ?

                    A 1 Reply Last reply Reply Quote 0
                    • A Offline
                      abilio @Knoahlr
                      last edited by abilio

                      @Knoahlr, to UTC, but then you'll be able to set the time offset calling:

                      time.timezone(3600) # GMT +1 for the Netherlands
                      

                      A call to time.localtime() will return the time using the provided offset. If you want the number of seconds since Epoch adjusted to the timezone, you can do something like:

                      time.time() + time.timezone()
                      

                      Also, time.gmtime() will be included, working like time.localtime(), but without adjusting for the offset.

                      So far, this is what would be available in the release.

                      K 1 Reply Last reply Reply Quote 0
                      • K Offline
                        Knoahlr @abilio
                        last edited by

                        @abilio Great, amazing feature.

                        1 Reply Last reply Reply Quote 0
                        • R Offline
                          rdixey @abilio
                          last edited by

                          @abilio Apparently this is not yet implemented in 1.6.1.b1 ?

                          '1.6.1.b1'
                          >>> os.uname()
                          (sysname='LoPy', nodename='LoPy', release='1.6.1.b1', version='v1.8.6-450-g31ef5170 on 2017-02-15', machine='LoPy with ESP32', lorawan='1.0.0')
                          >>> import machine
                          >>> rtc = machine.RTC()
                          >>> rtc.ntp_sync("pool.ntp.org")
                          Traceback (most recent call last):
                            File "<stdin>", line 1, in <module>
                          AttributeError: 'RTC' object has no attribute 'ntp_sync'
                          >>> 
                          >>> import time
                          >>> time.timezone(3600)
                          Traceback (most recent call last):
                            File "<stdin>", line 1, in <module>
                          AttributeError: 'module' object has no attribute 'timezone'
                          
                          A 1 Reply Last reply Reply Quote 0
                          • A Offline
                            abilio @rdixey
                            last edited by

                            @rdixey, you are totally right and I must personally apologize for it. We forgot to merge it with master just to realize it after making the release (yeah, it happened twice :( ) . I will work so is included in the next firmware release.

                            R 1 Reply Last reply Reply Quote 0
                            • R Offline
                              rdixey @abilio
                              last edited by

                              @abilio These new rtc.ntp_sync() & time.timezone() functions work nicely with the 1.6.4.b1 update. They are very convenient!

                              I think there is a typo on the Utime doc page though. The first function listed there is utime.mktime([secs]), is this intended to be utime.gmtime()?

                              Thanks for the good work on this :)

                              L S 2 Replies Last reply Reply Quote 0
                              • L Offline
                                livius @rdixey
                                last edited by

                                @rdixey said in Syncing RTC To Network Time:

                                mktime

                                It is standard in many languages - google for it ;-)

                                think about people first, then computers

                                R 1 Reply Last reply Reply Quote -1
                                • S Offline
                                  santorcuato @rdixey
                                  last edited by

                                  @rdixey said in Syncing RTC To Network Time:

                                  @abilio These new rtc.ntp_sync() & time.timezone() functions work nicely with the 1.6.4.b1 update. They are very convenient!

                                  I think there is a typo on the Utime doc page though. The first function listed there is utime.mktime([secs]), is this intended to be utime.gmtime()?

                                  Thanks for the good work on this :)

                                  Its not working for me :-(

                                  Can you post a working example?

                                  Thanks!

                                  R 1 Reply Last reply Reply Quote 0
                                  • R Offline
                                    rdixey @santorcuato
                                    last edited by rdixey

                                    @santorcuato I used it as a function in the boot.py of my LoPy. I had to set a delay to allow for the round trip to pool.ntp.org or else the function completed before ntp_sync and RTC remained = Unix Epoch . When I ping pool.ntp.org from my LAN the longest round trip was 630ms so I set sleep at 750ms. Less than that was too short.

                                    def setRTCLocalTime():
                                        rtc = machine.RTC()
                                        rtc.ntp_sync("pool.ntp.org")
                                        utime.sleep_ms(750)
                                        print('\nRTC Set from NTP to UTC:', rtc.now())
                                        utime.timezone(-18000)
                                        print('Adjusted from UTC to EST timezone', utime.localtime(), '\n')
                                    
                                    Connecting to a LoPy...
                                    Connected
                                    >>> 
                                    PYB: soft reboot
                                    
                                    RTC Set from NTP to UTC: (2017, 2, 26, 13, 18, 54, 225113, None)
                                    Adjusted from UTC to EST timezone (2017, 2, 26, 8, 18, 54, 6, 57)
                                    
                                    S 1 Reply Last reply Reply Quote 0
                                    • R Offline
                                      rdixey @livius
                                      last edited by

                                      @livius Excuse Me :) I already know what mktime() is. And I don't need anyone to give me instructions on using google to find info. I was pointing out a typo in the doc's.

                                      https://docs.pycom.io/pycom_esp32/library/utime.html

                                      mktime is the first function in the list and is described as 'Convert a time expressed in seconds since the Epoch.' I believe this is an error and should be gmtime().

                                      mktime is listed again as the third functon and described correctly.

                                      gmtime() is not in the list at all.

                                      L 1 Reply Last reply Reply Quote 2
                                      • L Offline
                                        livius @rdixey
                                        last edited by

                                        @rdixey said in Syncing RTC To Network Time:

                                        instructions

                                        Without explanation that function is twice in doc - this was my first hint ;-)

                                        think about people first, then computers

                                        1 Reply Last reply Reply Quote 0
                                        • S Offline
                                          santorcuato @rdixey
                                          last edited by

                                          @rdixey Ok, it seems interesting. Will try!

                                          Thanks

                                          1 Reply Last reply Reply Quote 0

                                          Hello! It looks like you're interested in this conversation, but you don't have an account yet.

                                          Getting fed up of having to scroll through the same posts each visit? When you register for an account, you'll always come back to exactly where you were before, and choose to be notified of new replies (either via email, or push notification). You'll also be able to save bookmarks and upvote posts to show your appreciation to other community members.

                                          With your input, this post could be even better 💗

                                          Register Login
                                          • 1
                                          • 2
                                          • 1 / 2
                                          • First post
                                            Last post

                                          Pycom on Twitter

                                          Pycom