Use a DS3231 RTC to wakeup an Arduino
Reading time2 Minutes
Rocket Scream Electronics published a very cool low power library for Arduino1 which really helps if you need to save some power on your Arduino and and to power it down2.
One limitation of the AVR hardware used on your Arduino is the rather small time you can put it to sleep without external hardware: max 8 seconds. If you want to disable the device for a longer period, you can either build a loop which triggers multiple 8 seconds sleeps or use an external interrupt to wakeup.
There are multiple RTC (real-time clock) devices available on breakout boards, many also support the required alarms. I bought a DS32313 which is a real low-cost alternative (~6 Euro including a coin battery).
The RTC requires either 3.3V or 5V and uses I2C to communicate with the Arduino. The SQW pin needs to be attached to one of the interrupt pins of your Arduino (e.g. for a Nano it’s D2 or D3).
You can find a sketch I uploaded to github which shows, how to set the clock and configure an alarm which then wakes up the Arduino4. As soon as the Arduino wakes up again, it begins to flash the LED.
Depending on your requirements, you can set one of the alarms to either match:
- seconds (e.g. XX:YY:30)
- minutes and seconds (e.g. XX:15:00
- hours, minutes and seconds (e.g. 13:37:00)
Although the DS3231 has two alarms you can set, only A1 supports seconds, A2 always matches to seconds = 00.
The configuration, which parts of the time need to match is done using a bitmask which needs to be combined for both alarms:
#define ALRM1_MATCH_EVERY_SEC 0b1111 // once a second #define ALRM1_MATCH_SEC 0b1110 // when seconds match #define ALRM1_MATCH_MIN_SEC 0b1100 // when minutes and seconds match #define ALRM1_MATCH_HR_MIN_SEC 0b1000 // when hours, minutes, and seconds match #define ALRM2_ONCE_PER_MIN 0b111 // once per minute (00 seconds of every minute) #define ALRM2_MATCH_MIN 0b110 // when minutes match #define ALRM2_MATCH_HR_MIN 0b100 // when hours and minutes match int ALARM_BITS = ALRM2_MATCH_MIN; ALARM_BITS <<= 4; ALARM_BITS |= ALRM1_MATCH_MIN_SEC;