XIAO MG24 Sense - ArduinoLowPower Interrupt Handler callback not firing

Hey there,

I have a XIAO MG24 Sense that I am putting into deep sleep with a timer to wake up ever couple of minutes. I also have a pin with and interrupt wakeup attached that’s working well. The only think I’d love to improve is to be able to tell if it was the timer that woke the XIAO up, or if it was the interrupt. The callback seems to be the way to do that but it doesn’t seem to be firing. Either that, or maybe my code is wrong. Does anyone have any experience with this?
Thanks

volatile int wakeReason = 0;

void enterStandbySleep() {
  LowPower.attachInterruptWakeup(WAKE_UP_PIN, callback, HIGH);
  LowPower.deepSleep(SLEEP_DURATION);
}

void callback() {
  wakeReason++;
}

This is just an example, but wakeReason never changes.

I have tested your code and it works as expected.

The callback is never called for Deep Sleep as the deep sleep causes a reset when the wake is processed so code essentially “looks” like a reboot.

The Pin Wake also works as expected - A High state wakes the device.

Thanks for testing! So there’s no way for deep sleep to ever know why it was woken up then?

Sorry for the delay in responding - Saturday here :sunglasses:

You can get the GPIO wake pin from the following…

uint32_t wake_cause = GPIO_EM4GetPinWakeupCause();

If the value returned is what your wake pin is then you have a GPIO wake.

In my case I use GPIO_IEN_EM4WUIEN0 (Port A5) so I use that as the check.

  if (GPIO_EM4GetPinWakeupCause() & GPIO_IEN_EM4WUIEN0)
  {
    PRINTF("GPIO Wake Pin %d", WAKE_PIN);
  }

Edit> Wake Pins on MG24.

Hi there,

So this is an Interesting topic to me. I have used the Wake Up “Stub” method, and the op’s question stirred the pot.
We have been using it basically all along with the Boot Counter code circulating to many examples and demo’s :+1: I wondered if it was the same on MG24 , AL says no, but sort of?

Officially, " the “wake stub” feature on the ESP32, which is a small piece of code that runs immediately after the chip wakes from deep sleep, before the main setup() or app_main() is called. "

ESP32 Wake Stub — Overview

  • Wake stub is a special function that resides in RTC slow memory.
  • It’s used to execute minimal logic right after wake-up, before the main app starts.
  • You can use it to:
    • Check wake reason (RTC GPIO, timer, etc.).
    • Decide whether to go back to sleep immediately (for example, a false wake).
    • Set flags or change boot behavior.
  • Useful for ultra-low-power decision making before full wake.

How to Use a Wake Stub on ESP32

You declare a stub like this:

RTC_IRAM_ATTR void esp_wake_deep_sleep_stub(void) {
  // Minimal logic here — no malloc, Serial, etc.
  gpio_set_level(GPIO_NUM_2, 1);  // Blink LED or something
  esp_default_wake_deep_sleep();  // Continue boot process
}

We all use this in Xiao Boot counter code…

RTC_IRAM_ATTR puts the stub in RTC slow memory, so it survives deep sleep.

:wrench: Limitations

  • No global variables unless marked with RTC_DATA_ATTR.
  • No Serial, no heap, no Wi-Fi, no BLE.
  • Must be extremely small and fast.
  • Must call esp_default_wake_deep_sleep() at the end if you want to continue boot.

How do others address it?

HTH
GL :slight_smile: PJ :v:

Does the EFR32MG24 (Silicon Labs) Support This?

MG24 Approach:

  • BURTC (Backup RTC) can wake the device.
  • Reset Reason and EMU Status can tell you why it woke up.
  • Your main firmware can act early on wake reason, but not before boot like ESP32’s stub.

How do you do stuff like this ?

I don’t worry about that as the MG24 wakes from deep sleep in a couple of uS, as opposed to the several (100?) mS of an ESP32.

I seldom use deep sleep (EM4) anyway, and generally stick with EM2 (light sleep). Unless I am using Arduino framework, but that is only for this forum.

1 Like

Thanks @grobasoz ! That worked great.

1 Like