Home Circuitpython Adafruit Feather M0 and DS3231 RTC circuitpython example

Adafruit Feather M0 and DS3231 RTC circuitpython example

by shedboy71

In this example we connect a DS3231 RTC to an Adafruit Feather M0 running Circuitpython

First lets look at some information about the chip from the manufacturer

The DS3231 is a low-cost, extremely accurate I²C real-time clock (RTC) with an integrated temperature-compensated crystal oscillator and crystal. The device incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted.

The integration of the crystal resonator enhances the long-term accuracy of the device as well as reduces the piece-part count in a manufacturing line. The DS3231 is available in commercial and industrial temperature ranges, and is offered in a 16-pin, 300-mil SO package.

The RTC maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year.

The clock operates in either the 24-hour or 12-hour format with an active-low AM/PM indicator. Two programmable time-of-day alarms and a programmable square-wave output are provided. Address and data are transferred serially through an I²C bidirectional bus.

A precision temperature-compensated voltage reference and comparator circuit monitors the status of VCC to detect power failures, to provide a reset output, and to automatically switch to the backup supply when necessary. Additionally, the active-low RST pin is monitored as a pushbutton input for generating a µP reset.


Highly Accurate RTC Completely Manages All Timekeeping Functions
Real-Time Clock Counts Seconds, Minutes, Hours, Date of the Month, Month, Day of the Week, and Year, with Leap-Year Compensation Valid Up to 2100
Accuracy ±2ppm from 0°C to +40°C
Accuracy ±3.5ppm from -40°C to +85°C
Digital Temp Sensor Output: ±3°C Accuracy
Register for Aging Trim
Active-Low RST Output/Pushbutton Reset Debounce Input
Two Time-of-Day Alarms
Programmable Square-Wave Output Signal
Simple Serial Interface Connects to Most Microcontrollers
Fast (400kHz) I2C Interface
Battery-Backup Input for Continuous Timekeeping
Low Power Operation Extends Battery-Backup Run Time
3.3V Operation
Operating Temperature Ranges: Commercial (0°C to +70°C) and Industrial (-40°C to +85°C)

This was my module of choice that I used, it is a commonly found low cost option that allows you easily connect it up to your board of choice. It contains a battery and eeprom as well the DS3231

Parts Required


Name Link
Adafruit Feather M0 Express Adafruit (PID 3403) Feather M0 Express – Designed for CircuitPython – ATSAMD21 Cortex M0
DS3231 module DS3231 AT24C32 IIC Precision RTC Real Time Clock Memory Module
Connecting cables Free shipping Dupont line 120pcs 20cm male to male + male to female and female to female jumper wire



This is not the exact same module but the wiring is the same

feather and DS3231 layout

feather and DS3231 layout

Code Example

I used Mu for development

The following is based on a library , I copied the adafruit_ds3231 library for this device to the lib folder on my Feather M0 Express – https://circuitpython.org/libraries

This is the basic example which comes with the library – a little bit tweaked

# 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
# For hardware I2C (M0 boards) use this line:
import busio as io
# Or for software I2C (ESP8266) use this line instead:
# import bitbangio as io
import adafruit_ds3231
i2c = io.I2C(board.SCL, board.SDA)  # Change to the appropriate I2C clock & data
# pins here!
# Create the RTC instance:
rtc = adafruit_ds3231.DS3231(i2c)
# Lookup table for names of days (nicer printing).
days = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
# pylint: disable-msg=bad-whitespace
# pylint: disable-msg=using-constant-test
if True:  # change to False if you do not want to set the time!
    #                     year, mon, date, hour, min, sec, wday, yday, isdst
    t = time.struct_time((2020, 03, 24, 16, 00, 00, 2, -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
# pylint: enable-msg=bad-whitespace
# 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


Here is what I saw in Mu REPL window

The date is Tuesday 24/3/2020
The time is 16:00:00
The date is Tuesday 24/3/2020
The time is 16:00:01
The date is Tuesday 24/3/2020
The time is 16:00:02
The date is Tuesday 24/3/2020
The time is 16:00:03



You may also like

Leave a Comment