🤖Have you ever tried Chat.M5Stack.com before asking??😎
    M5Stack Community
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Register
    • Login

    M5Paper wakeup cause

    Cores
    6
    13
    20.9k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • G
      grundprinzip @dov
      last edited by

      @dov I'm very new to the M5Paper, but I'm wondering if you couldn't use the esp_deep_sleep_start() instead of shutdown because this will keep the RTC going and shutdown everything else.

      In theory, you might be able to call esp_err_tesp_sleep_enable_timer_wakeup() with an appropriate duration and then simply continue. According to the documentation the Wifi connection data is kept as well.

      I'm currently trying to work on something like this as well.

      1 Reply Last reply Reply Quote 0
      • JopJ
        Jop @felmue
        last edited by

        Hi @felmue,

        Interesting post you wrote - nice solution to detect reason for awakening the M5Paper. But unfortunately the code you gave for M5Corelink doesn't compile on a M5Paper.

        I did some trial and error modifications and within 5 minutes I got code that does compile.
        Here just the relevant code in setup() - sketch from an example in the M5EPD library:

        #include <M5EPD.h>
        
        // is not yet working as should be
        
        M5EPD_Canvas canvas(&M5.EPD);
        
        void setup() {
          // Check power on reason before calling M5.begin()
          //  which calls Rtc.begin() which clears the timer flag.
          Wire1.begin(21, 22);                  // Jop: compiles
        //uint8_t data = M5.rtc.ReadReg(0x01);  // Jop: compiles NOT
          uint8_t data = M5.RTC.readReg(0x01);  // Jop: compiles   
           
          M5.begin();
        
          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");
          }
             
          M5.EPD.SetRotation(90);
          M5.TP.SetRotation(90);
          M5.EPD.Clear(true);
          M5.RTC.begin();
          
          canvas.createCanvas(540, 960);  
          canvas.setTextSize(3);
          if (flagRTC)
            canvas.drawString("Power on by: RTC timer", 25, 250); // <= this one we see always
          else  
            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);
            delay(1000);
            M5.shutdown(5);
          }
          M5.update();
          delay(100);
        }
        

        As you see I had to change just some capital-mode in identifiers to get it compiled.
        But apparently not the right register or bits are used for detecting wakeup cause.

        Maybe someone else is triggered by this to find the full solution for the M5Paper.

        Kind regards,

        Jop
        
        1 Reply Last reply Reply Quote 1
        • felmueF
          felmue
          last edited by

          Hello @Jop

          thank you for trying it on an M5Paper.

          Try to change Wire1.begin(21, 22) to Wire.begin(21, 22). M5Paper unlike M5CoreInk uses Wire for its internal I2C. And having Wire and Wire1 setup to use the same set of GPIOs makes M5.RTC.begin() fail and thus the timer flag never gets cleared.

          Cheers
          Felix

          GPIO translation table M5Stack / M5Core2
          Information about various M5Stack products.
          Code examples

          JopJ 1 Reply Last reply Reply Quote 0
          • JopJ
            Jop @felmue
            last edited by

            @felmue
            Hi Felix,

            Good tip. It works.

            Here the update code based on an example from the M5EPD library:

            #include <M5EPD.h>
            
            // m5paper-wakeup-cause
            // see forum: https://community.m5stack.com/topic/2851/m5paper-wakeup-cause/6
            
            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);     
               
              M5.begin();
            
              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");
              }
                 
              M5.EPD.SetRotation(90);
              M5.TP.SetRotation(90);
              M5.EPD.Clear(true);
              M5.RTC.begin();
              
              canvas.createCanvas(540, 960);  
              canvas.setTextSize(3);
              if (flagRTC)
                canvas.drawString("Power on by: RTC timer", 25, 250); // <= this one we should when waking up from sleep
              else  
                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);
                delay(1000);
                M5.shutdown(5); // shut donw now and wake up after 5 seconds
              }
              M5.update();
              delay(100);
            }
            

            One extra remark (maybe for a new topic): the shutdown() routine has some overloaded variations. Unfortunately not very well documented, as the version with only time (see: int shutdown( const rtc_time_t &RTC_TimeStruct); ) seems not to work as expected. If add the date too (last overloaded version) it works. Maybe my expectations are wrong. Sometimes one should like a bit more specifications from M5Stack in this documentation (is a timesaver).

            Anyway thnx for your suggestion Wire1 => Wire.

            Kind regards,

            Jop
            
            1 Reply Last reply Reply Quote 0
            • felmueF
              felmue
              last edited by

              Hello @Jop

              thanks for reporting back. I am happy to hear you got it working to your liking.

              Re shutdown: that has been fixed in a pull-request, but unfortunately M5Stack engineers are very slow lately (or no longer allowed or interested?) to approve and use pull-requests from the community.

              Essentially the following two lines need to be removed:

                  out_buf[2] = 0x00;
                  out_buf[3] = 0x00;
              

              See here around line 232.

              Thanks
              Felix

              GPIO translation table M5Stack / M5Core2
              Information about various M5Stack products.
              Code examples

              JopJ 2 Replies Last reply Reply Quote 0
              • JopJ
                Jop @felmue
                last edited by

                @felmue
                Hi Felix,

                Thnx for your fast response.

                I out commented the 2 lines you mentioned, this seems to work, but I experience more problems.
                This shutdown() logic of the M5Paper is rather buggy. I think some engineers of M5Stack should inspect this modules and repair.
                For example: I want my M5Paper to be waked up by the RTC every full 5 minutes, then it has to run for about 10 to 15 seconds and to go in sleepmode for the rest of that 5-minute period. For that I wrote routine goSleep() to calculate the next moment of awakening.
                I tried several possibilities for the different overlaid methods of shutdown():

                1. calculate remaining seconds to go sleep and used overload-2
                2. calculate timestamp for the next 5-minute moment and used overload-3
                3. calculate date & timestamps for the next 5-minute moment and used overload-4

                Now comes the weird thing (so the bugs), in any of these cases the wakeup comes ALSO at every 3-minute, so both at every 3-minute and at every 5-minute moments.
                So where I want to have this wake up schedule: hh:00 hh:05 hh:10 hh:15 hh:20 ...and so on...
                I get this wake up schedule: hh:00 hh:03 hh:05 hh:08 hh:10 hh:13 hh:15 hh:18 hh:20 ...and so on...

                Before your suggested patch I tried only method 1 (as 2 did not work without your patch) and then it was every 4-minute and every 5-minute my M5Paper woke up by the RTC.
                I inspected my calculations logic and this is OK. The problem is somewhere in the M5Paper library.

                If necessary I can isolate the code I use to show you; but that's a bit more work.

                Kind regards,

                Jop
                
                1 Reply Last reply Reply Quote 0
                • JopJ
                  Jop @felmue
                  last edited by

                  @felmue

                  Hi Felix,

                  In addition to my last post, I wrote that the shutdown() looks rather buggy.

                  Now I found reason for this behavior - partly reason - some overload variations are now OK, but one has still problem as I described in my last post.
                  The reason for buggy behavior, I included this:
                  #include <ESP32Time.h>
                  ESP32Time rtc;
                  to make it possible to set also the ESP32 internal RTC that's present in this processor, named by me with "rtc".
                  The external BM8563 I named as "RTC".
                  Maybe these library is interfering with the BM8563-code.

                  I said "partly reason" as Overload-2 still has the same problem as I wrote before.

                  Kind regards,

                  Jop
                  
                  1 Reply Last reply Reply Quote 0
                  • felmueF
                    felmue
                    last edited by

                    Hello @Jop

                    have you tried to rename rtc to something else? Does that fix the issue?

                    @M5Stack engineers : any idea what's going on here?

                    Thanks
                    Felix

                    GPIO translation table M5Stack / M5Core2
                    Information about various M5Stack products.
                    Code examples

                    JopJ 1 Reply Last reply Reply Quote 0
                    • JopJ
                      Jop @felmue
                      last edited by

                      @felmue
                      Hello Felix,

                      No, didn't try rename rtc. What difference should it make? (In C++ rtc and RTC are different identifiers, is n't it).
                      The reason for introduction of the own internal rtc of the ESP32 was looking for a simple way to set the system clock from the M5Paper RTC after awakening and without connecting to WiFi (this is very time- and battery-consuming).

                      The weird thing is: syncing with NTP is rather simple in ESP32-Arduino environment, but just setting the system time equal to the 'external' BM8563 RTC-time is more complicated. There is no simple routine. I found some not so elegant way with mktime().

                      Another point: I discovered bugs with awakening the M5Paper when this awakening moment should be exactly at midnight: so at 24:00u or 00:00u.
                      See a next post (if I find time to describe).

                      Kind regards,

                      Jop
                      
                      1 Reply Last reply Reply Quote 0
                      • D
                        dheijl
                        last edited by

                        To make this detection really reliable I had to change the RTC register check like this:

                        Wire.begin(21, 22);
                        uint8_t reason = M5.RTC.readReg(0x01);
                        // now it's safe
                        M5.begin();
                        // check reboot reason flag: TIE (timer int enable) && TF (timer flag active)
                        if ((reason & 0b0000101) == 0b0000101) {
                            restartByRTC = true;
                            Serial.println("Reboot by RTC");
                        } else {
                            restartByRTC = false;
                            Serial.println("Reboot by power button / USB");
                        }
                        
                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post