Knowledge Base

Deep sleeping during transmission back-offs and duty cycling? 

With loramac-node we have had to make quite a few modifications to ensure that a node deep sleeps (lowest current draw) as much as possible to save battery, including during transmission back-offs and duty cycling.
There was also the complexity of removing the variable time spent sleeping due to such transmission delays from regular data sampling and transmission periods. (E.g. if wake-up event is 60 minutes and duty cycle transmission delay is x minutes, then modify the wake-up event to be 60-x minutes)
Advice would be appreciated on whether deep sleeping during back-offs and duty cycle waits is already implemented in basicmac?
Or are there some particular steps that it is advised should be taken to achieve that?
Many thanks, Ron
The handling of sleep falls into the domain of the HAL. The included HAL reference implementation for the STM32L0 puts the MCU into STOP mode with Flash turned off whenever possible. To keep accurate time while sleeping, the external 32.768kHz crystal (LSE) is left on, and the low-power timer peripheral (LPTIM1) is used. Because this is a 16-bit timer, the MCU will wake up every 2 seconds to handle the overflow. This overflow handling is done in low-power run mode with the MSI at 65kHz, running from RAM with the Flash staying powered off.

The code for this can be found in stm32/hal.c
Hi Mike
Thanks, appreciate the response. Certainly useful to understand how deep sleep is implemented in the stack, particularly the use of LPTIM1, as we have used that for some applications of loramac-node, so we would have to rethink those when shifting to SimpleMAC.

However my question was really more about whether your 'whenever possible' applies to back-offs and duty cycling?

A view on this would be most helpful, thanks.
The run-time system used by the stack is based on jobs that can be scheduled to run at a specific point in time. For example, the stack will schedule a job to run 5 seconds after the transmission of a join-request to start the reception of a potential join-accept message. The scheduler will put the MCU to sleep between running jobs.

How deep the MCU will sleep depends on a few factors. Both the application and device drivers may restrict the available sleep modes. For example, if a UART peripheral that depends on a high-speed clock is active and in receive or send mode, it would disable going to a sleep mode that reduces the system clock speed or turns it off completely.

Further, entering and exiting sleep modes takes time; wake-up from different sleep modes has a latency that depends on the sleep mode itself. In general, the deeper the sleep, the longer it takes to wake-up. The HAL ensures that there is enough time to service the next job in a timely manner and chooses an appropriate sleep mode.

Without going into too much detail here, the way that deep sleep is implemented with the LPTIM1 peripheral means that wake-up is only possible on the roll-over that occurs every 2 seconds. If the next job needs to run before this time (minus the wake-up latency), a less deep sleep is used instead.

To answer your questions specifically, unless there is a job scheduled that need to be run at a point in time sooner than ~2 seconds, and unless there are peripherals active that restrict sleep modes, the MCU will go to deep sleep mode. This applies to any type of idle time, including duty-cycling and back-offs.
Great reply, thanks again Mike.
Sleep behaviour seems to be well designed and exactly what's needed.
Also the 'jobs' concept is simple yet flexible.

Pretty convinced now that it will be well worth the effort to become familiar with and shift to LoRa Basics MAC
     basicmac examples ››