MKR Zero Board Sleep Mode


I'm trying to make my MKR Zero blink an LED, sleep for a couple seconds, then wake up by itself from internal RTC and repeat the action before going back to sleep. I'm testing the sleep feature with this Arduino LowPower Library example but when I upload it, it goes to sleep and never wakes up (it only blinks the LED once, then after that nothing happens). I can tell it's sleeping because I can no longer see the COM port, but the LED never flashes again.

I should note that this external interrupt wake up example works great, but the timed wakeup doesn't.

Any ideas what's going on here?


Ultimately my goal is to sleep it for, say, 5 minutes. I know this isn't possible with a single sleep cycle so I can just use a counter and count the number of sleep periods it has gone through. However, I would like to minimize the current consumption. Would the deepSleep() function work for the SAMD21 and draw less power than the sleep() function?

Also, I read that the max sleep time for a single cycle is 16s. Does that mean I can use deepSleep(16000) and it should wake up after 16s?

Well, I guess I solved my problem by using this RTCZero code. But that still doesn't explain why the LowPower library code doesn't work. It's based on the RTCZero library.

However, I measured the current consumption through a LiPo battery and uCurrent GOLD ammeter and it's drawing 1.0mA of current. I was expecting more like something in the uA range. Is this the lowest the M0 can go with only internal RTC enabled? That doesn't seem right.

Did you ever figure out how to sleep in low power mode? I'm new to this and haven't had any luck.


Hi jackrubin,

Setting the SAMD21’s SLEEPDEEP bit in the ARM Core’s System Control Register (SCR), indicates that when the low power mode is activated, the processor should go into low power STANDBY mode, (rather than IDLE mode):

SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;            // Set up the CPU to enter low power STANDBY mode, (rather than IDLE mode)

The __WFI() (Wait for Interrupt) function is the command that actually puts the processor into deep sleep:

__WFI();                                      // Put the SAMD21 into deep sleep Zzzzzzzzzz

In this instance the processor can be woken by an interrupt, by simply using the attachInterrupt() function.

The SAMD21 also allows its various on-chip oscillators and off-chip crystals to remain active during sleep, in order for selected peripherals to remain active. This is usually done by setting the oscillator’s and peripheral’s RUNSTDBY (Run Standby) bit. For example this can be used allow the SAMD21’s Real Time Clock (RTC) to run off a slow clock, such as the 32.768kHz crystal, while CPU is asleep.

There’s also an ONDEMAND bit that allows the clocks to become active only when required by the peripheral. In this case a request is sent by the peripheral back via the generic clock system to start and stop the oscillator.