RAK4631 + OTAA + protection against battery discharge

Hello,
I used only ABP before mode but would like to switch to OTAA.
DeepSleep-Lorawan works in both modes but I would like in OTAA to have protection against battery discharge if the gateway does not work after restarting the node (so join is not possible for some time).
How to better do it:

  • do join in the factory and save the data to FLASH so that it is not necessary to rejoin in the furture
  • after a failed join attempt, put the device to sleep for e.g. 10 minutes and try again and so on

That will not be easy to implement, because the LoRaWAN stack needs to be initialized after power-up/restart and there is no option to tell the stack that it has already joined and provide the join information.

Thanks Bernd, ok but option no. 2 so in:
static void lorawan_join_failed_handler(void)
{
Serial1.println(“OVER_THE_AIR_ACTIVATION failed!”);
Serial1.println(“Check your EUI’s and Keys’s!”);
Serial1.println(“Check if a Gateway is in range!”);
}
put node for 10 min sleep and restart it?

That’s a bad idea if you goto sleep inside of lorawan_join_failed_handler, beause is a callback from the LoRaWAN stack. So putting your device into sleep inside this callback will mess up the whole timing of the stack.

A possible solution is to just set a flag (or a semaphore) in the callback function. Then in your loop() you can check that flag, if join failed goto sleep for 10 minutes and then retry.

e.g. (untested)

#include <Arduino.h>

SemaphoreHandle_t g_join_event;

void setup()
{
\\ ... your usual setup stuff

	// Create the join event semaphore
	g_join_event= xSemaphoreCreateBinary();
	// Initialize semaphore
	xSemaphoreGive(g_join_event);
	// Take semaphore
	xSemaphoreTake(g_join_event, 10);

	// Start Join process
	lmh_join();

	bool has_joined = false;
	while (!has_joined )
	{
		// Wait until semaphore is released (FreeRTOS)
		xSemaphoreTake(g_task_sem, portMAX_DELAY);
		if (lmh_join_status_get() != LMH_SET)
		{
			// Join failed, sleep for 10 minutes
			delay(10*60*1000);
			lmh_join(); // Try to join again
		}
		else
		{
			// Join success
			has_joined = true; // leave while(1)
		}
	}
}

void loop(void)
{
\\ ... your loop stuff
}

void lpwan_join_fail_handler(void)
{
	xSemaphoreGive(g_join_event);
}

static void lpwan_joined_handler(void)
{
	xSemaphoreGive(g_join_event);
}

Thank you, very helpful!
One more thing - when I wrote about sleeping, I meant Deep sleep. While waiting these 10 minutes, I don’t need to do anything. After that, there will be a software reset so everything will refresh anyway. Will this still be a problem for the stack?

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