{"id":165176,"date":"2025-02-19T10:08:45","date_gmt":"2025-02-19T10:08:45","guid":{"rendered":"https:\/\/randomnerdtutorials.com\/?p=165176"},"modified":"2025-02-19T10:08:48","modified_gmt":"2025-02-19T10:08:48","slug":"raspberry-pi-pico-ds3231-rtc-micropython","status":"publish","type":"post","link":"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-ds3231-rtc-micropython\/","title":{"rendered":"Raspberry Pi Pico: DS3231 RTC (Real-Time Clock) &#8211; Get Time and Set Alarms (MicroPython)"},"content":{"rendered":"\n<p>This is a getting started guide that shows how to interface the DS3231 Real Time Clock Module with the Raspberry Pi Pico board programmed with MicroPython: learn how to set and get the time, set alarms, and get temperature readings.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" fetchpriority=\"high\" decoding=\"async\" width=\"1200\" height=\"675\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/Raspberry-Pi-Pico-DS3231-Micropython.jpg?resize=1200%2C675&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico with DS3231 RTC (Real-Time Clock): Getting Time and Setting Alarms (MicroPython)\" class=\"wp-image-165188\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/Raspberry-Pi-Pico-DS3231-Micropython.jpg?w=1920&amp;quality=100&amp;strip=all&amp;ssl=1 1920w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/Raspberry-Pi-Pico-DS3231-Micropython.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/Raspberry-Pi-Pico-DS3231-Micropython.jpg?resize=1024%2C576&amp;quality=100&amp;strip=all&amp;ssl=1 1024w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/Raspberry-Pi-Pico-DS3231-Micropython.jpg?resize=768%2C432&amp;quality=100&amp;strip=all&amp;ssl=1 768w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/Raspberry-Pi-Pico-DS3231-Micropython.jpg?resize=1536%2C864&amp;quality=100&amp;strip=all&amp;ssl=1 1536w\" sizes=\"(max-width: 1200px) 100vw, 1200px\" \/><\/figure><\/div>\n\n\n<p>The DS3231 RTC module is a great module for accurate timekeeping, it also allows you to set alarms, output square waves with different frequencies, and get temperature readings<\/p>\n\n\n\n<p><strong>Table of Contents<\/strong><\/p>\n\n\n\n<p>In this tutorial, we&#8217;ll cover the following topics:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"#intro-rtc\" title=\"\">Introducing Real-Time Clock (RTC) Modules<\/a><\/li>\n\n\n\n<li><a href=\"#intro-ds3231\" title=\"\">Introducing the DS3231 RTC Module<\/a><\/li>\n\n\n\n<li><a href=\"#ds3231-esp32-rpi-pico-wiring\" title=\"\">Connecting the DS3231 RTC Module to the Raspberry Pi Pico<\/a><\/li>\n\n\n\n<li><a href=\"#ds3231-micropython-module\" title=\"\">DS3231 RTC MicroPython Module<\/a><\/li>\n\n\n\n<li><a href=\"#get-date-time\" title=\"Setting and Getting the Time\">Setting and Getting the Time<\/a><\/li>\n\n\n\n<li><a href=\"#set-alarms\" title=\"\">Setting Alarms<\/a><\/li>\n\n\n\n<li><a href=\"#periodic-alarms\" title=\"\">Setting Periodic Alarms<\/a><\/li>\n<\/ul>\n\n\n\n<p class=\"rntbox rntclblue\"><strong>New to the Raspberry Pi Pico?<\/strong> <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-micropython-ebook\/\" title=\"\">Check out our eBook: Learn Raspberry Pi Pico\/Pico W with MicroPython<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"prerequisites\">Prerequisites \u2013 MicroPython Firmware<\/h2>\n\n\n\n<p>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.<\/p>\n\n\n\n<p>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.<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/getting-started-raspberry-pi-pico-w\/#install-thonny-ide\">Programming Raspberry Pi Pico using MicroPython<\/a><\/li>\n<\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"intro-rtc\">Introducing Real-Time Clock (RTC) Modules<\/h2>\n\n\n\n<p>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.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC3231-DS1307-RTC-Modules.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RTC DS3231 and RTC DS1307 Modules\" class=\"wp-image-164850\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC3231-DS1307-RTC-Modules.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC3231-DS1307-RTC-Modules.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>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 gives temperature-compensated results. Additionally, it&#8217;s also possible to set external alarms with the DS3231, which can be extremely useful.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"intro-ds3231\">Introducing the DS3231 RTC Module<\/h2>\n\n\n\n<p>The following picture shows the DS3231 RTC Module. It uses a 32kHz temperature-compensated crystal oscillator (TCXO) to keep track of time in a precise way (it&#8217;s resistant to temperature changes). Because of that, it also allows you to get temperature data.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-Module.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RTC DS3231 Module\" class=\"wp-image-164851\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-Module.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-Module.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Besides keeping track of the date and time precisely, it also has built-in memory for storing up to two alarms and can output square waves at different frequencies: 1Hz, 4kHz, 8kHz, and 32kHz.<\/p>\n\n\n\n<p>You communicate with the RTC module using I2C communication protocol. Usually, it&#8217;s on address 0x68.  <\/p>\n\n\n\n<p>This module also comes with a 24C32 32-byte EEPROM that you can use to store any non-volatile data that you want. You can communicate with this EEPROM memory via I2C by addressing the right address (0x57).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">DS3231 Battery Holder<\/h3>\n\n\n\n<p>The DS3231 comes with a battery holder to connect a battery to keep accurate timekeeping. In the event of a power outage, it can still keep track of time accurately and keep all the alarms.<\/p>\n\n\n\n<p>You <strong>should use a LIR2032 battery, which is rechargeable<\/strong>. Don&#8217;t use a CR2032&nbsp;(not rechargeable). <\/p>\n\n\n\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-Module-back.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RTC DS3231 Battery Holder\" class=\"wp-image-164852\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-Module-back.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-Module-back.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure>\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<figure class=\"wp-block-image size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS3231-Battery-Holder.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"DS3231 RTC Module with Battery Back-up\" class=\"wp-image-164853\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS3231-Battery-Holder.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS3231-Battery-Holder.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure>\n<\/div>\n<\/div>\n\n\n\n<p>If you want to use a CR2032 battery, which is non-rechargeable, you must disconnect the battery charging circuit by unsoldering and removing the resistor (labeled R4 in my module) next to the diode.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-remove-resistor-for-nor-rechargeable-battery.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RTC DS3231 Remove Resistor for non re-chargeable battery\" class=\"wp-image-164864\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-remove-resistor-for-nor-rechargeable-battery.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2024\/12\/RTC-DS32321-remove-resistor-for-nor-rechargeable-battery.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\">DS3231 Alarms<\/h3>\n\n\n\n<p>The DS3231 can store up to two alarms: <strong>alarm 1<\/strong> and <strong>alarm 2<\/strong>. These alarms can be configured to trigger based on a specific time and\/or date. When an alarm is triggered, the SQW pin of the module outputs a LOW signal.<\/p>\n\n\n\n<p>You can detect this signal with the Raspberry Pi Pico and <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-motion-pir-micropython\/\" title=\"\">trigger interrupts<\/a>. This feature is extremely useful for periodic tasks, time-based automation and also one-time alerts (because you can clear an alarm after it&#8217;s triggered).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">DS3231 RTC Module I2C Address<\/h3>\n\n\n\n<p>By default, the address of the DS3231 RTC is <strong>0x68<\/strong> and the EEPROM connected to the module is 0x57. You can run an <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-i2c-scanner-micropython\/\" title=\"\">I2C scanner sketch to double-check the addresses<\/a>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">DS3231 RTC Module Pinout<\/h3>\n\n\n\n<p>The following table quickly describes the DS3231 RTC Module Pinout.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><td><strong>32K<\/strong><\/td><td>32kHz oscillator output \u2014 can be used as a clock reference<\/td><\/tr><tr><td><strong>SQW<\/strong><\/td><td>Square wave\/Interrupt output<\/td><\/tr><tr><td><strong>SCL<\/strong><\/td><td>SCL pin for I2C<\/td><\/tr><tr><td><strong>SDA<\/strong><\/td><td>SDA pin for I2C<\/td><\/tr><tr><td><strong>VCC<\/strong><\/td><td>Provides power to the module (3.3V or 5V)<\/td><\/tr><tr><td><strong>GND<\/strong><\/td><td>GND<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h1 class=\"wp-block-heading\" id=\"ds3231-esp32-rpi-pico-wiring\">Connecting the DS3231 RTC Module to the Raspberry Pi Pico<\/h1>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Wiring.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Wiring the DS3231 Module to the Raspberry Pi Pico\" class=\"wp-image-165186\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Wiring.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Wiring.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Here\u2019s a list of the parts required for this tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/raspberry-pi-pico-w\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Raspberry Pi Pico board<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/ds3231-rtc-module\/\" target=\"_blank\" rel=\"noopener\" title=\"DS3231 RTC Module\">DS3231 RTC Module<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/3mm-5mm-leds-kit-storage-box\/\" target=\"_blank\" rel=\"noopener\" title=\"\">LED<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/resistors-kits\/\" target=\"_blank\" rel=\"noopener\" title=\"\">220 Ohm resistor<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/jumper-wires-kit-120-pieces\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Jumper wires<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/makeradvisor.com\/tools\/mb-102-solderless-breadboard-830-points\/\" target=\"_blank\" rel=\"noopener\" title=\"\">Breadboard<\/a><\/li>\n<\/ul>\n\n\n<p>You can use the preceding links or go directly to <a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\">MakerAdvisor.com\/tools<\/a> to find all the parts for your projects at the best price!<\/p><p style=\"text-align:center;\"><a href=\"https:\/\/makeradvisor.com\/tools\/?utm_source=rnt&utm_medium=post&utm_campaign=post\" target=\"_blank\"><img data-recalc-dims=\"1\" decoding=\"async\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2017\/10\/header-200.png?w=1200&#038;quality=100&#038;strip=all&#038;ssl=1\"><\/a><\/p>\n\n\n\n<p>Wire the DS3231 to the Raspberry Pi Pico. You can use the following table as a reference. We&#8217;re using the default I2C pins.<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table><tbody><tr><td><strong>DS3231 RTC Module<\/strong><\/td><td><strong>Raspberry Pi Pico<\/strong><\/td><\/tr><tr><td>SQW<\/td><td><span class=\"rnthl rntclblue\">GPIO 3<\/span> (or any other digital pin)<\/td><\/tr><tr><td>SCL<\/td><td><span class=\"rnthl rntcyellow\">GPIO 5<\/span><\/td><\/tr><tr><td>SDA<\/td><td><span class=\"rnthl rntclgray\">GPIO 4<\/span><\/td><\/tr><tr><td>VCC<\/td><td><span class=\"rnthl rntcred\">3V3<\/span><\/td><\/tr><tr><td>GND<\/td><td><span class=\"rnthl rntcblack\">GND<\/span><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p class=\"rntbox rntclblue\"><\/p>\n\n\n\n<p class=\"rntbox rntclblue\">You may also like: <a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-pinout-gpios\/\" title=\"\">Raspberry Pi Pico and Pico W Pinout Guide: GPIOs Explained<\/a>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"working-with-rtc\">Working with the RTC<\/h2>\n\n\n\n<p>Using an RTC module in your projects always requires two important steps.<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Setting the current time<\/strong>: you can do it manually by inserting the current time (or a different desired time) on the code; the system&#8217;s local time; or get the time from an NTP server.<\/li>\n\n\n\n<li><strong>Retaining the time<\/strong>: to make sure the RTC keeps the correct time, even if it loses power, it needs to be connected to a battery. RTC modules come with a battery holder, usually for a coin cell.<\/li>\n<\/ol>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"ds3231-micropython-module\">DS3231 RTC MicroPython Module<\/h2>\n\n\n\n<p>There are different libraries with different features that make it easy to communicate with the DS3231 RTC module. We&#8217;ll use a slightly modified version of the <em>urtc.py<\/em> module developed by Adafruit.<\/p>\n\n\n\n<p>Follow the next steps to install the required module.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Download and Upload the&nbsp;<em>urtc.py<\/em><\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li><a href=\"https:\/\/raw.githubusercontent.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/refs\/heads\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/urtc.py\" target=\"_blank\" rel=\"noopener\" title=\"\">Click here to download the\u00a0<em>urtc.py<\/em>\u00a0code<\/a>;<\/li>\n\n\n\n<li>Copy the code to a file on Thonny IDE;<\/li>\n\n\n\n<li>Go to&nbsp;<strong>File<\/strong>&nbsp;&gt;&nbsp;<strong>Save as\u2026<\/strong>&nbsp;and select Raspberry Pi Pico;<\/li>\n\n\n\n<li>Save the file with the name&nbsp;<strong><em>urtc.py<\/em><\/strong>&nbsp;(don\u2019t change the name).<\/li>\n<\/ol>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Forked and adapted from https:\/\/github.com\/adafruit\/Adafruit-uRTC\/tree\/master\n\nimport collections\nimport time\n\n\nDateTimeTuple = collections.namedtuple(&quot;DateTimeTuple&quot;, [&quot;year&quot;, &quot;month&quot;,\n    &quot;day&quot;, &quot;weekday&quot;, &quot;hour&quot;, &quot;minute&quot;, &quot;second&quot;, &quot;millisecond&quot;])\n\n\ndef datetime_tuple(year=None, month=None, day=None, weekday=None, hour=None,\n                   minute=None, second=None, millisecond=None):\n    return DateTimeTuple(year, month, day, weekday, hour, minute,\n                         second, millisecond)\n\n\ndef _bcd2bin(value):\n    return (value or 0) - 6 * ((value or 0) &gt;&gt; 4)\n\n\ndef _bin2bcd(value):\n    return (value or 0) + 6 * ((value or 0) \/\/ 10)\n\n\ndef tuple2seconds(datetime):\n    return time.mktime((datetime.year, datetime.month, datetime.day,\n        datetime.hour, datetime.minute, datetime.second, datetime.weekday, 0))\n\n\ndef seconds2tuple(seconds):\n    (year, month, day, hour, minute,\n     second, weekday, _yday) = time.localtime(seconds)\n    return DateTimeTuple(year, month, day, weekday, hour, minute, second, 0)\n\n\nclass _BaseRTC:\n    _SWAP_DAY_WEEKDAY = False\n\n    def __init__(self, i2c, address=0x68):\n        self.i2c = i2c\n        self.address = address\n\n    def _register(self, register, buffer=None):\n        if buffer is None:\n            return self.i2c.readfrom_mem(self.address, register, 1)[0]\n        self.i2c.writeto_mem(self.address, register, buffer)\n\n    def _flag(self, register, mask, value=None):\n        data = self._register(register)\n        if value is None:\n            return bool(data &amp; mask)\n        if value:\n            data |= mask\n        else:\n            data &amp;= ~mask\n        self._register(register, bytearray((data,)))\n\n\n    def datetime(self, datetime=None):\n        if datetime is None:\n            buffer = self.i2c.readfrom_mem(self.address,\n                                           self._DATETIME_REGISTER, 7)\n            if self._SWAP_DAY_WEEKDAY:\n                day = buffer[3]\n                weekday = buffer[4]\n            else:\n                day = buffer[4]\n                weekday = buffer[3]\n            return datetime_tuple(\n                year=_bcd2bin(buffer[6]) + 2000,\n                month=_bcd2bin(buffer[5]),\n                day=_bcd2bin(day),\n                weekday=_bcd2bin(weekday),\n                hour=_bcd2bin(buffer[2]),\n                minute=_bcd2bin(buffer[1]),\n                second=_bcd2bin(buffer[0]),\n            )\n        datetime = datetime_tuple(*datetime)\n        buffer = bytearray(7)\n        buffer[0] = _bin2bcd(datetime.second)\n        buffer[1] = _bin2bcd(datetime.minute)\n        buffer[2] = _bin2bcd(datetime.hour)\n        if self._SWAP_DAY_WEEKDAY:\n            buffer[4] = _bin2bcd(datetime.weekday)\n            buffer[3] = _bin2bcd(datetime.day)\n        else:\n            buffer[3] = _bin2bcd(datetime.weekday)\n            buffer[4] = _bin2bcd(datetime.day)\n        buffer[5] = _bin2bcd(datetime.month)\n        buffer[6] = _bin2bcd(datetime.year - 2000)\n        self._register(self._DATETIME_REGISTER, buffer)\n\n\nclass DS1307(_BaseRTC):\n    _NVRAM_REGISTER = 0x08\n    _DATETIME_REGISTER = 0x00\n    _SQUARE_WAVE_REGISTER = 0x07\n\n    def stop(self, value=None):\n        return self._flag(0x00, 0b10000000, value)\n\n    def memory(self, address, buffer=None):\n        if buffer is not None and address + len(buffer) &gt; 56:\n            raise ValueError(&quot;address out of range&quot;)\n        return self._register(self._NVRAM_REGISTER + address, buffer)\n\n\nclass DS3231(_BaseRTC):\n    _CONTROL_REGISTER = 0x0e\n    _STATUS_REGISTER = 0x0f\n    _DATETIME_REGISTER = 0x00\n    _TEMPERATURE_MSB_REGISTER = 0x11\n    _TEMPERATURE_LSB_REGISTER = 0x12\n    _ALARM_REGISTERS = (0x08, 0x0b)\n    _SQUARE_WAVE_REGISTER = 0x0e\n\n    def lost_power(self):\n        return self._flag(self._STATUS_REGISTER, 0b10000000)\n\n    def alarm(self, value=None, alarm=0):\n        return self._flag(self._STATUS_REGISTER,\n                          0b00000011 &amp; (1 &lt;&lt; alarm), value)\n\n    def interrupt(self, alarm=0):\n        return self._flag(self._CONTROL_REGISTER,\n                          0b00000100 | (1 &lt;&lt; alarm), 1)\n\n    def no_interrupt(self):\n        return self._flag(self._CONTROL_REGISTER, 0b00000011, 0)\n\n    def stop(self, value=None):\n        return self._flag(self._CONTROL_REGISTER, 0b10000000, value)\n\n    def datetime(self, datetime=None):\n        if datetime is not None:\n            status = self._register(self._STATUS_REGISTER) &amp; 0b01111111\n            self._register(self._STATUS_REGISTER, bytearray((status,)))\n        return super().datetime(datetime)\n\n    def alarm_time(self, datetime=None, alarm=0):\n        if datetime is None:\n            buffer = self.i2c.readfrom_mem(self.address,\n                                           self._ALARM_REGISTERS[alarm], 3)\n            day = None\n            weekday = None\n            second = None\n            if buffer[2] &amp; 0b10000000:\n                pass\n            elif buffer[2] &amp; 0b01000000:\n                day = _bcd2bin(buffer[2] &amp; 0x3f)\n            else:\n                weekday = _bcd2bin(buffer[2] &amp; 0x3f)\n            minute = (_bcd2bin(buffer[0] &amp; 0x7f)\n                      if not buffer[0] &amp; 0x80 else None)\n            hour = (_bcd2bin(buffer[1] &amp; 0x7f)\n                    if not buffer[1] &amp; 0x80 else None)\n            if alarm == 0:\n                # handle seconds\n                buffer = self.i2c.readfrom_mem(\n                    self.address, self._ALARM_REGISTERS[alarm] - 1, 1)\n                second = (_bcd2bin(buffer[0] &amp; 0x7f)\n                          if not buffer[0] &amp; 0x80 else None)\n            return datetime_tuple(\n                day=day,\n                weekday=weekday,\n                hour=hour,\n                minute=minute,\n                second=second,\n            )\n        datetime = datetime_tuple(*datetime)\n        buffer = bytearray(3)\n        buffer[0] = (_bin2bcd(datetime.minute)\n                     if datetime.minute is not None else 0x80)\n        buffer[1] = (_bin2bcd(datetime.hour)\n                     if datetime.hour is not None else 0x80)\n        if datetime.day is not None:\n            if datetime.weekday is not None:\n                raise ValueError(&quot;can't specify both day and weekday&quot;)\n            buffer[2] = _bin2bcd(datetime.day)\n        elif datetime.weekday is not None:\n            buffer[2] = _bin2bcd(datetime.weekday) | 0b01000000\n        else:\n            buffer[2] = 0x80\n        self._register(self._ALARM_REGISTERS[alarm], buffer)\n        if alarm == 0:\n            # handle seconds\n            buffer = bytearray([_bin2bcd(datetime.second)\n                                if datetime.second is not None else 0x80])\n            self._register(self._ALARM_REGISTERS[alarm] - 1, buffer)\n    \n    def get_temperature(self):\n        &quot;&quot;&quot;\n        Reads the temperature from the DS3231's temperature registers.\n        Returns the temperature as a float in Celsius.\n        &quot;&quot;&quot;\n        msb = self._register(self._TEMPERATURE_MSB_REGISTER)  # 0x11\n        lsb = self._register(self._TEMPERATURE_LSB_REGISTER)  # 0x12\n        \n        if msb is None or lsb is None:\n            print(&quot;Error: Register read returned None&quot;)\n            return None\n        \n        temp = msb + ((lsb &gt;&gt; 6) * 0.25)\n        if msb &amp; 0x80:\n            temp -= 256\n        \n        return temp\n\nclass PCF8523(_BaseRTC):\n    _CONTROL1_REGISTER = 0x00\n    _CONTROL2_REGISTER = 0x01\n    _CONTROL3_REGISTER = 0x02\n    _DATETIME_REGISTER = 0x03\n    _ALARM_REGISTER = 0x0a\n    _SQUARE_WAVE_REGISTER = 0x0f\n    _SWAP_DAY_WEEKDAY = True\n\n    def __init__(self, *args, **kwargs):\n        super().__init__(*args, **kwargs)\n        self.init()\n\n    def init(self):\n        # Enable battery switchover and low-battery detection.\n        self._flag(self._CONTROL3_REGISTER, 0b11100000, False)\n\n    def reset(self):\n        self._flag(self._CONTROL1_REGISTER, 0x58, True)\n        self.init()\n\n    def lost_power(self, value=None):\n        return self._flag(self._CONTROL3_REGISTER, 0b00010000, value)\n\n    def stop(self, value=None):\n        return self._flag(self._CONTROL1_REGISTER, 0b00010000, value)\n\n    def battery_low(self):\n        return self._flag(self._CONTROL3_REGISTER, 0b00000100)\n\n    def alarm(self, value=None):\n        return self._flag(self._CONTROL2_REGISTER, 0b00001000, value)\n\n    def datetime(self, datetime=None):\n        if datetime is not None:\n            self.lost_power(False) # clear the battery switchover flag\n        return super().datetime(datetime)\n\n    def alarm_time(self, datetime=None):\n        if datetime is None:\n            buffer = self.i2c.readfrom_mem(self.address,\n                                           self._ALARM_REGISTER, 4)\n            return datetime_tuple(\n                weekday=_bcd2bin(buffer[3] &amp;\n                                 0x7f) if not buffer[3] &amp; 0x80 else None,\n                day=_bcd2bin(buffer[2] &amp;\n                             0x7f) if not buffer[2] &amp; 0x80 else None,\n                hour=_bcd2bin(buffer[1] &amp;\n                              0x7f) if not buffer[1] &amp; 0x80 else None,\n                minute=_bcd2bin(buffer[0] &amp;\n                                0x7f) if not buffer[0] &amp; 0x80 else None,\n            )\n        datetime = datetime_tuple(*datetime)\n        buffer = bytearray(4)\n        buffer[0] = (_bin2bcd(datetime.minute)\n                     if datetime.minute is not None else 0x80)\n        buffer[1] = (_bin2bcd(datetime.hour)\n                     if datetime.hour is not None else 0x80)\n        buffer[2] = (_bin2bcd(datetime.day)\n                     if datetime.day is not None else 0x80)\n        buffer[3] = (_bin2bcd(datetime.weekday) | 0b01000000\n                     if datetime.weekday is not None else 0x80)\n        self._register(self._ALARM_REGISTER, buffer)\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/urtc.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>With the module loaded to the board, now you can use the library functionalities in your code to interface with the DS3231 RTC module.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"get-date-time\">DS3231 RTC with the Raspberry Pi Pico: Set and Get Time<\/h2>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Set-and-Get-Time.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"RPi Pico DS3231 Set and Get Time\" class=\"wp-image-165185\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Set-and-Get-Time.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Set-and-Get-Time.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>The following code synchronizes the RTC time with the system time, and gets the current date, time, and temperature every second.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-ds3231-rtc-micropython\/\n\nimport time\nimport urtc\nfrom machine import I2C, Pin\n\ndays_of_week = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']\n\n# Initialize RTC (connected to I2C)\ni2c = I2C(0, scl=Pin(5), sda=Pin(4))\nrtc = urtc.DS3231(i2c)\n\n# Set the current time using a specified time tuple\n# Time tuple: (year, month, day, day of week, hour, minute, seconds, milliseconds)\n#initial_time = (2024, 1, 30, 1, 12, 30, 0, 0)\n\n# Or get the local time from the system\ninitial_time_tuple = time.localtime()  # tuple (microPython)\ninitial_time_seconds = time.mktime(initial_time_tuple)  # local time in seconds\n\n# Convert to tuple compatible with the library\ninitial_time = urtc.seconds2tuple(initial_time_seconds)\n\n# Sync the RTC\nrtc.datetime(initial_time)\n\nwhile True:\n    current_datetime = rtc.datetime()\n    temperature = rtc.get_temperature()\n    \n    # Display time details\n    print('Current date and time:')\n    print('Year:', current_datetime.year)\n    print('Month:', current_datetime.month)\n    print('Day:', current_datetime.day)\n    print('Hour:', current_datetime.hour)\n    print('Minute:', current_datetime.minute)\n    print('Second:', current_datetime.second)\n    print('Day of the Week:', days_of_week[current_datetime.weekday])\n    print(f&quot;Current temperature: {temperature}\u00b0C&quot;)    \n    # Format the date and time\n    formatted_datetime = (\n        f&quot;{days_of_week[current_datetime.weekday]}, &quot;\n        f&quot;{current_datetime.year:04d}-{current_datetime.month:02d}-{current_datetime.day:02d} &quot;\n        f&quot;{current_datetime.hour:02d}:{current_datetime.minute:02d}:{current_datetime.second:02d} &quot;\n    )\n    print(f&quot;Current date and time: {formatted_datetime}&quot;)\n    \n    print(&quot; \\n&quot;);\n    time.sleep(1)\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/DS3231_Sync_Time.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How the Code Works<\/h3>\n\n\n\n<p>Let\u2019s take a quick look at the relevant parts of this code.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Import Libraries<\/h4>\n\n\n\n<p>First, you need to import the <span class=\"rnthl rntliteral\">urtc<\/span> module you\u2019ve uploaded previously that contains the functions to interact with the RTC. You also need to import the <span class=\"rnthl rntliteral\">Pin<\/span> and <span class=\"rnthl rntliteral\">I2C<\/span> classes to establish an I2C communication with the module.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>import time\nimport urtc\nfrom machine import I2C, Pin<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Initialize the RTC Module<\/h4>\n\n\n\n<p>Then, initialize I2C communication and create an object called <span class=\"rnthl rntliteral\">rtc<\/span> to refer to our DS3231 RTC module.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Initialize RTC (connected to I2C)\ni2c = I2C(0, scl=Pin(5), sda=Pin(4))\nrtc = urtc.DS3231(i2c)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Synchronize the Time<\/h4>\n\n\n\n<p>To synchronize the RTC time, you must use the <span class=\"rnthl rntliteral\">datetime()<\/span> method on the <span class=\"rnthl rntliteral\">rtc<\/span> object and pass as an argument a time tuple with the following format:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>(year, month, day, day of week, hour, minute, seconds, milliseconds)<\/code><\/pre>\n\n\n\n<p><strong>Note:<\/strong> this tuple is different from the one used by the MicroPython <span class=\"rnthl rntliteral\">time<\/span> module.<\/p>\n\n\n\n<p>We can set the time manually to a defined date and time as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>#initial_time = (2024, 1, 30, 1, 12, 30, 0, 0)<\/code><\/pre>\n\n\n\n<p>Or, we can synchronize the RTC with the system\u2019s local time. We&#8217;ll synchronize the time with the system&#8217;s local time.<\/p>\n\n\n\n<p>First, we get the time tuple of the local time using <span class=\"rnthl rntliteral\">time.localtime()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>initial_time_tuple = time.localtime()  # tuple (microPython)<\/code><\/pre>\n\n\n\n<p>The tuple returned is different from the one used by the <span class=\"rnthl rntliteral\">urtc<\/span> module.<\/p>\n\n\n\n<p>So, first, we convert it to seconds using <span class=\"rnthl rntliteral\">time.mktime()<\/span>.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>initial_time_seconds = time.mktime(initial_time_tuple)  # local time in seconds<\/code><\/pre>\n\n\n\n<p>And finally, we convert it to a tuple that is compatible with the library using the <span class=\"rnthl rntliteral\">seconds2tuple()<\/span> function from the <span class=\"rnthl rntliteral\">urtc<\/span> library that accepts as an argument the number of seconds since epoch for the local time.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>initial_time = urtc.seconds2tuple(initial_time_seconds)<\/code><\/pre>\n\n\n\n<p>Finally, we can pass our <span class=\"rnthl rntliteral\">initial_time<\/span> variable that contains the local time in a tuple compatible with the <span class=\"rnthl rntliteral\">urtc<\/span> module to the <span class=\"rnthl rntliteral\">datetime()<\/span> function as follows.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Convert to tuple compatible with the library\ninitial_time = urtc.seconds2tuple(initial_time_seconds)\n\n# Sync the RTC\nrtc.datetime(initial_time)<\/code><\/pre>\n\n\n\n<p class=\"rntbox rntclblue\"><strong>Note: <\/strong> After setting the time for the first time, we only need to set the time again if the RTC loses power (you should have a battery connected to prevent this). You can use the <span class=\"rnthl rntliteral\">lost_power()<\/span> function on the <span class=\"rnthl rntliteral\">rtc<\/span> object to check if it has lost power. This function returns <span class=\"rnthl rntliteral\">True<\/span> or <span class=\"rnthl rntliteral\">False<\/span> accordingly.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Getting the Time<\/h4>\n\n\n\n<p>After these lines of code, the RTC module is synchronized with your local time and you can simply call <span class=\"rnthl rntliteral\">rtc.datetime()<\/span> to get the current time from the RTC. This returns an object with all the time elements.<\/p>\n\n\n\n<p>To get and print each time element, we can do as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>current_datetime = rtc.datetime()\nprint('Current date and time:')\nprint('Year:', current_datetime.year)\nprint('Month:', current_datetime.month)\nprint('Day:', current_datetime.day)\nprint('Hour:', current_datetime.hour)\nprint('Minute:', current_datetime.minute)\nprint('Second:', current_datetime.second)\nprint('Day of the Week:', days_of_week&#091;current_datetime.weekday])<\/code><\/pre>\n\n\n\n<p>We can also get the current temperature from the module by calling the <span class=\"rnthl rntliteral\">get_temperature()<\/span> method on the <span class=\"rnthl rntliteral\">rtc<\/span> object.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>temperature = rtc.get_temperature()<\/code><\/pre>\n\n\n\n<p>The temperature data comes in Celsius degrees.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>print(f\"Current temperature: {temperature}\u00b0C\")<\/code><\/pre>\n\n\n\n<p>We print the time and current temperature every second.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>time.sleep(1)<\/code><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\">Run the Code<\/h3>\n\n\n\n<p>Run this previous code to synchronize the RTC time with the local time, and get the current time and temperature.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"114\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=470%2C114&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Run MicroPython script on Thonny IDE\" class=\"wp-image-144594\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?w=470&amp;quality=100&amp;strip=all&amp;ssl=1 470w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=300%2C73&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 470px) 100vw, 470px\" \/><\/figure><\/div>\n\n\n<p>From now on, if the RTC has an attached battery, it will keep the time synchronized with your local time. So, you don\u2019t need to synchronize it anymore, and you can just call <span class=\"rnthl rntliteral\">rtc.datetime()<\/span> to get the current time.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"352\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-Get-Time-Testing.png?resize=800%2C352&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico with DS3231 with MicroPython Get Date, Time, and Temperature\" class=\"wp-image-165178\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-Get-Time-Testing.png?w=800&amp;quality=100&amp;strip=all&amp;ssl=1 800w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-Get-Time-Testing.png?resize=300%2C132&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-Get-Time-Testing.png?resize=768%2C338&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\" id=\"set-alarms\">DS3231 with the Raspberry Pi Pico &#8211; Setting Alarms<\/h2>\n\n\n\n<p>The DS3231 RTC Module allows you to set up to two alarms: alarm 1 and alarm 2. When the time reaches the alarm time, the module changes the state of the SQW pin from HIGH to LOW (it is active low). We can check for the change on that pin and perform a certain task when the alarm fires.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"750\" height=\"422\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Settings-Alarms.jpg?resize=750%2C422&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico DS3231 - Setting Alarms\" class=\"wp-image-165184\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Settings-Alarms.jpg?w=750&amp;quality=100&amp;strip=all&amp;ssl=1 750w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Settings-Alarms.jpg?resize=300%2C169&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/figure><\/div>\n\n\n<p>Important notes about the alarms:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>the RTC allows you to save up to two alarms;<\/li>\n\n\n\n<li>you can only have one alarm active at a time;<\/li>\n\n\n\n<li>after an alarm is triggered, you must clear its flag to avoid triggering and crashing the Pico;<\/li>\n\n\n\n<li>you must deactivate an alarm before activating the other.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">DS3231 &#8211; Setting Up the Alarms<\/h3>\n\n\n\n<p>The following example shows how to set up two alarms. It toggles an LED when the alarm fires. To test this example, add an LED with a 220 Ohm resistor to the circuit. Connect the LED to GPIO 2.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-ds3231-rtc-micropython\/\n\nimport time\nimport urtc\nfrom machine import Pin, I2C\n\n# Pin setup for SQW pin and LED\nCLOCK_INTERRUPT_PIN = 3  # Adjust to your specific GPIO pin for SQW\nLED_PIN = 2  # Adjust to your specific GPIO pin for the LED\n\n# Initialize RTC (connected to I2C)\ni2c = I2C(0, scl=Pin(5), sda=Pin(4))\nrtc = urtc.DS3231(i2c)\n\n# Setup GPIO for SQW and LED\nsqw_pin = Pin(CLOCK_INTERRUPT_PIN, Pin.IN, Pin.PULL_UP)\nled_pin = Pin(LED_PIN, Pin.OUT)\nled_pin.off()\n\n# Alarm times (year, month, day, weekday, hour, minute, second, millisecond)\nalarm1_time = urtc.datetime_tuple(2025, 01, 04, None, 12, 32, 00, 0)  # Alarm 1 uses full datetime\nalarm2_time = urtc.datetime_tuple(2025, 01, 04, None, 12, 35, 00, 0)   # Alarm 2 uses day, hour, minute, weekday\n\n# Print the current time from the RTC\ndef print_current_time():\n    now = rtc.datetime()\n    formatted_time = f&quot;{now.year}-{now.month:02}-{now.day:02} {now.hour:02}:{now.minute:02}:{now.second:02}&quot;\n    print(f&quot;Current time: {formatted_time}&quot;)\n\n\n#Callback for handling alarm interrupt.\ndef on_alarm(pin):\n    print(&quot;Interrupt detected.&quot;)\n    \n    if rtc.alarm(alarm=0):  # Check if Alarm 1 triggered\n        print(&quot;Alarm 1 triggered.&quot;)\n        rtc.alarm(False, alarm=0)  # Clear Alarm 1 flag\n        led_pin.value(not led_pin.value())  # Toggle LED for Alarm 1\n    \n    if rtc.alarm(alarm=1):  # Check if Alarm 2 triggered\n        print(&quot;Alarm 2 triggered.&quot;)\n        rtc.alarm(False, alarm=1)  # Clear Alarm 2 flag\n        led_pin.value(not led_pin.value())  # Toggle LED for Alarm 2\n\n# Setup alarms on the DS3231\ndef setup_alarms():\n    # Clear any existing alarms\n    rtc.alarm(False, 0)\n    rtc.alarm(False, 1)\n    rtc.no_interrupt()\n\n    # Set the desired alarm times\n    rtc.alarm_time(alarm1_time, 0)  # Alarm 1\n    rtc.alarm_time(alarm2_time, 1)  # Alarm 2\n\n    # Enable interrupts for the alarms\n    rtc.interrupt(0)\n    rtc.interrupt(1)\n    print(&quot;Alarms set successfully.&quot;)\n\n\n# Attach the interrupt callback\nsqw_pin.irq(trigger=Pin.IRQ_FALLING, handler=on_alarm)\n\ntry:\n    # Sync time to compile time if RTC lost power\n    if rtc.lost_power():\n        initial_time_tuple = time.localtime()  # tuple (MicroPython)\n        initial_time_seconds = time.mktime(initial_time_tuple)  # local time in seconds\n        initial_time = urtc.seconds2tuple(initial_time_seconds)  # Convert to tuple compatible with the library\n        rtc.datetime(initial_time)  # Sync the RTC\n\n    print(&quot;RTC initialized. Setting alarms...&quot;)\n    setup_alarms()\n\n    while True:\n        print_current_time()\n        time.sleep(5)\nexcept KeyboardInterrupt:\n    print(&quot;Exiting program.&quot;)\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/DS3231_Set_Alarms.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How Does the Code Work?<\/h3>\n\n\n\n<p>Let&#8217;s take a look at the relevant parts of code to set up the alarms.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Defining the Pins<\/h4>\n\n\n\n<p>First, you need to define the GPIO that is connected to the SQW pin. This is the pin that will change state when the alarms fire. We chose to connect it to GPIO 3, but you can choose any other pins as long as the circuit connections match.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>CLOCK_INTERRUPT_PIN = 3  # Adjust to your specific GPIO pin for SQW<\/code><\/pre>\n\n\n\n<p>We set the SQW pin as an input with an internal pull-up resistor (because it is an active-low pin).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>sqw_pin = Pin(CLOCK_INTERRUPT_PIN, Pin.IN, Pin.PULL_UP)<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Alarm Times<\/h4>\n\n\n\n<p>Then, we create two variables of type <span class=\"rnthl rntliteral\">datetime_tuple<\/span> to save the alarm times in variables as follows:<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Alarm times (year, month, day, weekday, hour, minute, second, millisecond)\nalarm1_time = urtc.datetime_tuple(2025, 01, 04, None, 12, 32, 00, 0)  # Alarm 1 uses full datetime\nalarm2_time = urtc.datetime_tuple(2025, 01, 04, None, 12, 35, 00, 0)   # Alarm 2 uses day, hour, minute, weekday<\/code><\/pre>\n\n\n\n<p>Adjust the alarms to your desired times.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Setting the SQW Pin as an Interrupt<\/h4>\n\n\n\n<p>Then, we set the SQW pin as an interrupt by calling the <span class=\"rnthl rntliteral\">irq()<\/span> method. <\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>sqw_pin.irq(trigger=Pin.IRQ_FALLING, handler=on_alarm)<\/code><\/pre>\n\n\n\n<p>The&nbsp;<span class=\"rnthl rntliteral\">irq()<\/span>&nbsp;method accepts the following arguments:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>handler:<\/strong>&nbsp;this is a function that will be called when an interrupt is detected, in this case the&nbsp;<span class=\"rnthl rntliteral\">on_alarm()<\/span>&nbsp;function.<\/li>\n\n\n\n<li><strong>trigger:<\/strong>&nbsp;this defines the trigger mode. There are 3 different conditions. In our case, we&#8217;ll use <span class=\"rnthl rntliteral\">IRQ_FALLING<\/span> to trigger the interrupt whenever the pin goes from HIGH to LOW.<\/li>\n<\/ul>\n\n\n\n<div id=\"rntbox-rntclgreen\" class=\"wp-block-group is-vertical is-layout-flex wp-container-core-group-is-layout-8cf370e7 wp-block-group-is-layout-flex\">\n<p>To learn more about setting interrupts with the Raspberry Pi Pico using MicroPython, check the following tutorial:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-motion-pir-micropython\/\">Raspberry Pi Pico: Detect Motion using a PIR Sensor (MicroPython)<\/a><\/li>\n<\/ul>\n<\/div>\n\n\n\n<h4 class=\"wp-block-heading\">on_alarm Function<\/h4>\n\n\n\n<p>The <span class=\"rnthl rntliteral\">on_alarm<\/span> function checks which alarm was triggered and deactivates that alarm to clear its flag. This function will be called when an alarm fires.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def on_alarm(pin):<\/code><\/pre>\n\n\n\n<p>The following line checks if alarm1 was triggered. This allows us to deactivate right after it&#8217;s triggered and also run a specific task at a determined time.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>if rtc.alarm(alarm=0):  # Check if Alarm 1 triggered\n    print(\"Alarm 1 triggered.\")\n    rtc.alarm(False, alarm=0)  # Clear Alarm 1 flag\n    led_pin.value(not led_pin.value())  # Toggle LED for Alarm 1<\/code><\/pre>\n\n\n\n<p>This line clears the alarm1 flag (to reset it to its initial state).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>rtc.alarm(False, alarm=0)  # Clear Alarm 1 flag<\/code><\/pre>\n\n\n\n<p>Then, we toggle the state of the LED.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>led_pin.value(not led_pin.value())  # Toggle LED for Alarm 1<\/code><\/pre>\n\n\n\n<p>We act similarly for the alarm2.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>if rtc.alarm(alarm=1):  # Check if Alarm 2 triggered\n    print(\"Alarm 2 triggered.\")\n    rtc.alarm(False, alarm=1)  # Clear Alarm 2 flag\n    led_pin.value(not led_pin.value())  # Toggle LED for Alarm 2<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Setting Up the Alarms<\/h4>\n\n\n\n<p>We create a function called <span class=\"rnthl rntliteral\">setup_alarms()<\/span> to set up the alarms.<\/p>\n\n\n\n<p>To set up the alarms, first we must clear any previous existing alarms as follows.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>def setup_alarms():\n    # Clear any existing alarms\n    rtc.alarm(False, 0)\n    rtc.alarm(False, 1)\n    rtc.no_interrupt()<\/code><\/pre>\n\n\n\n<p>Then, we can set the alarm times by calling the <span class=\"rnthl rntliteral\">alarm_time()<\/span> method on the <span class=\"rnthl rntliteral\">rtc<\/span> object. Pass as arguments the alarm time (a <span class=\"rnthl rntliteral\">datetime_tuple<\/span> type variable), and the alarm number (<span class=\"rnthl rntliteral\">0<\/span>=alarm1; <span class=\"rnthl rntliteral\">1<\/span>=alarm2).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Set the desired alarm times\nrtc.alarm_time(alarm1_time, 0)  # Alarm 1\nrtc.alarm_time(alarm2_time, 1)  # Alarm 2<\/code><\/pre>\n\n\n\n<p>We enable the interrupt for the alarms, so that the SQW pin is triggered when an alarm fires.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>rtc.interrupt(0)\nrtc.interrupt(1)<\/code><\/pre>\n\n\n\n<p>Then we have a <span class=\"rnthl rntliteral\">try<\/span> statement that will adjust the time of the RTC if needed (if it has lost power), and set up the alarms.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>try:\n    # Sync time to compile time if RTC lost power\n    if rtc.lost_power():\n        initial_time_tuple = time.localtime()  # tuple (MicroPython)\n        initial_time_seconds = time.mktime(initial_time_tuple)  # local time in seconds\n        initial_time = urtc.seconds2tuple(initial_time_seconds)  # Convert to tuple compatible with the library\n        rtc.datetime(initial_time)  # Sync the RTC\n\n    print(\"RTC initialized. Setting alarms...\")\n    setup_alarms()<\/code><\/pre>\n\n\n\n<p>Then, we&#8217;ll constantly print the current time every five seconds.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>while True:\n    print_current_time()\n    time.sleep(5)<\/code><\/pre>\n\n\n\n<p>Detecting the alarms is done in the background because we&#8217;ve set up an interrupt on the SQW pin.<\/p>\n\n\n\n<h4 class=\"wp-block-heading\">Testing the Alarms<\/h4>\n\n\n\n<p>Set the alarms to a close-up time so that you can see them in action. Then, run the code.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"114\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=470%2C114&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Run MicrppPython script Thonny IDE\" class=\"wp-image-144594\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?w=470&amp;quality=100&amp;strip=all&amp;ssl=1 470w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=300%2C73&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 470px) 100vw, 470px\" \/><\/figure><\/div>\n\n\n<p>The current time will be printed into the shell every five seconds. When the alarm fires, you&#8217;ll get a message on the shell and the LED will toggle.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"776\" height=\"357\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-alarms.png?resize=776%2C357&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"DS3231 RTC with the Raspberry Pi Pico MicroPython - Triggering Alarms\" class=\"wp-image-165179\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-alarms.png?w=776&amp;quality=100&amp;strip=all&amp;ssl=1 776w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-alarms.png?resize=300%2C138&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-set-alarms.png?resize=768%2C353&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 776px) 100vw, 776px\" \/><\/figure><\/div>\n\n\n<h3 class=\"wp-block-heading\" id=\"periodic-alarms\">DS3231 &#8211; Setting Up Periodic Alarms<\/h3>\n\n\n\n<p>To set up periodic alarms we can adjust the alarm time every time an alarm is triggered. For example, imagine you want to trigger an alarm every 10 minutes. To do that:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>read the current time when the alarm is triggered;<\/li>\n\n\n\n<li>set up a new alarm by adding 600 seconds (10 minutes) to the current time;<\/li>\n\n\n\n<li>after 10 minutes the alarm will be triggered;<\/li>\n\n\n\n<li>repeat the previous steps.<\/li>\n<\/ul>\n\n\n\n<p>That&#8217;s exactly what we&#8217;ll implement in the following example.<\/p>\n\n\n<pre style=\"max-height: 40em; margin-bottom: 20px;\"><code class=\"language-python\"># Rui Santos &amp; Sara Santos - Random Nerd Tutorials\n# Complete project details at https:\/\/RandomNerdTutorials.com\/raspberry-pi-pico-ds3231-rtc-micropython\/\n\nfrom machine import Pin, I2C\nimport time\nimport urtc\n\n# Pin setup for SQW pin and LED\nCLOCK_INTERRUPT_PIN = 3  # Adjust to your specific GPIO pin for SQW\nLED_PIN = 2  # Adjust to your specific GPIO pin for the LED\n\n# Initialize RTC (connected to I2C)\ni2c = I2C(0, scl=Pin(5), sda=Pin(4))\nrtc = urtc.DS3231(i2c)\n\n# Setup GPIO for SQW and LED\nsqw_pin = Pin(CLOCK_INTERRUPT_PIN, Pin.IN, Pin.PULL_UP)\nled_pin = Pin(LED_PIN, Pin.OUT)\nled_pin.off()\n\n# Add minutes to a datetime tuple and return a new datetime tuple\ndef add_minutes_to_time(dt, minutes):\n    timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, 0, 0))\n    new_timestamp = timestamp + (minutes * 60)\n    new_time = time.localtime(new_timestamp)\n    return urtc.datetime_tuple(new_time[0], new_time[1], new_time[2], None, new_time[3], new_time[4], new_time[5], 0)\n\n# Print the current time from the RTC\ndef print_current_time():\n    now = rtc.datetime()\n    formatted_time = f&quot;{now.year}-{now.month:02}-{now.day:02} {now.hour:02}:{now.minute:02}:{now.second:02}&quot;\n    print(f&quot;Current time: {formatted_time}&quot;)\n\n# Callback for handling alarm interrupt\ndef on_alarm(pin):\n    print(&quot;Alarm triggered! Toggling the LED.&quot;)\n    led_pin.value(not led_pin.value())  # Toggle the LED\n\n    # Clear the alarm flag and schedule the next alarm\n    if rtc.alarm(alarm=0):  # Check if Alarm 0 triggered\n        print(&quot;Clearing Alarm 0 flag.&quot;)\n        rtc.alarm(False, alarm=0)  # Clear alarm flag\n\n        # Schedule the alarm to repeat 10 minutes from now\n        now = rtc.datetime()\n        next_alarm_time = add_minutes_to_time(now, 10)  # Add 10 minutes\n        rtc.alarm_time(next_alarm_time, alarm=0)  # Set new alarm\n        rtc.interrupt(0)  # Ensure Alarm 0 interrupt is enabled\n        print(f&quot;Next alarm set for: {next_alarm_time}&quot;)\n\n\ndef setup_alarm():\n    # Clear any existing alarms\n    rtc.alarm(False, 0)\n    rtc.no_interrupt()\n\n    # Get the current time and set the first alarm 1 minute from now\n    now = rtc.datetime()\n    first_alarm_time = add_minutes_to_time(now, 1)  # Set first alarm for 1 minute from now\n    rtc.alarm_time(first_alarm_time, alarm=0)  # Alarm 0\n\n    # Enable the interrupt for Alarm 0\n    rtc.interrupt(0)\n\n    print(f&quot;Alarm set for: {first_alarm_time}&quot;)\n\n# Attach the interrupt callback\nsqw_pin.irq(trigger=Pin.IRQ_FALLING, handler=on_alarm)\n\ntry:\n    # Sync time to compile time if RTC lost power\n    if rtc.lost_power():\n        initial_time_tuple = time.localtime()  # tuple (MicroPython)\n        initial_time_seconds = time.mktime(initial_time_tuple)  # local time in seconds\n        initial_time = urtc.seconds2tuple(initial_time_seconds)  # Convert to tuple compatible with the library\n        rtc.datetime(initial_time)  # Sync the RTC\n\n    print(&quot;RTC initialized. Setting up the periodic alarm...&quot;)\n    setup_alarm()\n\n    while True:\n        print_current_time()\n        time.sleep(5)\nexcept KeyboardInterrupt:\n    print(&quot;Exiting program.&quot;)\n<\/code><\/pre>\n\t<p style=\"text-align:center\"><a class=\"rntwhite\" href=\"https:\/\/github.com\/RuiSantosdotme\/Random-Nerd-Tutorials\/raw\/master\/Projects\/Raspberry-Pi-Pico\/MicroPython\/DS3231_Set_Periodic_Alarms.py\" target=\"_blank\">View raw code<\/a><\/p>\n\n\n\n<p>In this example, we create a function called <span class=\"rnthl rntliteral\">add_minutes_to_time()<\/span> that will add minutes to the current time.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Add minutes to a datetime tuple and return a new datetime tuple\ndef add_minutes_to_time(dt, minutes):\n    timestamp = time.mktime((dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second, 0, 0))\n    new_timestamp = timestamp + (minutes * 60)\n    new_time = time.localtime(new_timestamp)\n    return urtc.datetime_tuple(new_time&#091;0], new_time&#091;1], new_time&#091;2], None, new_time&#091;3], new_time&#091;4], new_time&#091;5], 0)<\/code><\/pre>\n\n\n\n<p>This function accepts as arguments a <span class=\"rnthl rntliteral\">datetime<\/span> tupple (like the current time) and the minutes you want to add to the current time to set up a new alarm in the future. This function returns a new <span class=\"rnthl rntliteral\">datetime<\/span> tuple with the new alarm time.<\/p>\n\n\n\n<p>When an alarm is triggered, the <span class=\"rnthl rntliteral\">on_alarm()<\/span> function will run. It will first toggle the state of the onboard LED.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Callback for handling alarm interrupt\ndef on_alarm(pin):\n    print(\"Alarm triggered! Toggling the LED.\")\n    led_pin.value(not led_pin.value())  # Toggle the LED<\/code><\/pre>\n\n\n\n<p>Then, it will deactivate (clear the flag for alarm1).<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>if rtc.alarm(alarm=0):  # Check if Alarm 0 triggered\n    print(\"Clearing Alarm 0 flag.\")\n    rtc.alarm(False, alarm=0)  # Clear alarm flag<\/code><\/pre>\n\n\n\n<p>After that, it will set up a new alarm time by adding a predefined number of minutes to the current time. In this example, we&#8217;re setting up an alarm every 10 minutes<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code># Schedule the alarm to repeat 10 minutes from now\nnow = rtc.datetime()\nnext_alarm_time = add_minutes_to_time(now, 10)  # Add 10 minutes\nrtc.alarm_time(next_alarm_time, alarm=0)  # Set new alarm\nrtc.interrupt(0)  # Ensure Alarm 0 interrupt is enabled\nprint(f\"Next alarm set for: {next_alarm_time}\")<\/code><\/pre>\n\n\n\n<p>You can easily change this by adjusting to your desired time on the following line.<\/p>\n\n\n\n<pre class=\"wp-block-code language-python\"><code>next_alarm_time = add_minutes_to_time(now, 10)  # Add 10 minutes<\/code><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\">Testing the Periodic Alarms<\/h4>\n\n\n\n<p>Set the alarms to a close-up time so that you can see them in action. Then, run the code.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"470\" height=\"114\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=470%2C114&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Run MicroPython script on Thonny IDE\" class=\"wp-image-144594\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?w=470&amp;quality=100&amp;strip=all&amp;ssl=1 470w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2023\/12\/thonny-ide-run-button.png?resize=300%2C73&amp;quality=100&amp;strip=all&amp;ssl=1 300w\" sizes=\"(max-width: 470px) 100vw, 470px\" \/><\/figure><\/div>\n\n\n<p>The first alarm will trigger after one minute. The following alarms will trigger every 10 minutes. When an alarm is triggered, we also toggle the state of the LED.<\/p>\n\n\n<div class=\"wp-block-image\">\n<figure class=\"aligncenter size-full\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"869\" height=\"353\" src=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Periodic-Alarms.png?resize=869%2C353&#038;quality=100&#038;strip=all&#038;ssl=1\" alt=\"Raspberry Pi Pico with DS3231 - Setting periodic alarms\" class=\"wp-image-165180\" srcset=\"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Periodic-Alarms.png?w=869&amp;quality=100&amp;strip=all&amp;ssl=1 869w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Periodic-Alarms.png?resize=300%2C122&amp;quality=100&amp;strip=all&amp;ssl=1 300w, https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/RPi-Pico-DS3231-Periodic-Alarms.png?resize=768%2C312&amp;quality=100&amp;strip=all&amp;ssl=1 768w\" sizes=\"(max-width: 869px) 100vw, 869px\" \/><\/figure><\/div>\n\n\n<h2 class=\"wp-block-heading\">Wrapping Up<\/h2>\n\n\n\n<p>In this tutorial, you learned how use the DS3231 Real-Time Clock module with the Raspberry Pi Pico programmed with MicroPython to get the current date and time and set up alarms. This module can be very useful in data logging projects, automation, periodic tasks and many other applications.<\/p>\n\n\n\n<p>We hope you found this quick guide useful. We have guides for other sensors and modules that you may find useful:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-bme680-micropython\/\">Raspberry Pi Pico: BME680 Environmental Sensor (MicroPython)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-bh1750-micropython\/\">Raspberry Pi Pico: BH1750 Ambient Light Sensor (MicroPython)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-bme280-micropython\/\">Raspberry Pi Pico: BME280 Get Temperature, Humidity, and Pressure (MicroPython)<\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-anemometer-micropython\/\" title=\"\">Raspberry Pi Pico with Anemometer: Measure Wind Speed (MicroPython)<\/a><\/li>\n<\/ul>\n\n\n\n<p>Learn more about the Raspberry Pi Pico with our resources:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><a href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-w-micropython-ebook\/\"><strong>Learn Raspberry Pi Pico\/Pico W with MicroPython (eBook)<\/strong><\/a><\/li>\n\n\n\n<li><a href=\"https:\/\/randomnerdtutorials.com\/projects-raspberry-pi-pico\/\">Free Raspberry Pi Pico projects and tutorials<\/a><\/li>\n<\/ul>\n\n\n\n<p>Thanks for reading.<\/p>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This is a getting started guide that shows how to interface the DS3231 Real Time Clock Module with the Raspberry Pi Pico board programmed with MicroPython: learn how to set &#8230; <\/p>\n<p class=\"read-more-container\"><a title=\"Raspberry Pi Pico: DS3231 RTC (Real-Time Clock) &#8211; Get Time and Set Alarms (MicroPython)\" class=\"read-more button\" href=\"https:\/\/randomnerdtutorials.com\/raspberry-pi-pico-ds3231-rtc-micropython\/#more-165176\" aria-label=\"Read more about Raspberry Pi Pico: DS3231 RTC (Real-Time Clock) &#8211; Get Time and Set Alarms (MicroPython)\">CONTINUE READING \u00bb<\/a><\/p>\n","protected":false},"author":5,"featured_media":165188,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[324,326],"tags":[],"class_list":["post-165176","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-raspberry-pi-pico","category-raspberry-pi-pico-micropython"],"aioseo_notices":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/randomnerdtutorials.com\/wp-content\/uploads\/2025\/01\/Raspberry-Pi-Pico-DS3231-Micropython.jpg?fit=1920%2C1080&quality=100&strip=all&ssl=1","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/165176","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/comments?post=165176"}],"version-history":[{"count":5,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/165176\/revisions"}],"predecessor-version":[{"id":167524,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/posts\/165176\/revisions\/167524"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media\/165188"}],"wp:attachment":[{"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/media?parent=165176"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/categories?post=165176"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/randomnerdtutorials.com\/wp-json\/wp\/v2\/tags?post=165176"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}