RUI3 Wake on Interrupt

When api.system.sleep.all(time) is called, is there a way to wake up the device using a software interrupt?

Hi @BraveKerry ,

What do you mean with software interrupt? What peripheral do you need to trigger the interrupt? Currently, I believe there is no provision in the RUI3 FW framework to do that. It can only wakeup via a timer or UART input.

Btw, you can sleep for an interval and do some housekeeping tasks if you need on that fixed interval. Let’s say you sleep for 10seconds then check things on that interval then go back to sleep again. I am not sure though about the impact on your current consumption with that.

Theoretically it should be possible to use in RUI3 API the attachInterrupt() Arduino function to get an interrupt from a GPIO.

Honestly I did not test it.

My apologies, by software interrupt, I was more or less thinking of timer interrupts. However, I’ve also attempted attachInterrupt(), but after running the interrupt handler, it doesn’t seem to wake up the device, unless api.system.sleep.all() is called without parameters.
On the topic of timer interrupts, I did test out api.system.timer methods. I’m wondering where I may find more documentation on it? I’m currently just reading the function specs on the header files (couldn’t find much on the RUI3 documentation).

I have tried using attachInterrupt() as an interrupt, however, I’m quite confused on the differing behavior of running it with a set time vs no set time. I’m particularly looking for the behavior of running it without parameters, so that the device may wake up, but being able to call the method with a set timer, e.g. calling attachInterrupt(10000) and still being able to wake device from interrupt. I have screenshots of my testing below.
image

Sorry, I thought you mean external sources. attachInterrupt works only with GPIO’s.

For wakeup from timer, I use that in my RUI3 examples, e.g. in the RUI3-Sensor-Node-Air-Quality. I start a timer that wakes up frequently the device, calls a function to do some stuff, then the device sleeps again. The loop() does nothing than sleep.

Reduced code

void setup()
{
	// ...
	// some setup code
	// ...

	// Create a unified timer in C language. Timer callback function is **sensor_handler**
	udrv_timer_create(TIMER_0, sensor_handler, HTMR_PERIODIC);

	// Start a unified C timer in C language.Second parameter is wakeup time in milliseconds
	udrv_timer_start(TIMER_0, 30000, NULL);
	}

	// ...
	// other setup code
	// ...
}

/**
 * @brief sensor_handler is a timer function called every
 * g_lorawan_settings.send_repeat_time milliseconds. Default is 20000. Can be
 * changed in the timer start function
 *
 */
void sensor_handler(void *)
{
	// ...
	// Do some sensor readings or other stuff
	// ...
}

/**
 * @brief This example is complete timer
 * driven. The loop() does nothing than
 * sleep.
 *
 */
void loop()
{
	api.system.sleep.all();
}
1 Like

This code part will be available as an API command in the future. something like api.system.timer.start()
Still waiting for the R&D to implement it.

EDIT

Just found out that (at least in my RUI3 version) the timer commands already exist:

    /**@par     Create a timer.
     * @param   id the timer ID
     * @param   handler the handler function for this timer
     * @param   mode the mode of this timer
     * @return  bool
     * @retval  TRUE for creating timer successfully
     * @retval  FALSE for creating timer failure
     */
bool    api.system.timer.create(RAK_TIMER_ID id, RAK_TIMER_HANDLER handler, RAK_TIMER_MODE mode);

    /**@par    Start a timer.
     * @param   id the timer ID
     * @param   ms the period of timer
     * @param   data the data passed to timer handler function
     * @return  bool
     * @retval  TRUE for starting timer successfully
     * @retval  FALSE for starting timer failure
     */
bool    api.system.timer.start(RAK_TIMER_ID id, uint32_t ms, void *data);

    /**@par     Stop a timer.
     * @param   id the timer ID
     * @return  bool
     * @retval  TRUE for stoping timer successfully
     * @retval  FALSE for stoping timer failure
     */
bool    api.system.timer.stop(RAK_TIMER_ID id);
1 Like

I’ve gotten the below to work as I’d like, with timers that wake up the device. Cheers! On a side note, do you know if created timers persist forever? i.e. would it be a bad idea to create hundreds of timers with different ids?

void loop()
{
  int sleepTimer = stateHandler(); 
  Serial.print("Sleeping for ");
  Serial.println(sleepTimer); 
  if (sleepTimer > 0) {
    api.system.timer.create((RAK_TIMER_ID) MAIN_TIMER, (RAK_TIMER_HANDLER) timerInterruptHandler, RAK_TIMER_ONESHOT);
    api.system.timer.start((RAK_TIMER_ID) MAIN_TIMER, sleepTimer, (void *) 1);
  }
  api.system.sleep.all(); 
  Serial.println("Woke up");
}

void timerInterruptHandler() {
  Serial.println("Timer interrupt");
}

You have 5 timers available, so use them wisely:

/**@par	Description
 * 	The ID of timer
 */
typedef enum {
    RAK_TIMER_0 = TIMER_0,	///< timer ID #0
    RAK_TIMER_1 = TIMER_1,	///< timer ID #1
    RAK_TIMER_2 = TIMER_2,	///< timer ID #2
    RAK_TIMER_3 = TIMER_3,	///< timer ID #3
    RAK_TIMER_4 = TIMER_4,	///< timer ID #4
    RAK_TIMER_ID_MAX = TIMER_ID_MAX,	///< this is the number of all available timers
} RAK_TIMER_ID;
1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.