RUI3 on RAK3172 API error

I am using the RUI3 library for the first time and facing some problems with the returned values for RX1DL and RX2DL.

RAK3172
Latest FW version 4.2.1

The function bellow does the module initialization:

#define OTAA_BAND                RAK_REGION_LA915
#define OTAA_DEVEUI              {0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x88}
#define OTAA_APPEUI              {0x6a, 0x22, 0x2b, 0x60, 0x3f, 0x2e, 0xd0, 0xba}
#define OTAA_APPKEY              {0x6a, 0x22, 0x2b, 0x60, 0x3f, 0x2e, 0xd0, 0xba, 0x43, 0x3e, 0xfb, 0x10, 0x05, 0xb4, 0x4b, 0x1c}
#define OTAA_JN1DL               5
#define OTAA_JN2DL               6
#define OTAA_RX1DL               5
#define OTAA_RX2DL               6

uint8_t gui8_Device_EUI[8];               // OTAA Device EUI MSB first
uint8_t gui8_App_EUI[8];                  // OTAA Application EUI MSB first
uint8_t gui8_App_KEY[16];                 // OTAA Application Key MSB first

void Init_LoRa(void)
{
   uint8_t ui8_DEF_Device_EUI[8] = OTAA_DEVEUI;
   uint8_t ui8_DEF_App_EUI[8] = OTAA_APPEUI;
   uint8_t ui8_DEF_App_KEY[16] = OTAA_APPKEY;
   uint8_t ui8_NoMatch;


   if (api.lorawan.nwm.get() != 1U) {
      Serial.printf("Set network working mode %s\r\n", api.lorawan.nwm.set() ? "Success" : "Fail");
   }

   if (api.lorawan.band.get() != OTAA_BAND) {
      Serial.printf("Set network band %s\r\n", api.lorawan.band.set(OTAA_BAND) ? "Success" : "Fail");
   }

   if (api.lorawan.njm.get() != RAK_LORA_OTAA) {
      Serial.printf("Set network activation mode %s\r\n", api.lorawan.njm.set(RAK_LORA_OTAA) ? "Success" : "Fail");
   }

   if (api.lorawan.adr.get() != true) {
      Serial.printf("Set network ADR %s\r\n", api.lorawan.adr.set(true) ? "Success" : "Fail");
   }

   if (api.lorawan.pnm.get() != true) {
      Serial.printf("Set public network mode %s\r\n", api.lorawan.pnm.set(true) ? "Success" : "Fail");
   }

   if (api.system.lpmlvl.get() != 2U) {
      Serial.printf("Set low power level %s\r\n", api.system.lpmlvl.set(2U) ? "Success" : "Fail");
   }

   if (api.system.lpm.get() != true) {
      Serial.printf("Set low power mode %s\r\n", api.system.lpm.set(1U) ? "Success" : "Fail");
   }
   
   api.lorawan.deui.get(gui8_Device_EUI, 8U);                        // Device EUI
   ui8_NoMatch = 0U;
   for(uint8_t i=0U;i<=7U;i++) {
      if(gui8_Device_EUI[i] != ui8_DEF_Device_EUI[i]) {
         ui8_NoMatch = 1U;
      }
   }
   if(ui8_NoMatch == 1U) {
      Serial.printf("Set Device EUI %s\r\n", api.lorawan.deui.set(ui8_DEF_Device_EUI, 8U) ? "Success" : "Fail");
   }

   api.lorawan.appeui.get(gui8_App_EUI, 8U);                         // App EUI
   ui8_NoMatch = 0U;
   for(uint8_t i=0U;i<=7U;i++) {
      if(gui8_App_EUI[i] != ui8_DEF_App_EUI[i]) {
         ui8_NoMatch = 1U;
      }
   }
   if(ui8_NoMatch == 1U) {
      Serial.printf("Set App EUI %s\r\n", api.lorawan.appeui.set(ui8_DEF_App_EUI, 8U) ? "Success" : "Fail");
   }

   api.lorawan.appkey.get(gui8_App_KEY, 16U);                        // App KEY
   ui8_NoMatch = 0U;
   for(uint8_t i=0U;i<=15U;i++) {
      if(gui8_App_KEY[i] != ui8_DEF_App_KEY[i]) {
         ui8_NoMatch = 1U;
      }
   }
   if(ui8_NoMatch == 1U) {
      Serial.printf("Set App KEY %s\r\n", api.lorawan.appkey.set(ui8_DEF_App_KEY, 16U) ? "Success" : "Fail");
   }

   if (api.lorawan.deviceClass.get() != 0U) {
      Serial.printf("Set device class %s\r\n", api.lorawan.deviceClass.set(0U) ? "Success" : "Fail");
   }

   if (api.lorawan.jn1dl.get() != OTAA_JN1DL) {
      Serial.printf("Set join delay on RX window 1 %s\r\n", api.lorawan.jn1dl.set(OTAA_JN1DL) ? "Success" : "Fail");
   }

   if (api.lorawan.jn2dl.get() != OTAA_JN2DL) {
      Serial.printf("Set join delay on RX window 2 %s\r\n", api.lorawan.jn2dl.set(OTAA_JN2DL) ? "Success" : "Fail");
   }

   Serial.printf("RX1DL before: %d\r\n", api.lorawan.rx1dl.get());
   if (api.lorawan.rx1dl.get() != OTAA_RX1DL) {
      Serial.printf("Set join delay on received window 1 %s\r\n", api.lorawan.rx1dl.set(OTAA_RX1DL) ? "Success" : "Fail");
   }
   Serial.printf("RX1DL after: %d\r\n", api.lorawan.rx1dl.get());

   Serial.printf("RX2DL before: %d\r\n", api.lorawan.rx2dl.get());
   if (api.lorawan.rx2dl.get() != OTAA_RX2DL) {
      Serial.printf("Set join delay on received window 2 %s\r\n", api.lorawan.rx2dl.set(OTAA_RX2DL) ? "Success" : "Fail");
   }
   Serial.printf("RX2DL after: %d\r\n", api.lorawan.rx2dl.get());

}

The code is working as expected, read the parameter, compare and program only in case it is different. To avoid flash memory wearing out. Please, confirm this is the correct way to do it.

But, for the last two comands, RX1DL and RX2DL, the Get value is strange and does not match with the value read via AT command.
I added some Prints before and after for debug reasons:

Serial.printf("RX1DL before: %d\r\n", api.lorawan.rx1dl.get());
   if (api.lorawan.rx1dl.get() != OTAA_RX1DL) {
      Serial.printf("Set join delay on received window 1 %s\r\n", api.lorawan.rx1dl.set(OTAA_RX1DL) ? "Success" : "Fail");
   }
   Serial.printf("RX1DL after: %d\r\n", api.lorawan.rx1dl.get());

   Serial.printf("RX2DL before: %d\r\n", api.lorawan.rx2dl.get());
   if (api.lorawan.rx2dl.get() != OTAA_RX2DL) {
      Serial.printf("Set join delay on received window 2 %s\r\n", api.lorawan.rx2dl.set(OTAA_RX2DL) ? "Success" : "Fail");
   }
   Serial.printf("RX2DL after: %d\r\n", api.lorawan.rx2dl.get());

See the output:

RX1DL before: -994
Set join delay on received window 1 Success
RX1DL after: 5
RX2DL before: 1005
Set join delay on received window 2 Success
RX2DL after: 6

Reading after via AT comands, the results do not match with the Get API:
AT+RX1DL=?
AT+RX1DL=4294966

AT+RX2DL=?
AT+RX2DL=0

When restarting the board, all previous commands are already programmed in the flash and the SET commands are not executed. But for the RX1DL and RX2DL they are always executed…

I tested it with previous FW versions and same problem.

Please, what can be wrong here?

Reading the delays is working for me on RAK3172 RUI3 V4.2.1:

image

What might be confusing (and it is not stated in the API documentation), is that the API calls return the values in milliseconds, while the AT commands return the values in seconds.

Hi @beegee ,

This is indeed confusing. You mean the return values are:
API: Milliseconds
AT: Seconds

What about the inputs, both in seconds?

Anyway, the values I presented above are strange… maybe the input was out of range due to the mentioned differences. I will test again as soon as you confirme about the inputs.

In your print you say: “Setup the device with AT commands first”. Is it really necessary or my Init_LoRa function using API only should work for the first Setup as well?

For the inputs it is the same

API: Milliseconds
AT: Seconds

I never set parameters from the API to keep my code running in all variations
LoRaWAN - LoRa P2P
Any LoRaWAN region

Whatever I set with AT commands is stored in the flash. I need to set them only once.

@beegee ,

I changed the define values to milliseconds:
#define OTAA_JN1DL 5000
#define OTAA_JN2DL 6000
#define OTAA_RX1DL 5000
#define OTAA_RX2DL 6000

I got some Fails during API SET command. Than I wrote the values before via AT commands and now the API GET is working.

I believe this is a BUG, the API SET command should work… that is the purpose of the SET, correct?

I was expecting to not have to use AT commands, since the Init function would do it all via API. Apparently this is not the case.

I got another issue with the MASK read and write. Both, API and AT command, lots of errors printed in the serial and the system freezes. Please, can you test it?

If you enabled automatic join on reboot, the device might be trying to join the network while you issue the commands in setup().

You cannot change certain parameters when the device is in join mode. This is valid for both API and AT commands.

If you want to control all settings from API in your setup routine, disable autojoin (AT+JOIN=0:0 or api.lorawan.join(0,0,10,10);).
Then manually start join after you have changed all settings.

Hi @beegee ,

above you can see my Init_LoRa code, there is no JOIN command. I’m still having trouble with the basic setup.

The first fail messages (from my application) can be due to some timing for the API to get the final return status. Reseting and running again the remaining configurations are successful executed.

Please, did you get the chance to verify the MASK command?
I will try to change the region from LA915 to AU915, just to confirm the issue with the MASK command is not related to the region.

Thank you

Follow an update.
The MASK command does not work when only the LA915 support is selected in the Arduino Board Configuration.

This code was added at the end of the Init_LoRa function, and it crashes completelly! Even when the AT+MASK=? is sent via serial.

#define OTAA_MASK                0x0001UL
uint16_t gui16_ChMask;                    // OTAA Channel Mask

   api.lorawan.mask.get(&gui16_ChMask);
   if (gui16_ChMask != OTAA_MASK) {
      Serial.printf("Set channel mask %s\r\n", api.lorawan.mask.set((uint16_t *)OTAA_MASK) ? "Success" : "Fail");
   }

Changing the selection from LA915 to AU915, it works fine.
Selecting both, LA915 and AU915 support, works fine as well!

It is hard to understand, but in my opinion the LA915 is not complete. It would be very nice if this implementation could be reviewed.
I know you do not have the Gateway/LNS to test it, but at least a code review could be performed.

Thank you

LA915 support is a contribution by the open-source community, it was not added by us. It seems to be broken in RUI3 V4.2.1.

Do you need LA915?

Yes, all public network users in Brazil need the LA915. A code review of this implementation would be great!

I know the network provider Netmore acquires Everynet operations here in south america… Not sure if they will continue with LA915 or change to AU915.

[Netmore Group Continues Global Expansion with the Acquisition of LoRaWAN® Network Operator Everynet | Netmore Group](https://News Netmore)

At the moment, the only option is to go back to RUI3 V4.1.1

Our problem with LA915 is that we have no LoRaWAN server that would support LA915. Neither Chirpstack, TTN, AWS, Actiltiy or any other accessible server I know does support it.
So we can not test and have to rely on the community.

If you search in the forum for LA915, you will find a few threads about this problem.