RAK3172: Extra +EVT:TX_DONE waking up from sleep

Hello,

This post explains the reason for multiples +EVT:TX_DONE received:

https://forum.rakwireless.com/t/rak3172-one-send-double-answer/13883/2?u=igtti

My current issue is:
After sending the payload I wait for the “SendCallback” and go to Sleep. It works most of the times. But, when the extra +EVT:TX_DONE comes it wakes the system up!

I haven’t found a way to detect this and prevent the system from being waked up.
Please, how to handle this extra +EVT:TX_DONE ?

You cannot handle the +EVT:TX_DONE message, it is generated automatically by RUI3 for the AT command interface.

If you setup your code well, this message will only shortly wake-up the device and it will go immediately into sleep again if you use api.system.lpmlvl.set(2); and api.system.lpm.set(1); and do not use the loop.
However, if you are using api.system.sleep.xxxx(yyyy) in your loop(), it is quite difficult.

Check our RUI3-Best-Practices repo for examples for RUI3.
Specially the RUI3-LowPower-Example is a good example how to use RUI3 as an event driven system and achieve lowest power consumption.

Hi @beegee ,

This is exactly my case, I am using timers to control the tasks and as soon as all are completed I call the “api.system.sleep.all()”.

The problem when using the “api.system.lpm.set(1)” is about the UART1, which stops working well.

Is it possible to dinamically set and unset the LPM in order to allow the UART to operate when needed?

Is there a callback to check the interrupt source?

Thanks.

You can try to use api.system.lpm.set(1) and api.system.lpm.set(0) to enable/disable the sleep mode if you need to use UART1, but I never used that.

What “interrupt source” do you mean?
If you setup interrupts, you have to define the interrupt handler.
For LoRa/LoRaWAN, only the callbacks mentioned in the documentation are available.

Hello @beegee ,

I found a way to use the “api.system.sleep.all()” and not setting the Low Power Mode “api.system.lpm.set(0)”.
It is not the most elegant solution, but is working very well.

In general I retry the sleep command as soon as the system wakes and the reason is different from my expected frequent timer.

I set a flag in my main timer callback:

/***************************************************************************************
*   Wakeup Timer function to start the short time timers
****************************************************************************************/
void WakeupTimer_Callback(void *data)
{
   //Serial.println("Interrupt 10min");
   gui8_WakeupSource = 1U;                                     // Wakeup indicated as this timer
   api.system.timer.start(RAK_TIMER_1, TASK_500ms, NULL);
   api.system.timer.start(RAK_TIMER_2, TASK_100ms, NULL);
}

And test this flag when the system wakes up, if not set, sleep again:

Serial.println("Going to sleep");
      gui8_WakeupSource = 0U;                // Reset the flag waiting for the next interrupt

      api.system.sleep.all();                // Sleep all
 
      if(gui8_WakeupSource != 1U) {
         Serial.println("Sleep again 1...");
         api.system.sleep.all();                // Sleep all again, due to unexpected interrupt (UART ??)
      }
      if(gui8_WakeupSource != 1U) {
         Serial.println("Sleep again 2...");
         api.system.sleep.all();                // Sleep all again, due to unexpected interrupt (UART ??)
      }
      if(gui8_WakeupSource != 1U) {
         Serial.println("Sleep again 3...");
         api.system.sleep.all();                // Sleep all again, due to unexpected interrupt (UART ??)
      }
      if(gui8_WakeupSource != 1U) {
         Serial.println("Sleep again 4...");
         api.system.sleep.all();                // Sleep all again, due to unexpected interrupt (UART ??)
      }

      Serial.println("Waking up");

I repeated 4 times the sleep again check. During my tests I could see it waking up max 2 times. And most of the times only the first Sleep is executed.

Best regards.