Unable to get RAK3172 to join LoRa network!

Hi

I have a RAK3172 installed on a Wisblock board and 3 sensors on it. I have flashed it previously with sample code from Rak to handle sensors and it was joining LoRa network well and reporting sensors without any problems.
Now I try to use that same module for an other project (transmission of serial data through LoRa).
I have flashed in it the LoRa OTAA sample code for RAK3172 using VSCode and so far all good. Code transfers fine and I can send a AT+JOIN command to the rak3172 module.
Unhappy when I send the AT command to RUI, it first answers with OK as usual and then few seconds later I get that:
+EVT:JOIN_FAILED_RX_TIMEOUT
Only modification I have done in sample code is to be sure it’s well on EU868 band and to fill the APPEUI, DevEUI, and APPKEY.
I see well the JOIN request received on my LoRa GW but TTN doesn’t accept it as if had made some mistakes on the LoRa identifiers. I reused some identifiers I was using with previous code on that same board.
Any idea what can be wrong ?
I tried also the fill the identifiers in LSB and MSB mode but no changes at all :frowning:

Thanks

Vincèn

Hi Vincen,

Try to disable automatic join with AT+JOIN=0:0
The example code is calling api.lorawan.join(). If the device has already joined before (because automatic join was enabled), it will try to rejoin again. This can lead to a reuse of the Join DevNonce which will cause an error on the LNS.

An application should either use automatic join or the API function. Not both.

You could change the example code to

if (api.lorawan.njs.get() == 0)
{
	// Not yet joined, start join, enable automatic join, set interval of join trials to 10 seconds and retry 50 times before giving up
	api.lorawan.join(1, 1, 10, 50);
}

Hi @beegee

Thanks a lot for your message. I have disabled automatic join as you indicated and then did an ATZ to reset MCU and discovered I have an other problem. It states that in console:

LoRaWan OTAA - set band is incorrect!

although I think I have setup it properly in code and that the module sends well LoRa packets on EU868 as I see them in my gw :slight_smile:

For the join I’m quite confused as I have searched in code but found no command to do a JOIN. RUI3 is doing a JOIN by default at startup ?
the parameters modified using AT commands are permanent ? or they don’t survive a reset of module or reload of program in the device ?

Also something very strange: i have done some modifications in the DEVEUI as I had done a syntax error in it (one character different of the one setup in TTN console) but module doesn’t take the modification. LoRa messages sent are always with all DEVEUI although compilation and download of program in module is going well !

Vincèn

Copy of code just to be sure we are talking about the same :wink:

/***
 *  This example shows LoRaWan protocol joining the network in OTAA mode, class A, region EU868.
 *  Device will send uplink every 5 minutes.
***/

#define OTAA_PERIOD   (300000)
/*************************************

   LoRaWAN band setting:
     RAK_REGION_EU433
     RAK_REGION_CN470
     RAK_REGION_RU864
     RAK_REGION_IN865
     RAK_REGION_EU868
     RAK_REGION_US915
     RAK_REGION_AU915
     RAK_REGION_KR920
     RAK_REGION_AS923

 *************************************/
#define OTAA_BAND     (RAK_REGION_EU868)
#define OTAA_DEVEUI   {0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x09, 0x61, 0x7B}
#define OTAA_APPEUI   {0xAC, 0x1F, 0x09, 0xFF, 0xF8, 0x68, 0x31, 0x72}
#define OTAA_APPKEY   {0xAC, 0x1F, 0x09, 0xFF, 0xFE, 0x09, 0x61, 0x7B, 0xAC, 0x1F, 0x09, 0xFF, 0xF8, 0x68, 0x31, 0x72}

/** Packet buffer for sending */
uint8_t collected_data[64] = { 0 };

void recvCallback(SERVICE_LORA_RECEIVE_T * data)
{
    if (data->BufferSize > 0) {
        Serial.println("Something received!");
        for (int i = 0; i < data->BufferSize; i++) {
            Serial.printf("%x", data->Buffer[i]);
        }
        Serial.print("\r\n");
    }
}

void joinCallback(int32_t status)
{
    Serial.printf("Join status: %d\r\n", status);
}

/*************************************
 * enum type for LoRa Event
    RAK_LORAMAC_STATUS_OK = 0,
    RAK_LORAMAC_STATUS_ERROR,
    RAK_LORAMAC_STATUS_TX_TIMEOUT,
    RAK_LORAMAC_STATUS_RX1_TIMEOUT,
    RAK_LORAMAC_STATUS_RX2_TIMEOUT,
    RAK_LORAMAC_STATUS_RX1_ERROR,
    RAK_LORAMAC_STATUS_RX2_ERROR,
    RAK_LORAMAC_STATUS_JOIN_FAIL,
    RAK_LORAMAC_STATUS_DOWNLINK_REPEATED,
    RAK_LORAMAC_STATUS_TX_DR_PAYLOAD_SIZE_ERROR,
    RAK_LORAMAC_STATUS_DOWNLINK_TOO_MANY_FRAMES_LOSS,
    RAK_LORAMAC_STATUS_ADDRESS_FAIL,
    RAK_LORAMAC_STATUS_MIC_FAIL,
    RAK_LORAMAC_STATUS_MULTICAST_FAIL,
    RAK_LORAMAC_STATUS_BEACON_LOCKED,
    RAK_LORAMAC_STATUS_BEACON_LOST,
    RAK_LORAMAC_STATUS_BEACON_NOT_FOUND,
 *************************************/

void sendCallback(int32_t status)
{
    if (status == RAK_LORAMAC_STATUS_OK) {
        Serial.println("Successfully sent");
    } else {
        Serial.println("Sending failed");
    }
}

void setup()
{
    Serial.begin(115200, RAK_AT_MODE);
    delay(2000);

    Serial.println("RAKwireless LoRaWan OTAA Example");
    Serial.println("------------------------------------------------------");

    if(api.lorawan.nwm.get() != 1)
    {
        Serial.printf("Set Node device work mode %s\r\n",
            api.lorawan.nwm.set(1) ? "Success" : "Fail");
        api.system.reboot();
    }

    // OTAA Device EUI MSB first
    uint8_t node_device_eui[8] = OTAA_DEVEUI;
    // OTAA Application EUI MSB first
    uint8_t node_app_eui[8] = OTAA_APPEUI;
    // OTAA Application Key MSB first
    uint8_t node_app_key[16] = OTAA_APPKEY;

    if (!api.lorawan.appeui.set(node_app_eui, 8)) {
        Serial.printf("LoRaWan OTAA - set application EUI is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.appkey.set(node_app_key, 16)) {
        Serial.printf("LoRaWan OTAA - set application key is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.deui.set(node_device_eui, 8)) {
        Serial.printf("LoRaWan OTAA - set device EUI is incorrect! \r\n");
        return;
    }

    if (!api.lorawan.band.set(OTAA_BAND)) {
        Serial.printf("LoRaWan OTAA - set band is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.deviceClass.set(RAK_LORA_CLASS_A)) {
        Serial.printf("LoRaWan OTAA - set device class is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.njm.set(RAK_LORA_OTAA))	// Set the network join mode to OTAA
    {
        Serial.printf("LoRaWan OTAA - set network join mode is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.join())	// Join to Gateway
    {
        Serial.printf("LoRaWan OTAA - join fail! \r\n");
        return;
    }

    /** Wait for Join success */
    while (api.lorawan.njs.get() == 0) {
        Serial.print("Wait for LoRaWAN join...");
        api.lorawan.join();
        delay(10000);
    }

    if (!api.lorawan.adr.set(true)) {
        Serial.printf("LoRaWan OTAA - set adaptive data rate is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.rety.set(1)) {
        Serial.printf("LoRaWan OTAA - set retry times is incorrect! \r\n");
        return;
    }
    if (!api.lorawan.cfm.set(1)) {
        Serial.printf("LoRaWan OTAA - set confirm mode is incorrect! \r\n");
        return;
    }

    /** Check LoRaWan Status*/
    Serial.printf("Duty cycle is %s\r\n", api.lorawan.dcs.get()? "ON" : "OFF");	// Check Duty Cycle status
    Serial.printf("Packet is %s\r\n", api.lorawan.cfm.get()? "CONFIRMED" : "UNCONFIRMED");	// Check Confirm status
    uint8_t assigned_dev_addr[4] = { 0 };
    api.lorawan.daddr.get(assigned_dev_addr, 4);
    Serial.printf("Device Address is %02X%02X%02X%02X\r\n", assigned_dev_addr[0], assigned_dev_addr[1], assigned_dev_addr[2], assigned_dev_addr[3]);	// Check Device Address
    Serial.printf("Uplink period is %ums\r\n", OTAA_PERIOD);
    Serial.println("");
    api.lorawan.registerRecvCallback(recvCallback);
    api.lorawan.registerJoinCallback(joinCallback);
    api.lorawan.registerSendCallback(sendCallback);
}

void uplink_routine()
{
    /** Payload of Uplink */
    uint8_t data_len = 0;
    collected_data[data_len++] = (uint8_t) 't';
    collected_data[data_len++] = (uint8_t) 'e';
    collected_data[data_len++] = (uint8_t) 's';
    collected_data[data_len++] = (uint8_t) 't';

    Serial.println("Data Packet:");
    for (int i = 0; i < data_len; i++) {
        Serial.printf("0x%02X ", collected_data[i]);
    }
    Serial.println("");

    /** Send the data package */
    if (api.lorawan.send(data_len, (uint8_t *) & collected_data, 2, true, 1)) {
        Serial.println("Sending is requested");
    } else {
        Serial.println("Sending failed");
    }
}

void loop()
{
    static uint64_t last = 0;
    static uint64_t elapsed;

    if ((elapsed = millis() - last) > OTAA_PERIOD) {
        uplink_routine();

        last = millis();
    }
    //Serial.printf("Try sleep %ums..", OTAA_PERIOD);
    api.system.sleep.all(OTAA_PERIOD);
    //Serial.println("Wakeup..");
}

The api.lorawan.join() call is in line 132, assuming you used the LoRaWan_OTAA.ino example.

LoRaWan OTAA - set band is incorrect! will be thrown if

  • the device is already trying to join
  • the band is wrong

Not sure which one it is in your case.

/***************************** IMHO **********************************/
I don’t like these examples and I never use them.

Personally, I never setup LoRaWAN credentials from my code.
Device setup is always made with AT commands, because the settings are saved in flash and they need to be done only once. There is no need to set them every time in the application code.
/***************************** IMHO END ******************************/

To tell you what’s the reason for the error message I need the complete log output from the device.

  1. Double-Check Identifiers: Ensure that the DevEUI, AppEUI, and AppKey on the RAK3172 module precisely match those in The Things Network (TTN). Even slight differences will prevent successful joining.
  2. Encoding Format: Confirm that the identifiers are correctly formatted. TTN often expects the DevEUI and AppEUI in MSB format, while AppKey is usually LSB. Double-check these and try both formats if unsure.
  3. Network Band Configuration: Ensure the module is set to the correct frequency band (EU868). Use the command AT+Band=EU868 to confirm.
  4. Confirm Module Firmware: Some firmware versions have different handling of join requests. Consider updating to the latest firmware if not already done.
  5. Debug Logs: Use debugging tools or check TTN’s logs to view additional information about join requests and rejections.