Scaling an IoT deployment? Join our webinar on May 28th where we dive into real-world scaling pain points and how to overcome them.

Blues Developers
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
Button IconHelp
Notehub StatusVisit our Forum
Button IconSign In
Sign In
Sign In
What’s New
Resources
Blog
Technical articles for developers
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Developer Certification
Get certified on wireless connectivity with Blues
Webinars
Listing of Blues technical webinars
Blues.comNotehub.io
Shop
Docs
homechevron_rightBlogchevron_rightBuilding a Connected Clock with Blues and the Raspberry Pi Pico

Building a Connected Clock with Blues and the Raspberry Pi Pico

Building a Connected Clock with Blues and the Raspberry Pi Pico banner

August 24, 2023

Learn how to make web requests with the Notecard and use Timer Interrupts on Micropython whilst building a clock.

  • Cellular
  • Raspberry Pi
  • MicroPython
Kimball Johnson
Kimball JohnsonSenior Developer Advocate
email

A Simple Clock

This post is a continuation of a previous article on getting started with the Notecard on the Raspberry Pi Pico, where I showed how to set the time on the Raspberry Pi Pico Real Time Clock from the Notecard. If you haven't already, you'll want to read that post before continuing.

In this post we will take this further, to build a clock. Using web APIs we can augment the display further, ensuring the correct timezone information, and displaying local weather. The project is based on the Galactic Unicorn by Pimoroni , an interesting LED Matrix with a Raspberry Pi Pico W built in. Whilst a display with 583 RGB LEDs would not be your first thought when building a project with an ultra-low-power cellular IoT connectivity device like the Blues Notecard, it does provide a mesmerising example to demonstrate the capabilities.

To start, combining the code from last time, and the clock example provided by Pimoroni, we can get a basic clock going very quickly with the following code snippet:

year, month, day, wd, hour, minute, second, _ = rtc.datetime()
last_second = second

# Check whether the RTC time has changed and if so redraw the display
def redraw_display_if_reqd():
    global year, month, day, wd, hour, minute, second, last_second

    year, month, day, wd, hour, minute, second, _ = rtc.datetime()
    if second != last_second:
        clock = "{:02}:{:02}:{:02}".format(hour, minute, second)        
        graphics.text(clock, 0, 0)
        last_second = second

while True:
    redraw_display_if_reqd()

    # update the display
    gu.update(graphics)

    time.sleep(0.01)

Not shown we initialize the Notecard and RTC as in the previous example, and initialize the Graphics library.

Then we configure the display and set up some colours and the font before going into the main loop. Here in the main loop we call a function to update the clock display, which simply checks to only update the display once a second.

The first issue that you will see, unless you happen to be on UTC time currently, is that the time displayed is incorrect. We can get timezone offset information from the Notecard, but this would mean we needed to check frequently to account for Daylight saving time. Instead, we will query a web API to determine both the current offset and the next daylight saving changeover time.

Simple Clock

Web Requests with Notecard

To access web APIs through the Notecard we need to set up a Proxy Route on Notehub. This allows us to avoid hardcoding URLs, keys, and certificates in the application on the Pico while relying on Notehub's secure authentication mechanisms for performing requests.

In our Notehub project, we add a new route to access the Time API :

Creating a Proxy Route on Notehub.io

Once set up, we can access this from the Notecard with the web.get request. To use this the Notecard needs to be in continuous mode. If you recall from the previous post though, we have the Notecard in periodic mode as a power-saving feature, however, this is simple to work around. The hub.set request has a parameter of on and off for temporary enablement of continuous mode. The time to leave it in continuous mode is set with the parameter seconds and defaults to five minutes. The off parameter to the request will disconnect immediately.

Combining this, we can define a function allowing us to enable the mode, wait until the Notecard is connected, make the web request, and disconnect.

def webRequest(route,path):
    nCard.Transaction({'req': 'hub.set', 'on': True})
    connected = False
    while connected == False:
        res = card.status(nCard)
        connected = res.get('connected',False)
        time.sleep(1)
    res = nCard.Transaction({'req': 'web.get', 'route': route, 'name': path})
    
    nCard.Transaction({'req': 'hub.set', 'off': True})
    return res

When this is returned, the json structure from the API is returned as the value to the body parameter, which Python helpfully converts to a dict for our use. With this, we can now use the data provided to add the correct offset to our RTC before we set it. The get_tz_info function call here makes the call to webRequest, and manipulates the response into the return structure.

tzInfo = get_tz_info()

celltime = card.time(nCard)
epochtime = celltime["time"]
epochtime += tzInfo['offset']
if tzInfo['dstactive']:
    epochtime += tzInfo['dstoffset']
    dstupdate = tzInfo['dstchange']
tm = time.gmtime(epochtime)
rtc = machine.RTC()
rtc.datetime((tm[0], tm[1], tm[2], tm[6], tm[3], tm[4], 0, 0))

Now we have both the correct time, and with the dstupdate parameter holding the date and time of the next DST change, we can set a check in our main loop to update accordingly. This is great, and allows us to have a clock that will display the correct time anywhere in the world. Using a similar technique, with another proxy route setup in Notehub for Open-Meteo we can get weather information every 15 minutes. In our main loop, we can add some code like this:

if (second != last_second and second == 0 and minute == 0):
    weather = update_weather(latitude,longitude)
    current_weather=weather['body']['current_weather']
    draw_weather(current_weather['weathercode'],math.floor(current_weather['temperature']),'c')

Here we are checking that we are at the top of the hour, (and that the second value has changed, so we don't run the code 100 times), then call a couple of functions, one that wraps accessing the weather API, passing in the latitude and longitude (this is available from the Notecard either with the GPS, or getting the cell tower information for a less accurate location), and then calling another function to draw the resultant information to the screen.

The astute of you will realise there is a problem here though, our main loop is responsible for updating the clock display every second, and our webRequest function has a loop waiting for the notecard to connect, which itself has a 1-second delay every time round the loop. What will happen in practice is there will be a several-second delay as the Notecard comes out of low-power mode and reconnects to the cell network, and then the Notehub, during which time the main loop is blocked.

This sort of blocking is important to handle in many Notecard applications, for example you don't want to stop collecting sensor information just because you have a need to power up and make a web request. There are multiple ways to handle this, for example rather than blocking on waiting for the Notecard to connect, you could make the request to connect, and then check periodically in the main loop until it was ready, whilst still handling the other functions of the loop, but Micropython on the Pico gives us a more elegant solution.

Stopping Clock

Micropython Timer Interrupts

Micropython on the Raspberry Pi Pico gives you software based timer interrupts , only limited by memory; using these, we can trigger our display updates, removing them from our main loop.

Timers are created with just one function call:

timer = Timer(mode=Timer.PERIODIC, period=1000, callback=function)

The timer will operate in two modes, PERIODIC as above, will call the function repeatedly with the period, specified in milliseconds, as the interval. ONESHOT will wait the specified period, and then call the function once. The callback can either be a function, or a lambda inline, as shown in the example:

Timer(period=5000, mode=Timer.ONE_SHOT, callback=lambda t:print(1))

For our case, we define a function update_clock and pass it as the callback function

def update_clock(timer = None):
    global second, minute
    year, month, day, wd, hour, minute, second, _ = rtc.datetime()
    x = 0
    y = 0
    draw_clock(x, y, hour, minute, second)

timer = Timer(mode=Timer.PERIODIC, period=1000, callback=upfate_clock)

This updates the time part variables from the RTC, then calls the function that sets up the drawing on the screen. This doesn't however call the function to actually draw onto the screen, for this we define another function and timer:

def update_gfx(timer = None):
    # update the display
    gu.update(graphics)

gfx_timer = Timer(mode=Timer.PERIODIC, period=100, callback=update_gfx)

Finally, we adjust our main loop, removing these lines as they are now handled by timers:

redraw_display_if_reqd()
gu.update(graphics)

Conclusion

I hope this helps you see the power of the Notecard, and some tricks with using Micropython to work with it. There is of course more than one way to achieve what I have here, but hopefully this will provide inspiration.

Check out the full (evolving) source code at Github , to see how it all comes together.

In the next article on this series, we will show how you can use Notehub to set up changeable settings for the Notecard application, and how you can send data on demand to the Notecard. In the meantime please check out the Notecard Starter Kit and the Quickstart on blues.dev.

In This Article

  • A Simple Clock
  • Web Requests with Notecard
  • Micropython Timer Interrupts
  • Conclusion

Blues Developer News

The latest IoT news for developers, delivered right to your inbox.

Comments

Join the conversation for this article on our Community Forum

Blues Developer Newsletter

The latest IoT news for developers, delivered right to your inbox.

© 2025 Blues Inc.
© 2025 Blues Inc.
TermsPrivacy
Notecard Disconnected
Having trouble connecting?

Try changing your USB cable as some cables do not support transferring data. If that does not solve your problem, contact us at support@blues.com and we will get you set up with another tool to communicate with the Notecard.

Advanced Usage

The help command gives more info.

Connect a Notecard
Use USB to connect and start issuing requests from the browser.
Try Notecard Simulator
Experiment with Notecard's latest firmware on a Simulator assigned to your free Notehub account.

Don't have an account? Sign up