RV3028 Losing time between sketches

Hello again,

I thought I’d gotten over my RTC problems but it seems it’s not to be.

I’m able to run the set_time.py sketch (once I was using the right set_time.py file) and it appeared to be working (once I’d fixed the QWST connector that hadn’t been soldered on my Badger2040. Nothing like surprise surface-mount soldering to brighten your day…) But now that I’m at the stage where I’m ready to try running my sketch directly on the device (instead of through Thonny) I find that the time coming from the RV3028 is actually nonsense.

First screenshot, showing the RTC initialisation -

Second screenshot, showing the result of my test sketch that ran about 5s later-

Between these two sketches the Badger remained plugged-in to my PC and connected to Thonny, so I don’t even think it would have gone onto the battery backup. The second image does show a valid time, although not the current time, and when I re-ran the sketch it reported ‘19/06/2098 63:05:47’ so I’m pretty sure the valid time was just luck. I did try with and without the call to .setup() in check_time.py but the result was still way off.

So what is going on here? Is the battery in my brand-new RV3028 so flat that it’s losing time while it’s powered externally? Or is there some more setup that I’m missing somewhere?

This is code I run on my Pico that works for me. It’s a dual display setup. The following code was clipped and pasted from a much bigger file. It won’t run on its own without a bit of editing. Hopefully I snagged all the important stuff. It was my best guess at what was needed to make it work.

import time
from breakout_rtc import BreakoutRTC
rtc = BreakoutRTC(i2c)
rtc.set_backup_switchover_mode(1)
rtc.set_24_hour()
rtc.update_time()
rtc.enable_periodic_update_interrupt(True)

while True:
    
    if rtc.read_periodic_update_interrupt_flag():
        rtc.clear_periodic_update_interrupt_flag()

        if rtc.update_time():
            rtc_date = rtc.string_date()
            rtc_time = rtc.string_time()

    display2.set_pen(white)
    hours = rtc.get_hours()
    minutes = rtc.get_minutes()
    display2.text(rtc.string_date(), 10, 0, 240, 2)
    
    if hours <12:
        display2.text(f"{hours:2}:{minutes:02}:am", 150, 0, 240, 2)
    elif hours == 12:
        display2.text(f"{hours:2}:{minutes:02}:pm", 140, 0, 240, 2)
    elif hours >12:
        hours = hours - 12
        display2.text(f"{hours:2}:{minutes:02}:pm", 150, 0, 240, 2)
1 Like

Thank you for your help!

From a little trial and error it appears that update_time() needs to be called every time the sketch runs, and set_backup_switchover_mode() only needs to be run once per-device as part of the initial setup.

Do you know if there’s a proper interface spec or something for these breakouts? I’ve had to resort to reading the source code (pimoroni-pico/rv3028.cpp at main · pimoroni/pimoroni-pico · GitHub and rv3028-python/__init__.py at master · pimoroni/rv3028-python · GitHub) of the drivers to figure out what functions I actually have access to. Compared to things like NPM module libraries, this is a long way from user-friendly, so I’m glad they have such friendly users :)

Usually, I can gleam what code I need from the examples. Some breakouts have a Function Reference list, which helps a lot. But those are more on the Python side versus Micro Python. It can be a challenge sometimes. If I get really stuck, I do a
@hel or @gadgetoid. They both work for Pimoroni.
Another option is to e-mail Tech Support directly.
Contact Us for Raspberry Pi Technical Support - Pimoroni

1 Like

Just to follow-up, these are the available functions on the RV3028 as of the May 2021 micropython driver (found by doing dir(name of RV3028 instance) ), hopefully this helps someone else -

'clear_alarm_interrupt_flag'
'clear_clock_output_interrupt_flag'
'clear_interrupts'
'clear_periodic_update_interrupt_flag'
'clear_timer_interrupt_flag'
'disable_alarm_interrupt'
'disable_clock_out'
'disable_periodic_update_interrupt'
'disable_timer'
'disable_timer_interrupt'
'disable_trickle_charge'
'enable_alarm_interrupt'
'enable_clock_out'
'enable_interrupt_controlled_clockout'
'enable_periodic_update_interrupt'
'enable_timer'
'enable_timer_interrupt'
'enable_trickle_charge'
'get_date'
'get_hours'
'get_minutes'
'get_month'
'get_seconds'
'get_status'
'get_timer_count'
'get_unix'
'get_weekday'
'get_year'
'is_12_hour'
'is_pm'
'read_alarm_interrupt_flag'
'read_clock_output_interrupt_flag'
'read_periodic_update_interrupt_flag'
'read_timer_interrupt_flag'
'reset'
'set_12_hour'
'set_24_hour'
'set_backup_switchover_mode'
'set_date'
'set_hours'
'set_minutes'
'set_month'
'set_seconds'
'set_time'
'set_timer'
'set_to_compiler_time'
'set_unix'
'set_weekday'
'set_year'
'setup'
'string_date'
'string_date_usa'
'string_time'
'string_time_stamp'
'update_time'

Just dropped a lil function into the examples which should hopefully help out if you’re wanting to set your Pico’s time from a RV3028 breakout!

2 Likes