Raspberry Pi Pico: DS1307 RTC Module – Keep Track of Time (MicroPython)

In this guide you’ll learn how to interface a DS1307 RTC module with the Raspberry Pi Pico programmed with MicroPython. We’ll cover the basic functioning of the module, how to connect it to the Pico, how to set and keep track of its time. Finally, we’ll create a simple digital clock with an OLED display.

Raspberry Pi Pico: DS1307 RTC Module - Keep Track of Time (MicroPython)

Table of Contents:

In this tutorial, we’ll cover the following subjects:

Prerequisites – MicroPython Firmware

To follow this tutorial you need MicroPython firmware installed in your Raspberry Pi Pico board. You also need an IDE to write and upload the code to your board.

The recommended MicroPython IDE for the Raspberry Pi Pico is Thonny IDE. Follow the next tutorial to learn how to install Thonny IDE, flash MicroPython firmware, and upload code to the board.

Real-Time Clock (RTC) Modules

To keep track of time when your Raspberry Pi Pico is not connected to your computer or to the internet, we can use Real-Time Clock (RTC) modules.

RTC modules, such as the DS3231 and DS1307, have their own tiny clock inside to keep track of time by themselves. Usually, they come with a battery holder to connect a battery so that they keep working even if the Raspberry Pi Pico resets or loses power.

The DS3231 and the DS1307 are some of the most popular choices to use with microcontrollers. Both are compatible with the Raspberry Pi Pico and communicate via I2C communication protocol. The DS3231 is more accurate because it comes with a temperature sensor and gives temperature-compensated results. Nonetheless, the DS1307 is also accurate and suitable for most applications that need to keep track of time.

Introducing the DS1307 RTC Module

Throughout this tutorial, we’ll be using the DS1307 RTC Module, but if you have a DS3231, most of the information provided applies to both modules. Additionally, all the code should be compatible with both modules with just a small change.

DS1307 RTC Module

The DS1307 RTC Module comes with the DS1307 chip (to keep track of time) and the AT24C32 EEPROM (to save data permanently). It can also be programmed to output square waves with different frequencies. We’ll only use the DS1307 chip features for timekeeping.

DS1307 Battery Holder

It comes with a battery holder to connect a CR2032 battery to keep accurate timekeeping. In the event of a power outage, it can still keep track of time accurately.

This module also comes with the option to connect a DS18B20 temperature. After connecting that sensor to the module, you can get the temperature from the module DS pin.

DS1307 RTC Real Time Clock Battery Holder
DS1307 RTC Real Time Clock Battery Holder with Battery

DS1307 RTC Module I2C Address

By default, the address of the DS1307 RTC is 0x68 and the EEPROM connected to the module is 0x50. You can run an I2C scanner sketch to double-check these values:

DS1307 RTC Module Pinout

The following table quickly describes the DS1307 RTC Module Pinout.

SQOutput for square waves (we won’t use)
DSOutput for temperature readings if DS18B20 is connected (we won’t use)
SCLSCL pin for I2C
SDASDA pin for I2C
VCCProvides power to the module (3.3V or 5V)
GNDGND
BATBackup supply input (we won’t use) or use the default battery holder

Connecting the DS1307 RTC Module to the Pico

Here’s a list of the parts required for this tutorial:

You can use the preceding links or go directly to MakerAdvisor.com/tools to find all the parts for your projects at the best price!

We’ll only use the I2C and power pins to interface the RTC module with the Raspberry Pi Pico. We’ll connect SCL to GPIO 5 and SDA to GPIO 4. You can use any other suitable I2C pins, as long as you change them on the code. You can use the following table as a reference or take a look at the schematic diagram.

DS1307 RTC ModuleRaspberry Pi Pico
SCLGPIO 5
SDAGPIO 4
VCC3V3(OUT)
GNDGND
Raspberry Pi Pico DS1307 RTC Module Wiring

Recommended reading: Raspberry Pi Pico and Pico W Pinout Guide: GPIOs Explained

MicroPython Library for RTC Modules

To make it easier to program the Raspberry Pi Pico to interface with the RTC module, we’ll use the library that can be found in the following link.

This library is compatible with both the DS1307 and DS3231 RTC modules.

Uploading the urtc.py Library

Upload the library to your Raspberry Pi Pico by following the next steps:

  1. Click here to download the urtc.py library code.
  2. Create a new file in Thonny IDE and copy the library code.
  3. Go to File > Save as and select Raspberry Pi Pico.
  4. Name the file urtc.py and click OK to save the file on the Raspberry Pi Pico.

And that’s it. The library was uploaded to your board. Now, you can use the library functionalities in your code by importing the library.

Synchronizing the RTC Module

The first thing you should do when using an RTC module in your projects is to synchronize the RTC time with your local time. For that, you can use the following code:

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-ds1307-rtc-micropython/

import time
import urtc
from machine import I2C, Pin

days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

# Initialize RTC (connected to I2C)
i2c = I2C(0, scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c)

# Set the current time using a specified time tuple
# Time tupple: (year, month, day, day of week, hour, minute, seconds, milliseconds)
#initial_time = (2024, 1, 30, 1, 12, 30, 0, 0)

# Or get the local time from the system
initial_time_tuple = time.localtime() #tuple (microPython)
initial_time_seconds = time.mktime(initial_time_tuple) # local time in seconds

# Convert to tuple compatible with the library
initial_time = urtc.seconds2tuple(initial_time_seconds)

# Sync the RTC
rtc.datetime(initial_time)

while True:
    current_datetime = rtc.datetime()
    print('Current date and time:')
    print('Year:', current_datetime.year)
    print('Month:', current_datetime.month)
    print('Day:', current_datetime.day)
    print('Hour:', current_datetime.hour)
    print('Minute:', current_datetime.minute)
    print('Second:', current_datetime.second)
    print('Day of the Week:', days_of_week[current_datetime.weekday])

    time.sleep(1)

View raw code

How the Code Works

Let’s take a quick look at the relevant parts of this code.

Import Libraries

First, you need to import the urtc module you’ve imported previously that contains the functions to interact with the RTC. You also need to import the Pin and I2C classes to establish an I2C communication with the module.

import time
import urtc
from machine import I2C, Pin

Initialize the RTC Module

Then, initialize I2C communication and create an object called rtc to refer to our DS1307 RTC module.

i2c = I2C(0, scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c)

If you’re using a DS3231, you should replace the following line:

rtc = urtc.DS1307(i2c)

With:

rtc = urtc.DS3231(i2c)

Synchronize the Time

To synchronize the RTC time, you must use the datetime() method on the rtc object and pass as an argument a time tuple with the following format:

(year, month, day, day of week, hour, minute, seconds, milliseconds)

Note: this tuple is different from the one used by the MicroPython time module.

We can synchronize the RTC with the system’s local time.

First, we get the time tuple of the local time using time.localtime().

initial_time = urtc.seconds2tuple(initial_time_seconds)

The tuple returned is different from the one used by the RTC module.

So, first, we convert it to seconds using time.mktime().

initial_time_seconds = time.mktime(initial_time_tuple) # local time in seconds

And finally, we convert it to a tuple that is compatible with the library using the seconds2tuple() function from the urtc library that accepts as an argument the number of seconds since epoch for the local time.

initial_time = urtc.seconds2tuple(initial_time_seconds)

Finally, we can pass our initial_time variable that contains the local time in a tuple compatible with the RTC library to the datetime() function as follows.

rtc.datetime(initial_time)

After this line of code, the RTC module is synchronized with your local time and you can simply call rtc.datetime() to get the current time from the RTC. This returns an object with all the time elements.

To get and print each time element, we can do as follows:

current_datetime = rtc.datetime()
print('Current date and time:')
print('Year:', current_datetime.year)
print('Month:', current_datetime.month)
print('Day:', current_datetime.day)
print('Hour:', current_datetime.hour)
print('Minute:', current_datetime.minute)
print('Second:', current_datetime.second)
print('Day of the Week:', days_of_week[current_datetime.weekday])

Run the Code

Run this previous code to synchronize the RTC time with the local time.

Run script Thonny IDE MicroPython

From now on, if the RTC has an attached battery, it will keep the time synchronized with your local time. So, you don’t need to synchronize it anymore, and you can call rtc.datetime() to get the current time.

Getting Time from the RTC Module

In this section, we provide an example that gets the time from the RTC module (that should already be synchronized after running the previous example) and displays it on an OLED display.

Raspberry Pi Pico Digital Clock with OLED and RTC Module

Make sure you’ve run the example of the previous section first to synchronize the RTC. Also, don’t forget that you need the ssd1306.py module imported to your Raspberry Pi Pico. Follow the next instructions to upload the ssd1306.py module to your board.

  1. Create a new file in Thonny IDE and copy the library code. The OLED library code can be found here.
  2. Go to File Save as and select Raspberry Pi Pico.
  3. Name the file ssd1306.py and click OK to save the file on the Raspberry Pi Pico.

Recommended reading: Raspberry Pi Pico: SSD1306 OLED Display (MicroPython)

Wiring the Circuit

We’ll connect the OLED display to GPIO 0 (SDA) and GPIO 1 (SCL/SCK). We’ll use GPIO 4 (SDA) and GPIO 5 (SCL) to connect the RTC. You can use the following table or diagram as a reference.

SDASCL/SDK
OLED DisplayGPIO 0GPIO 1
RTC ModuleGPIO 4GPIO 5
Raspberry Pi Pico with RTC and OLED Display

Code

Upload the following code as main.py to your Raspberry Pi Pico.

# Rui Santos & Sara Santos - Random Nerd Tutorials
# Complete project details at https://RandomNerdTutorials.com/raspberry-pi-pico-ds1307-rtc-micropython/

import time
import urtc
from machine import SoftI2C, Pin
import ssd1306

days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

# Initialize RTC Module
i2c_rtc = SoftI2C(scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c_rtc)

# Initialize OLED 
oled_width = 128
oled_height = 64
i2c_oled = SoftI2C(scl=Pin(0), sda=Pin(1))
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c_oled)

while True:
    # Get current time from the RTC
    current_datetime = rtc.datetime()

    # Format the date and time as strings
    formatted_date = '{:02d}-{:02d}-{:04d}'.format(current_datetime.day, current_datetime.month, current_datetime.year)
    formatted_time = '{:02d}:{:02d}:{:02d}'.format(current_datetime.hour, current_datetime.minute, current_datetime.second)
    formatted_day_week = days_of_week[current_datetime.weekday]

    # Clear the OLED display
    oled.fill(0)

    # Display the formatted date and time
    oled.text('Date: ' + formatted_day_week, 0, 0)
    oled.text(formatted_date, 0, 16)
    oled.text('Time: ' + formatted_time, 0, 32)
    oled.show()

    # Print the formatted date and time to the shell
    print('Formatted date:', formatted_date)
    print('Formatted time:', formatted_time)

    # Wait for 1 second
    time.sleep(1)

View raw code

How Does the Code Work?

First, we import the required libraries.

import time
import urtc
from machine import SoftI2C, Pin
import ssd1306

We create an array with the days of the week.

days_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']

Initialize the RTC module.

# Initialize RTC Module
i2c_rtc = SoftI2C(scl=Pin(5), sda=Pin(4))
rtc = urtc.DS1307(i2c_rtc)

Initialize the OLED display.

# Initialize OLED 
oled_width = 128
oled_height = 64
i2c_oled = SoftI2C(scl=Pin(0), sda=Pin(1))
oled = ssd1306.SSD1306_I2C(oled_width, oled_height, i2c_oled)

Get the current date and time from the RTC module.

while True:
    # Get current time from the RTC
    current_datetime = rtc.datetime()

Extract the date and time from the current_datetime variable and format them as strings. Also, get the day of the week.

# Format the date and time as strings
formatted_date = '{:02d}-{:02d}-{:04d}'.format(current_datetime.day, current_datetime.month, current_datetime.year)
formatted_time = '{:02d}:{:02d}:{:02d}'.format(current_datetime.hour, current_datetime.minute, current_datetime.second)
formatted_day_week = days_of_week[current_datetime.weekday]

Finally, we display the formatted date and time on the OLED display.

# Clear the OLED display
oled.fill(0)

# Display the formatted date and time
oled.text('Date: ' + formatted_day_week, 0, 0)
oled.text(formatted_date, 0, 16)
oled.text('Time: ' + formatted_time, 0, 32)
oled.show()

We also display the date and time on the shell.

# Print the formatted date and time to the shell
print('Formatted date:', formatted_date)
print('Formatted time:', formatted_time)

The time is updated on the screen every second.

# Wait for 1 second
time.sleep(1)

Testing the Code

After uploading the code to your board with the name main.py:

  1. Go to File > Save as and select Raspberry Pi Pico.
  2. Name the file main.py and click OK to save the file on the Raspberry Pi Pico.

Disconnect the Raspberry Pi from the REPL and notice that it displays the correct date and time thanks to timekeeping with the RTC module. You can remove and apply power again and it will always show the accurate date and time.

Raspberry Pi Pico Clock with OLED Display and RTC Module

Wrapping Up

In this guide, you learned how to synchronize the RTC module with the system’s time and how to get synchronized time from it. You also learned how to create a simple digital clock that display the day of the week, date, and time.

We hope you found this guide useful. Another alternative to get date and time is using a GPS module.

 If you want to learn more about the Raspberry Pi Pico, check out our resources:

Thanks for reading.



Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »
Learn how to build a home automation system and we’ll cover the following main subjects: Node-RED, Node-RED Dashboard, Raspberry Pi, ESP32, ESP8266, MQTT, and InfluxDB database DOWNLOAD »

Recommended Resources

Build a Home Automation System from Scratch » With Raspberry Pi, ESP8266, Arduino, and Node-RED.

Home Automation using ESP8266 eBook and video course » Build IoT and home automation projects.

Arduino Step-by-Step Projects » Build 25 Arduino projects with our course, even with no prior experience!

What to Read Next…


Enjoyed this project? Stay updated by subscribing our newsletter!

Leave a Comment

Download Our Free eBooks and Resources

Get instant access to our FREE eBooks, Resources, and Exclusive Electronics Projects by entering your email address below.