RAK3172 Low Power Mode with timer and button: source code example

I spent some time to find out how to make LPM with timers and keep board sleep rest of the time and this is an example:

uint8_t ledPin = PA8; // set your pin
uint8_t buttonPin = PA9; // set your pin

void setup()

  if (!api.system.lpm.set(1)) 
	Serial.println("Set low power mode is incorrect! \r\n");

  pinMode(ledPin, OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(buttonPin, button_click, FALLING);

  if (api.system.timer.create(RAK_TIMER_0, (RAK_TIMER_HANDLER)sensor_handler, RAK_TIMER_PERIODIC) != true) 
    Serial.printf("Creating timer failed.\r\n");
  if (api.system.timer.start(RAK_TIMER_0, 1000 * 5 , NULL) != true) 
    Serial.printf("Starting timer failed.\r\n");

  digitalWrite(ledPin, HIGH);

void button_click()

void sensor_handler(void *)
    digitalWrite(ledPin, HIGH);
    digitalWrite(ledPin, LOW);

void loop()

Energy consumption:

I hope it will help someone.

1 Like

Can you implement with LoRaWAN together ?

Sorry, I do not use LoWAN, only Phy

Here is low power RUI3 example with LoRaWAN

If you wonder why there are only a few API calls for LoRaWAN in it, I setup my devices with AT commands or WisToolBox. That way I can use the same code on multiple devices without the need to change the AppEUI, DevEUI and AppKey every time.

I checked your code in github and it looks almost the same like mine, except one moment: after LoRa done with sending your message you need explicitly change LoRa back to Sending mode, otherwise it will keep waiting in loop for the next incoming message and will NOT go back into LPM.

I did it like this:

void send_callback(void)
  Serial.printf("P2P finish Rx mode %s\r\n", api.lorawan.precv(0) ? "Success" : "Fail");

wIch the at command to define interval ?
for example, 10 seconds ?
AT+SENDINT=00 00 00 0a ?


AT+SENDINT=10 sets send interval to 10 seconds.

for me i got

RAKwireless RUI3 Node

Setup the device with WisToolBox or AT commands before using it

RUI3 RUI_4.0.2_RAK3172-E

[SETUP] Confirmed disabled

[SETUP] Retry = 0

[SETUP] DR = 2

Current Work Mode: LoRaWAN.

Sorry, custom AT commands need ATC instead of AT


i will test

btw, in the example that you sent me, must i send a AT+JOIN ?

Looks that the user must to send…

Once device is setup, you can use AT_JOIN=1:1, which will tell the device to automatically join on power-up or reset.

Hey, if you use
And RESET, never JOIN

But, if you use
And RESET, and AT+JOIN=1:0, always JOIN

test there

RAK - YouTube

you sleep example looks working…

I can wake up when press a key…to ground…


pinMode(Hall_Sensor, INPUT_PULLUP);

attachInterrupt(Hall_Sensor, Hydrometer_Pulse, FALLING);

But looks that is getting a lot of interrupts…

something that i have to do into Handler ?

void sensor_handler(void *)


  MYLOG("UPLINK", "Start");

  if (api.lorawan.nwm.get() == 1)

  { // Check if the node has joined the network

    if (!api.lorawan.njs.get())


      MYLOG("UPLINK", "Not joined, skip sending");




UPD: this option is do nothing and actually with that option device stop working after around 4-5 days.

solved about interrupt, NOISE

About your text

“UPD: this option is do nothing and actually with that option device stop working after around 4-5 days.”

What means ?

in you lowpower arduino example, why dont you never used the ATZ command ?
You mean that the RAK3172 will never stop…if stop…will trigger a watch dog ?

For example, i do a ATZ when get 3 sequences of LINKCHECK0:0:0:0:0 or when i get 3 sequences of JOIN fail…

Is really necessary i do this ATZ ?

Give me your opnion…about user experiences…