Sleep Well and Wake Up On-time!

A project log for Terminal-BASIC programmable calculator

A poket-to-laptop size microcomputer/programmable calculator, based on Terminal-BASIC

ptravptrav 12/02/2020 at 05:480 Comments

Last two weeks I spent on hardware development. According to the requirements, the calculator should be able to keep precise time in DS3231 Real-Time Clock (RTC) and wake up from deep sleep at the predefined moment. The final schematics looks as following:

The wake-up signal is taken from the DS3231 SQW pin and send into a NOT element of 4069. The DS3231 is obtained in form of ZS042 breakout board - it is easier than soldering a surface mounted chip with many pins. The modifications on the ZS042:

(1) Mandatory - cut the top right leg of 4.7k 4-resistor assembly 1 - without it, the DS3231 will be able to keep the line up if VCC is off. Note that pin 3 (INT/SQW) is simply a MOSFET to GND - essentially an equivalent of a momentary switch to ground.

(2) Mandatory - remove 200 Ohm resistor in the battery charging circuit. Because the board is powered by VCC=3.3V, it is useless anyway, but may be a battery hazard if using with 5V supply.

(3) Optional - remove 1k resistor in the power LED (this reduces power consumption from 1.9 to 0.3-0.5 mA).

The chip programming magic is done earlier by Mike Yakimov - the author of - and available at

#include <Arduino.h>
#include <Wire.h>
#include "RTCData.hpp"

//I2C Slave Address  
#define DS3231_SLAVE_ADDRESS  0x68

// Default control - battery oscillator ON and Alarm 1 DISABLED
#define DS3231_CONTROL_DEF    0x04

// Default control - battery oscillator ON and Alarm 1 ENABLED
#define DS3231_CONTROL_ALR    0x05

// Default status - all clear
#define DS3231_STATUS_DEF    0x00

class DS3231_Controller{
    bool firstRun = true;
    uint8_t lastError = 0;
    uint8_t wakeupStatus = 0;

    void begin();
    bool isRunning();
    void setDateTime( DS3231_DateTime datetime);
    DS3231_DateTime getDateTime();
    DS3231_Temperature getTemperature();
    void setWakeUp(DS3231_Alarm alr);
    DS3231_Alarm getWakeUp();

    uint8_t _getRegister(uint8_t address, uint8_t n=1, uint8_t *data=NULL);
    uint8_t _setRegister(uint8_t address, uint8_t n, uint8_t *data=NULL);