Friday, April 7, 2023

Getting the right time with MicroPython

 For an index to all my stories click this text

I am working at several time related projects. A talking clock and a special clock for very small kids. These projects are Raspberry Pi Pico based and the software is written in MicroPython.

There are two versions of the Pico. The Raspberry Pi Pico and the Pico W. They are basically the same except that the Pico W has wifi on board.

One of my clock projects, build with the Pico, sets the time with 2 buttons. The first button increases the hours, the second button increases the minutes. This time is set into the Pico's RTC (real time clock). As the Pico's build in oscillator generates a very stable and accurate pulse you only have to adjust the time every few days.

The Pico W offers an extra functionality. It can get the right time from the internet. That way we do not have to set the time manually.

Time on the internet.

When you boot your computer or tablet you will notice that it will display the right time. That is because these devices fetch the time from the internet. There are special servers that provide the right time. They are called Network Time Protocol servers. Abbreviated to NTP servers.
NTP servers have been around for a long time. Large database systems and company servers depend on them to synchronise their services.

And lucky for us mere mortals, we are allowed to access these servers so we can get the right time.

In MicroPython there is a special library for getting the time from an NTP server. Unfortunately it is not included in the standard libraries and a bit hidden on the MicroPython Github Repositry. Here is the link:
https://github.com/micropython/micropython-lib/blob/master/micropython/net/ntptime/ntptime.py

For convenience I copied the library to my own Github repositry. You can find it here: https://github.com/Lucvolders/MicroPython/tree/main/Libraries/NTPtime

The library gets the time from an NTP server and updates the build in RTC. So the RTC has the right time and that can be used in your own projects.

Here is the complete code in MicroPython.

import time
import ntptime
import machine
import network

# Router credentials
ssid = "ROUTERS_NAME" # wifi router name
pw = "PASSWORD" # wifi router password
print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF) # station mode
wifi.active(True)
wifi.connect(ssid, pw)

# wait for connection
while not wifi.isconnected():
    pass

# wifi connected
print("Connected. IP: ",str(wifi.ifconfig()[0], "\n")) 

rtc = machine.RTC()

rtc.datetime((2000, 1, 1, 0, 0, 0, 00, 0))
print(time.localtime())

ntptime.settime()
time.sleep(2)

dstadjust = 1

while True:
    print ("Year   = ", time.localtime()[0])
    print ("Month  = ", time.localtime()[1])
    print ("Day    = ", time.localtime()[2])
    hour = time.localtime()[3]
    hour = hour + dstadjust
    print ("Hour   = ", hour)
    print ("Minute = ", time.localtime()[4])
    print ("===============")
    time.sleep(10)

As usual I will highlight parts of the program for an explanation.

import time
import ntptime
import machine
import network

The libraries that we need are loaded. Do not forget to copy the ntptime.py library into the Pico's lib folder.

# Router credentials
ssid = "Routers name" # wifi router name
pw = "Routers password" # wifi router password
print("Connecting to wifi...")

# wifi connection
wifi = network.WLAN(network.STA_IF) # station mode
wifi.active(True)
wifi.connect(ssid, pw)

Make sure to fill in your routers credentials here and the program uses these to connect to the internet.

# wait for connection
while not wifi.isconnected():
    pass

The program waits till a connection to the internet is established.

# wifi connected
print("Connected. IP: ",str(wifi.ifconfig()[0], "\n")) 

For your convenience your Raspberry Pi Pico's IP number is printed in Thonny's shell.

rtc = machine.RTC()

rtc.datetime((2000, 1, 1, 0, 0, 0, 00, 0))
print(time.localtime())

The RTC (real time clock) is activated and the date and time are initially set to the year 2000, month 1 and day 1, 0 hour, 0 minutes.

ntptime.settime()
time.sleep(2)

The ntptime library gets the right time from the internet and sets it into the Raspberry Pi Pico's RTC. Then we wait 2 seconds for everything to settle down.

dstadjust = 1

As I do not know where you live you will have to adjust the figure 1 yourself. dstadjust is the daylight savings time adjustment. Here I use the value 1 as I am in the Netherlands. Adjust this value to your own needs.

while True:
    print ("Year   = ", time.localtime()[0])
    print ("Month  = ", time.localtime()[1])
    print ("Day    = ", time.localtime()[2])
    hour = time.localtime()[3]
    hour = hour + dstadjust
    print ("Hour   = ", hour)
    print ("Minute = ", time.localtime()[4])

    print ("===============")
    time.sleep(10)

The while-True loop runs forever and in the loop the relevant information is printed in Thonny's shell.

time.localtime() is a tuple. Each of the tuple's elements can be adressed like this:

time.localtime()[X])

In this the X represents the elements of the tuple.
0 is the year, 1 is the month, 2 is the date, 3 is the hour and 4 are the minutes. The elements 5,6 and 7 are the seconds, day of the week and the day of the year. These last 3 elements are not used in my projects.

Please pay attention to the next lines:

    hour = time.localtime()[3]
    hour = hour + dstadjust
    print ("Hour   = ", hour)

First time.localtime()[3] is copied in a varaible with the name hour. Then we adjust that variable with the dstadjust value for getting the right hour and then we print the value.



And this is how the program prints its data in Thonny's shell.

If you are planning to build some time-related projects this should get you going.

Till next time
have fun

Luc Volders