RAK3172 sending "status" uplink by himself

Hi,

I have noticed that module RAK3172 is sending lorawan status uplinks every 24 hours by himself. I have not configured this anywhere.

I have two questions:

  1. How can I disable this periodic status uplink ? (my uplinks are more frequent and have battery information)

or

  1. How can I insert my battery reading in this status uplink? (I can reduce the payload of my periodic uplinks)

Thank you
Antonio

It is in the settings of your LoRaWAN server (so either it is by default on 24 hours, or you set it to that interval). If you enable this status report, it is requested from the RAK3172 during the Join process.

In Chirpstack you can set this in the Device Profile:

Thank you for the information.

I’m using chirpstack v3 as we are using API REST extensively and v4 require too many changes. In v3 there is not such configurable parameter so I guess this is hardcoded anywhere.

Is there any RUI3 API or variable to report back the battery level using these status messages?

Thank you
Antonio

1 Like

RUI3 does not have any function to include the battery level into the status message.
As RUI3 is designed for WisDuo modules, we cannnot know what kind of battery measurement would be required, which analog pin to use, …

You can use api.system.bat.get() but that expects that you have a 1M/1.5M voltage divider on your battery supply and read the voltage through ADC1 / PB3.

image

If you have another circuit or pin to read the battery voltage, you can use the Analog IO functions to setup an ADC pin and read the voltage.

Thank you for your answer. Understood.

May be it is interesting to add a new api function , something like this:

api.system.bat.set( my_battery_voltage_function() )
In order to inform the API and subsequent “status” packets the battery voltage.

or even a callback RUI3 calls before each “status” packet
api.system.bat.callback( my_battery_voltage_callback_function() );

This approach is HW independent. Best regards
Antonio

I was thinking about something like this. Will discuss it with the R&D team.

LoRaWAN stack have internal callback with nulled function in service_lora.c

LoRaMacCallbacks.GetBatteryLevel = NULL;

It`s just need to register the function to get the battery status

    /*!
     * \brief   Measures the battery level
     *
     * \retval  Battery level [0: node is connected to an external
     *          power source, 1..254: battery level, where 1 is the minimum
     *          and 254 is the maximum value, 255: the node was not able
     *          to measure the battery level]
     */
    uint8_t ( *GetBatteryLevel )( void );

I have to remove the static keyword in the declaration of LoRaMacCallbacks in service_lora.c in order to use it.

Will let you know if this works

Thank you @croman13n3c for the information

Hi @croman13n3c

confirmed LoRaMacCallbacks.GetBatteryLevel = my_get_battery_level(); works !!

But previously I had to remove the static before LoRaMacCallbacks declaration in order to make it public

cores/STM32WLE/component/service/lora/service_lora.c:
/* static */ LoRaMacCallback_t LoRaMacCallbacks;

Thank you!
Antonio

My proposal to the R&D team, but no promise when it will be implemented (This is from a RAK4631, but beside of the USB detection it works on RAK3172).
Two small changes in the RUI3 files:
service_lora.h add uint8_t UserBattLevel(void) __attribute__((weak));
service_lora.c change LoRaMacCallbacks.GetBatteryLevel = NULL; to LoRaMacCallbacks.GetBatteryLevel = UserBattLevel;

/**
 * @brief Callback for LoRaMAC stack to get battery level
 *   Requires changes in the RUI3 files
 *   service_lora.h add `uint8_t UserBattLevel(void) __attribute__((weak));`
 *   service_lora.c change `LoRaMacCallbacks.GetBatteryLevel = NULL;` to `LoRaMacCallbacks.GetBatteryLevel = UserBattLevel;`
 */
uint8_t UserBattLevel(void)
{
	// on USB return 0
	if (NRF_POWER->USBREGSTATUS == 3)
	{
		MYLOG("BAT", "On USB");
		return 0;
	}

	// else calculate the battery status
	float batt_voltage = api.system.bat.get();
	for (int idx = 0; idx < 10; idx++)
	{
		batt_voltage += api.system.bat.get();
	}
	batt_voltage = batt_voltage / 11;
	batt_voltage *= 1000;

	uint8_t lora_batt = batt_voltage * 255 / 4200;

	MYLOG("BAT", "Calculated %d from %.2fmV", lora_batt, batt_voltage);
	return lora_batt;
}

In addition, some info about the values that should be returned:

0 ==> permanent power supply
1 … 254 ==> Battery level, 0% to 100% converted to a value from 1 to 254
255 ==> no information about supply