Resetting RTC flag

  • I cannot get the RTC flag on my M5paper to work correctly. Using the example RTC_WakeUp the screen always reads "Power on by: RTC timer" however the device was started. Even if I press the reset button first and then the on button, the screen still says "Power on by: RTC timer". I seems the if ((data & 0b00000100) == 0b00000100) statement is always true. How can I reset it?

    #include <M5EPD.h>
    M5EPD_Canvas canvas(&M5.EPD);
    void setup() {
      //  Check power on reason before calling M5.begin()
      //  which calls RTC.begin() which clears the timer flag.
      Wire.begin(21, 22);                  
      uint8_t data = M5.RTC.readReg(0x01);     
      bool flagRTC = false;
      // Check timer flag
      if ((data & 0b00000100) == 0b00000100) {
        flagRTC = true;
        Serial.println("Power on by: RTC timer");
      else {
        Serial.println("Power on by: PWR Btn");
      canvas.createCanvas(540, 960);  
      if (flagRTC)
        canvas.drawString("Power on by: RTC timer", 25, 250); // <= this one we should when waking up from sleep
        canvas.drawString("Power on by: PWR Btn", 25, 250);
      canvas.drawString("Press PWR Btn for sleep!", 45, 350);
      canvas.drawString("after 5 sec wakeup!", 70, 450);
      canvas.pushCanvas(0, 0, UPDATE_MODE_DU4);
    void loop() {
      if (M5.BtnP.wasPressed()) {    
        canvas.drawString("I'm going to sleep.zzzZZZ~", 45, 550);
        canvas.pushCanvas(0, 0, UPDATE_MODE_DU4);
        M5.shutdown(5); // shut donw now and wake up after 5 seconds

  • Hello @Steve1

    try to check the timer interrupt enable bit as well, like this:

    if ((data & 0b00000101) == 0b00000101) 


  • I don't think this is a reliable way of checking whether the boot was caused by the RTC or the some other reason. From the BM8563 datasheet (my highlighting): Interrupt output
    Bits TF and AF: When an alarm occurs, AF is set to logic 1. Similarly, at the end of a
    timer countdown, TF is set to logic 1. These bits maintain their value until overwritten
    using the interface.
    If both timer and alarm interrupts are required in the application, the
    source of the interrupt can be determined by reading these bits. To prevent one flag being
    overwritten while clearing another, a logic AND is performed during a write access.

  • Hello @Cognitive5525

    they are overwritten (and cleared) by calling M5.RTC.begin();.


  • Thanks for the insights folks. However I am still confused as to how have an RTC restart do one thing and a power button restart do another.

    My practical goal is to have the M5Paper go online and retrieve the NTP time data on a button power on but, in order to save battery charge to simply use the RTC for time data on an RTC restart.

  • Hello @Steve1

    well, there is an alternative method you could use. The power button also acts as regular button. So you could check if the power button was still pressed when M5Paper starts running. Something like this at the beginning of setup():

      M5.begin(true, false, true, true, true);
      bool pwrBtnStart = M5.BtnP.isPressed(); // true if started by PWR button

    Note: for it to work you'll need to press and hold the power button long enough for the code to reach the statement checking the button. In my tests I need to hold the power button for about 5 seconds.

    Note: a disadvantage of the power button check method is that when M5Paper is powered on by USB it thinks it was an RTC start.