This guide will help you get started with a PiicoDev Real Time Clock. We'll set and read the time/date, observe the power-backup capability, and configure the RTC with an alarm.
A Real-Time Clock (RTC) is a timekeeping device that accurately tracks the passage of time. Most RTCs feature a calendar and alarm so they may be used to schedule actions. The PiicoDev Real-Time Clock is based on a low-power and very accurate RV-3028, factory calibrated to within 30 seconds per year. Power to the RTC is backed-up by a supercapacitor, capable of running the clock for up to a week without external power. When power is connected, the supercap is recharged. From dead-flat, it takes about three minutes to charge the supercap enough to sustain shorter power outages. A full charge takes about an hour.
Hardware and Connections
To follow along you'll need:
- A Raspberry Pi Pico (with Soldered Headers)
- A PiicoDev Real Time Clock
- A PiicoDev Expansion Board for Raspberry Pi Pico
- A PiicoDev Cable
- (Optional) A PiicoDev Platform will keep everything mounted securely.
Plug your Pico into the expansion board. Make sure it is plugged in the correct orientation - Pin 0 on the expansion board should be to the left of the Pico's USB connector.
Connect your RTC to the expansion board with a PiicoDev Cable.
To follow along you'll need:
- A Raspberry Pi single board computer (Pictured: Raspberry Pi 4 Model B)
- A PiicoDev Real Time Clock
- A PiicoDev Adapter for Raspberry Pi
- A PiicoDev Cable (100mm or longer is best for Raspberry Pi)
- (Optional) A PiicoDev Platform will keep everything mounted securely.
Mount the Adapter onto your Pi's GPIO. Make sure it is plugged in the correct orientation - An arrow on the Adapter will point to the Pi's Ethernet connector (on a Pi 3 the Ethernet connector and USB ports are swapped.)
Connect your RTC to the Adapter with a PiicoDev Cable.
To follow along you'll need:
- A micro:bit v2
- A PiicoDev Real Time Clock
- A PiicoDev Adapter for micro:bit
- A PiicoDev Cable
- (Optional) A PiicoDev Platform will keep everything mounted securely.
Plug your micro:bit into the Adapter, making sure the buttons on the micro:bit are facing up.
Connect your RTC to the Adapter with a PiicoDev Cable.
Setup Thonny
Download / Install PiicoDev Modules
To work with PiicoDev hardware, we need to download some drivers. The drivers provide all the functions to easily connect and communicate with PiicoDev hardware. Select your dev board from the options above.
We will need these files to easily drive the PiicoDev Real Time Clock:
- Save the following files to your preferred coding directory - In this tutorial, we save to My Documents > PiicoDev.
- Download the PiicoDev Unified Library: PiicoDev_Unified.py (right-click, "save link as").
- Download the device module: PiicoDev_RV3028.py (right-click, "save link as")
- Upload the files to your Pico. This process was covered in the Setup Thonny section.
The PiicoDev Unified Library is responsible for communicating with PiicoDev hardware, and the device module contains functions for driving specific PiicoDev devices.
We will need these files to easily drive the PiicoDev Real Time Clock:
- Save the following files to your preferred coding directory - In this tutorial, we save to My Documents > PiicoDev.
- Download the PiicoDev Unified Library: PiicoDev_Unified.py (right-click, "save link as").
- Download the device module: PiicoDev_RV3028.py (right-click, "save link as")
- Upload the files to your micro:bit. This process was covered in the Setup Thonny section.
The PiicoDev Unified Library is responsible for communicating with PiicoDev hardware, and the device module contains functions for driving specific PiicoDev devices.
Set and Read the Time and Date
The following example shows how to set and read the time. The script initialises the RTC which enables charging the supercap. The date and time are set numerically, and the weekday is set with an integer between 0 and 6.
The setDateTime() method pushes the values we have set onto the RTC. Conversely, the getDateTime() method pulls the current date-time from the RTC and stores that data into the attributes (day, month, year, etc.). That means any time we want to get the current time, we must first call getDateTime().
We can query the name of the weekday by reading from the weekdayName property which contains a string ("Monday", "Tuesday" ... "Sunday"). weekdayName assumes that Monday is day zero. If you prefer, you can also set the weekday using weekdayName eg. rtc.weekdayName = "Monday"
timestamp() is a special method that first updates the current date-time, and then returns a string in the format YYYY-MM-DD HH:MM:SS. This is useful for printing timestamps to the shell or a log file.
# PiicoDev Real Time Clock RV-3028 # An example of how to set and read the date, time, and weekday from PiicoDev_RV3028 import PiicoDev_RV3028 from PiicoDev_Unified import sleep_ms rtc = PiicoDev_RV3028() # Initialise the RTC module, enable charging # Set the time by assigning values to rtc's attributes # Replace the following values with the current date/time rtc.day = 6 rtc.month = 5 rtc.year = 2022 rtc.hour = 11 rtc.minute = 57 rtc.second = 00 rtc.ampm = '24' # 'AM','PM' or '24'. Defaults to 24-hr time rtc.weekday = 4 # Rolls over at midnight, works independently of the calendar date rtc.setDateTime() # Sets the time with the above values # Get the current time rtc.getDateTime() # Print the current time, and today's name # You can read from individual time attributes eg hour, minute, weekday. print("The time is " + str(rtc.hour) + ":" + str(rtc.minute)) print("Today is " + str(rtc.weekdayName) + "\n") # weekdayName assumes counting from 0=Monday. while True: print(rtc.timestamp()) # timestamp() automatically updates time, and returns a pre-formatted string. Useful for printing and datalogging! sleep_ms(1000)
After running the script, you ought to see:
- First, a message that reads "The time is..." and "Today is..." with the correct time and week day name.
- Second, the current timestamp being printed every second.
Running on Backup Power
In the previous example, the PiicoDev RTC was automatically configured to charge the supercapacitor during initialisation. If your RTC has remained powered for a few minutes since running the example then the capacitor will have enough charge to withstand a power outage. Let's test it out!
- Stop the example script if you haven't already
- Disconnect the RTC for some time
- Reconnect the RTC
Now we'll check if the clock has kept accurate time during the power outage. Run the following code - which is a stripped-down version of the previous example that just reads the timestamp. All going well, you should see accurate timestamps printing in the shell!
Be careful not to accidentally set the time again during this process! There should be no need to call setDateTime(), since we already set the correct time in the previous example.
# A simple example to read the date, timestamp and weekday from the PiicoDev RTC from PiicoDev_RV3028 import PiicoDev_RV3028 from PiicoDev_Unified import sleep_ms rtc = PiicoDev_RV3028() while True: print(rtc.timestamp()) sleep_ms(1000)
Advanced Examples
These examples use more advanced features of the RTC. As such, their documentation is a little more terse. Select a tab to see the example.
The following example checks whether the current time matches a pre-set scheduled time to perform an action. The action is only performed once. This can be used to create an alarm, or schedule events in the future. The alarmSetup() method accepts values for minutes, hours, and weekday (or date).
The status of the alarm can be checked with the checkAlarm() method, which returns True the first time it is called after an alarm has triggered. Subsequent calls to checkAlarm() will return False, until the alarm is triggered again. This means you don't have to query checkAlarm() at the exact time the alarm is set for.
By default, alarmSetup() will also configure the hardware interrupt pin (INT) to trigger on an alarm event.
# PiicoDev Real Time Clock RV-3028 # Some examples of how to set an alarm # Alarms can trigger on a combination of minutes, hours, and weekday/date from PiicoDev_RV3028 import PiicoDev_RV3028 from PiicoDev_Unified import sleep_ms rtc = PiicoDev_RV3028() # Initialise the RTC module (24-hr mode by default), enable charging ### Trigger once per hour, at the start of the hour rtc.alarmSetup(minutes=0) ### Trigger on the 3rd day of the week (count from zero) at 1:23 PM # rtc.alarmSetup(weekday=2, hours=13, minutes=23) ### Trigger on the first day of the month # rtc.alarmSetup(date=1) while True: print(rtc.timestamp()) if rtc.checkAlarm(): print("Alarm Triggered") sleep_ms(2000)
The PiicoDev RTC features a clock output pin (CLK) that generates a square wave - the frequency is user configurable. Valid frequencies are: 0Hz (off, Low), 1, 32, 64, 1024, 8192 and 32,768Hz
# Set the CLK output pin frequency from PiicoDev_RV3028 import PiicoDev_RV3028 rtc = PiicoDev_RV3028() rtc.configClockOutput(1) # The frequency, in Hz, of the square wave on the CLK output pin. Valid values are: 32768, 8192, 1024, 64, 32, 1, and 0 (always low).
The PiicoDev RTC features a UNIX time register that can be set independently of the date-time. UNIX time is represented as the number of seconds since the last epoch. When reset to zero, this timer can be useful for keeping uptime or a mission-timer for data logging
from PiicoDev_RV3028 import PiicoDev_RV3028 from PiicoDev_Unified import sleep_ms rtc = PiicoDev_RV3028() # Initialise the RTC module rtc.setUnixTime(0) # reset UNIX time while True: print(rtc.getUnixTime()) # display UNIX time sleep_ms(1500)
The PiicoDev RTC features an External Event Interrupt pin (EVI) and Time Stamp function that can capture the time of an external event. The example below configures the EVI pin to capture the timestamp of a falling edge. If multiple events occur before the event time is queried, only the most recent timestamp is returned.
# Read the EVI pin event time. # The program will continue listening for an event until one is detected. from PiicoDev_RV3028 import PiicoDev_RV3028 from PiicoDev_Unified import sleep_ms rtc = PiicoDev_RV3028() rtc.resetEventInterrupt(edge = 'falling') rtc.getDateTime() print('Monitoring started at: ' + rtc.timestamp()) while (rtc.getEventInterrupt() is False): print('Waiting for 10 seconds. If there is a falling edge on EVI pin the time will be recorded.') sleep_ms(10000) print('Event occurred at: ', end='') rtc.getDateTime(eventTimestamp=True) print(rtc.timestamp(eventTimestamp=True))
Technical Resources
Pinout and Pin Descriptions
Pin | Description |
GND | Power Input, Ground |
3V3 | Power Input, 3.3V. Tolerant up to 5V (Note 1) |
SDA | I2C Communications - Data |
SCL | I2C Communications - Clock |
INT | Interrupt Output, Low when an interrupt occurs |
EVI | Event Input - pull to Ground to trigger an event interrupt |
CLK |
Clock output, square wave configurable from 1Hz to 32,768Hz |
(Note 1) The RV-3028 RTC will operate down to Vcc of 1.2V however at this voltage the included supercapacitor will not hold sufficient charge to guarantee that time is kept through a power failure. Time is lost when the capacitor voltage drops below about 900 mV and it will typically only charge to Vcc-0.3V due to an internal Schottky diode. The RV-3028 works up to 5V, but this is only recommended for freestyle prototyping ie. not connected to any other PiicoDev hardware. PiicoDev is a 3.3V system.