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

    M5.Axp.ScreenBreath() crashes when used in interrupt

    M5 Stick/StickC
    2
    3
    4.1k
    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.
    • M
      M95D
      last edited by

      Hi.
      It seems that M5.Axp.ScreenBreath() crashes when it is used in a interrupt. Try the demo below in Arduino IDE. It should turn off the display after a timer delay and turn it back on when the button is pressed.
      On my system this program crashes with a watchdog timeout during i2c operation.

      #include <M5StickC.h>  //define M5StickC hardware components and functions
      #define BUTTON_MAIN 37  //The main button pin number
      #define SCREEN_TIMEOUT 10 //Screen-off timeout in seconds
      hw_timer_t *timer;
      
      void IRAM_ATTR onButton() { //Interrupt on button press => turn on the screen
       detachInterrupt(BUTTON_MAIN); //Ignore more button presses
       M5.Axp.ScreenBreath(10); //Set screen light ON
       timerAlarmEnable(timer); //Start timer for screen-off delay
      }
      
      void IRAM_ATTR onTimer(){  //Interrupt on timer => turn off the screen
       timerAlarmDisable(timer); //Stop the timer.
       M5.Axp.ScreenBreath(0); //Set screen light OFF
       attachInterrupt(BUTTON_MAIN,onButton,FALLING); //Attach interrupt on button press => turn on the screen
      }
      
      void setup() {
      M5.begin(); //Init M5
      M5.Lcd.fillScreen(YELLOW); //Make screen yellow
      pinMode(BUTTON_MAIN, INPUT_PULLUP); //Button GPIO set as input, pull-up enabled
      timer=timerBegin(1,40000,true); //Init screen light timer, divisor 40000 => 0.5ms steps
      timerAttachInterrupt(timer,&onTimer,true);  //Set screen light timer interrupt function
      timerAlarmWrite(timer,SCREEN_TIMEOUT*2000,true); //Set interrupt to turn off screen after X timer steps of 0.5ms each.
      timerAlarmEnable(timer); //Start timer for screen-off delay
      }
      
      void loop() {
        //No code here.
      }
      
      1 Reply Last reply Reply Quote 0
      • felmueF
        felmue
        last edited by

        Hello @M95D

        interrupt functions need to be as short as possible, run from RAM and everything in it (e.g. every function you call from within) also needs to run from RAM. In your case only onTimer() is in RAM, but everything else is probably not. All this is causing the watchdog to trigger.

        To solve the issue, you should only set a flag in the interrupt function and test this flag in the loop() function and then act upon it.

        Try something like this:

        #include <M5StickC.h>  //define M5StickC hardware components and functions
        #define BUTTON_MAIN 37  //The main button pin number
        #define SCREEN_TIMEOUT 10 //Screen-off timeout in seconds
        hw_timer_t *timer;
        
        volatile bool onButtonFlag = false;
        volatile bool onTimerFlag = false;
        
        void IRAM_ATTR onButton() { //Interrupt on button press => turn on the screen
          onButtonFlag = true;
        }
        
        void IRAM_ATTR onTimer(){  //Interrupt on timer => turn off the screen
          onTimerFlag = true;
        }
        
        void setup() {
        M5.begin(); //Init M5
        M5.Lcd.fillScreen(YELLOW); //Make screen yellow
        pinMode(BUTTON_MAIN, INPUT_PULLUP); //Button GPIO set as input, pull-up enabled
        timer=timerBegin(1,40000,true); //Init screen light timer, divisor 40000 => 0.5ms steps
        timerAttachInterrupt(timer,&onTimer,true);  //Set screen light timer interrupt function
        timerAlarmWrite(timer,SCREEN_TIMEOUT*2000,true); //Set interrupt to turn off screen after X timer steps of 0.5ms each.
        timerAlarmEnable(timer); //Start timer for screen-off delay
        }
        
        void loop() {
          if(onButtonFlag) {
            onButtonFlag = false;
            detachInterrupt(BUTTON_MAIN); //Ignore more button presses
            M5.Axp.ScreenBreath(10); //Set screen light ON
            timerAlarmEnable(timer); //Start timer for screen-off delay
          }
          if(onTimerFlag) {
            onTimerFlag = false;
            timerAlarmDisable(timer); //Stop the timer.
            M5.Axp.ScreenBreath(0); //Set screen light OFF
            attachInterrupt(BUTTON_MAIN,onButton,FALLING); //Attach interrupt on button press => turn on the screen
          }
        }
        

        Cheers
        Felix

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

        1 Reply Last reply Reply Quote 0
        • M
          M95D
          last edited by

          Works. Thank you!

          1 Reply Last reply Reply Quote 0
          • First post
            Last post