It's easy to use the DS3231 RTC with CircuitPython too!  There's a handy Adafruit CircuitPython DS3231 module you can load on a board and get started setting and reading the time with Python code!

CircuitPython Wiring

First wire up the DS3231 to your board as shown on the previous Arduino page.  The DS3231 uses a simple I2C connection with:

  • Vin (red wire) connected to your board's 3.3V or 5V output.
  • GND (black wire) connected to your board's ground.
  • SCL (yellow wire) connected to your board's I2C SCL / clock line.
  • SDA (blue wire) connected to your board's I2C SDA / data line.

CircuitPython Library Installation

You'll also need to install the Adafruit CircuitPython DS3231 library on your CircuitPython board.  Remember this module is for Adafruit CircuitPython firmware and not firmware!

First make sure you are running the latest version of Adafruit CircuitPython for your board.

Next you'll need to install the necessary libraries to use the hardware--carefully follow the steps to find and install these libraries from Adafruit's CircuitPython library bundle.  For example the Circuit Playground Express guide has a great page on how to install the library bundle for both express and non-express boards.

Remember for non-express boards like the Trinket M0, Gemma M0, and Feather/Metro M0 basic you'll need to manually install the necessary libraries from the bundle:

  • adafruit_ds3231.mpy
  • adafruit_bus_device
  • adafruit_register

Before continuing make sure your board's lib folder or root filesystem has the adafruit_ds3231.mpy, adafruit_bus_device, and adafruit_register files and folders copied over.

CircuitPython Usage

Next connect to the board's serial REPL so you are at the CircuitPython >>> prompt.

Then import the necessary board module to initialize the I2C bus:

import board
i2c = board.I2C()

Note on some boards like the ESP8266 that don't have a hardware I2C interface you might need to instead import and use the bitbangio module, like:

import board
import bitbangio
i2c = bitbangio.I2C(board.SCL, board.SDA)

Now import the DS3231 module and create an instance of the DS3231 class using the I2C interface created above:

      import adafruit_ds3231
ds3231 = adafruit_ds3231.DS3231(i2c)

At this point you're read to read and even set the time of the clock.  You just need to interact with the datetime property of the DS3231 instance.  For example to read it you can run:


Notice the time is returned as a special Python time structure.  This is from the time module in Python and it has properties like:

  • tm_year - The year of the timestamp
  • tm_mon - The month of the timestamp
  • tm_mday - The day of the month of the timestamp
  • tm_hour - The hour of the timestamp
  • tm_min - The minute of the timestamp
  • tm_sec - The second of the timestamp
  • tm_wday - The day of the week (0 = Monday, 6 = Sunday)
  • tm_yday - The day within the year (1-366)
  • tm_isdst - 0 if not in daylight savings, 1 if in savings, and -1 if unknown

Also notice if the time hasn't been set it defaults to a value of January 1st, 2000 (wow Y2K retro!).

You can write to the datetime property to set the time of the clock, for example to set it to January 1st, 2017, at midnight local time you could run:

import time
ds3231.datetime = time.struct_time((2017, 1, 1, 0, 0, 0, 6, 1, -1))

Notice the parameters to the struct_time initializer, you must pass in a tuple of all the values listed above.

Now if you read the datetime property you'll see the clock is running from the set time.  For example if you want to read and print out just the year, month, day, hour, minute, and second you could run:

current = ds3231.datetime
print('The current time is: {}/{}/{} {:02}:{:02}:{:02}'.format(current.tm_mon, current.tm_mday, current.tm_year, current.tm_hour, current.tm_min, current.tm_sec))

That's all there is to using the DS3231 with CircuitPython!  Simply import the DS3231 module, create an instance of the class, and interact with its datetime property to set and get the time!

Here's a complete example program you can save as on your board and see the time and date printed every second to the REPL:

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

# Simple demo of reading and writing the time for the DS3231 real-time clock.
# Change the if False to if True below to set the time, otherwise it will just
# print the current date and time every second.  Notice also comments to adjust
# for working with hardware vs. software I2C.

import time
import board
import adafruit_ds3231

i2c = board.I2C()  # uses board.SCL and board.SDA
# i2c = board.STEMMA_I2C()  # For using the built-in STEMMA QT connector on a microcontroller
rtc = adafruit_ds3231.DS3231(i2c)

# Lookup table for names of days (nicer printing).
days = ("Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday")

# pylint: disable-msg=using-constant-test
if False:  # change to True if you want to set the time!
    #                     year, mon, date, hour, min, sec, wday, yday, isdst
    t = time.struct_time((2017, 10, 29, 15, 14, 15, 0, -1, -1))
    # you must set year, mon, date, hour, min, sec and weekday
    # yearday is not supported, isdst can be set but we don't do anything with it at this time
    print("Setting time to:", t)  # uncomment for debugging
    rtc.datetime = t
# pylint: enable-msg=using-constant-test

# Main loop:
while True:
    t = rtc.datetime
    # print(t)     # uncomment for debugging
        "The date is {} {}/{}/{}".format(
            days[int(t.tm_wday)], t.tm_mday, t.tm_mon, t.tm_year
    print("The time is {}:{:02}:{:02}".format(t.tm_hour, t.tm_min, t.tm_sec))
    time.sleep(1)  # wait a second

This guide was first published on Feb 03, 2016. It was last updated on Nov 28, 2023.

This page (CircuitPython) was last updated on Nov 28, 2023.

Text editor powered by tinymce.