Join request to cluster-local Join Server failed - Error when sending data to TTN

I am trying to send data to TTN through LoRaWan using the RadioLib. I am using a TTGO LoRa32 device as end Node and a RAK7268 gateway. I have registered the end device on the TTN console and added the proper AppEUI,DevEUI and AppKey.

Initially, since I do not have the NwkKey, I use the AppKey and I am able to join the server. I am able to receive the downlink message. Then when I run the program again with the correct the NwkKey that has been generated by the console, I cannot see the Live data been fed but instead get an error saying “name”: “ns.up.join.cluster.fail” . I am not sure what is wrong because I can confirm that I have entered the keys correctly too.

**EDIT - The message preview says “DevNonce has already been used”

Thank you

Hi @lakindu, two tips that should resolve this problem;

  1. Make sure your device is registered as a LoRaWAN v1.1 device, as that is the version used by RadioLib. When you do that, you will also see a NwkKey appear. The key you used is not a valid OTAA key - it’s a key that is only used in a single session.
  2. The DevNonce error is because the newer versions of LoRaWAN require persistence, i.e. when the device restarts or is reflashed, it should still remember the Nonces. As the way persistence is handled varies greatly between platforms, these examples are not handled within RadioLib, but rather in the repository RadioLib-persistence, linked from the LoRaWAN examples folder in RadioLib.

And then a few more tips:

  1. You have asked many quite different questions over the last couple of weeks. I recommend sticking to one device/setup for a while and learn the basics on LW and the details on the stack (e.g. RadioLib) on that one device first.
  2. Please read all of the Learn section that is linked from the top of the page. Things like the Keys are explained there.
  3. Whenever asking specific questions, please include the code used. Makes it easier to find problems for us, less guesswork.

Please make reading the comprehensive instructions in the notes.md which would have answered both the keys and the DevNonce issues for you - I very much doubt they were written to do anything other than get you started so it is surprising you haven’t taken the time to look at them, as you’ve been asked to do so already on another topic.

And read that Learn section as well!

The people answering here are volunteers with a finite amount of time who have to choose who to spend their energies on - those that help themselves always make more progress faster.

Hello @stevencellist , thank you for your response.

  1. Make sure your device is registered as a LoRaWAN v1.1 device, as that is the version used by RadioLib. When you do that, you will also see a NwkKey appear. The key you used is not a valid OTAA key - it’s a key that is only used in a single session.

I removed my previous end device and created a new one with the LoRawan version 1.1 as you mentioned. However, I get a new error now saying the ‘RADIOLIB-ERR-DWELL_TIME_EXCEEDED(-1114)’ when I try to run the example. The uplink interval is set to 300 seconds by default and I do not understand what the problem is.

I have read the notes.md on the radio.lib and I have enabled the reset DevNonce option as mentioned there too.

Please make reading the comprehensive instructions in the notes.md which would have answered both the keys and the DevNonce issues for you - I very much doubt they were written to do anything other than get you started so it is surprising you haven’t taken the time to look at them, as you’ve been asked to do so already on another topic.

@descartes I do apologize. I read through the notes.md section and I have gone through the instructions but this time I encounter an error that I have not come accross before.

Please refer to point 3:

I am using the LoRaWAN_Starter example in RadioLib, Region is AS923, LoRaWan version 1.1, RP001 Regional Parameters 1.1 revision B and the board that I am using is LoRa32 OLED by Lilygo. Attached below is the code.

LoRaWAN_Starter.ino

#include "config.h"

void setup() {
  Serial.begin(115200);
  while(!Serial);
  delay(5000);  // Give time to switch to the serial monitor
  Serial.println(F("\nSetup ... "));

  Serial.println(F("Initialise the radio"));
  int16_t state = radio.begin();
  debug(state != RADIOLIB_ERR_NONE, F("Initialise radio failed"), state, true);

  // Setup the OTAA session information
  node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);

  Serial.println(F("Join ('login') the LoRaWAN Network"));
  state = node.activateOTAA();
  debug(state != RADIOLIB_LORAWAN_NEW_SESSION, F("Join failed"), state, true);

  Serial.println(F("Ready!\n"));
}

void loop() {
  Serial.println(F("Sending uplink"));

  // This is the place to gather the sensor inputs
  // Instead of reading any real sensor, we just generate some random numbers as example
  uint8_t value1 = radio.random(100);
  uint16_t value2 = radio.random(2000);

  // Build payload byte array
  uint8_t uplinkPayload[3];
  uplinkPayload[0] = value1;
  uplinkPayload[1] = highByte(value2);   // See notes for high/lowByte functions
  uplinkPayload[2] = lowByte(value2);
  
  // Perform an uplink
  int16_t state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));    
  debug((state != RADIOLIB_LORAWAN_NO_DOWNLINK) && (state != RADIOLIB_ERR_NONE), F("Error in sendReceive"), state, false);

  Serial.print(F("Uplink complete, next in "));
  Serial.print(uplinkIntervalSeconds);
  Serial.println(F(" seconds"));
  
  // Wait until next uplink - observing legal & TTN FUP constraints
  delay(uplinkIntervalSeconds * 1000UL);  // delay needs milli-seconds
}

config.h

#ifndef _CONFIG_H
#define _CONFIG_H

#include <RadioLib.h>

// how often to send an uplink - consider legal & FUP constraints - see notes
const uint32_t uplinkIntervalSeconds = 5UL * 60UL;    // minutes x seconds

// joinEUI - previous versions of LoRaWAN called this AppEUI
// for development purposes you can use all zeros - see wiki for details
#define RADIOLIB_LORAWAN_JOIN_EUI  0x0000000000000000

// the Device EUI & two keys can be generated on the TTN console 
#ifndef RADIOLIB_LORAWAN_DEV_EUI   // Replace with your Device EUI
#define RADIOLIB_LORAWAN_DEV_EUI   0x
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY   // Replace with your App Key 
#define RADIOLIB_LORAWAN_APP_KEY  
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY   // Put your Nwk Key here
#define RADIOLIB_LORAWAN_NWK_KEY   

// for the curious, the #ifndef blocks allow for automated testing &/or you can
// put your EUI & keys in to your platformio.ini - see wiki for more tips

// regional choices: EU868, US915, AU915, AS923, IN865, KR920, CN780, CN500
const LoRaWANBand_t Region = AS923;
const uint8_t subBand = 0;  // For US915, change this to 2, otherwise leave on 0

// ============================================================================
// Below is to support the sketch - only make changes if the notes say so ...

// Auto select MCU <-> radio connections
// If you get an error message when compiling, it may be that the 
// pinmap could not be determined - see the notes for more info

// Adafruit
#if defined(ARDUINO_SAMD_FEATHER_M0)
    #pragma message ("Adafruit Feather M0 with RFM95")
    #pragma message ("Link required on board")
    SX1276 radio = new Module(8, 3, 4, 6);


// LilyGo 
#elif defined(ARDUINO_TTGO_LORA32_V1)
  #pragma message ("Using TTGO LoRa32 v1 - no Display")
  SX1276 radio = new Module(18, 26, 14, 33);

#elif defined(ARDUINO_TTGO_LORA32_V2)
   #pragma message ("Using TTGO LoRa32 v2 + Display")
   SX1276 radio = new Module(18, 26, 12, RADIOLIB_NC);

#elif defined(ARDUINO_TTGO_LoRa32_v21new) // T3_V1.6.1
  #pragma message ("Using TTGO LoRa32 v2.1 marked T3_V1.6.1 + Display")
  SX1276 radio = new Module(18, 26, 14, 33);

#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1262)
  #pragma error ("ARDUINO_TBEAM_USE_RADIO_SX1262 awaiting pin map")

#elif defined(ARDUINO_TBEAM_USE_RADIO_SX1276)
  #pragma message ("Using TTGO T-Beam")
  SX1276 radio = new Module(18, 26, 23, 33);


// HelTec: https://github.com/espressif/arduino-esp32/blob/master/variants/heltec_*/pins_arduino.h
#elif defined(ARDUINO_HELTEC_WIFI_LORA_32)
  #pragma message ("Using Heltec WiFi LoRa32")
  SX1276 radio = new Module(18, 26, 14, 33);

#elif defined(ARDUINO_heltec_wifi_lora_32_V2)
  #pragma message ("Using Heltec WiFi LoRa32 v2")
  SX1278 radio = new Module(14, 4, 12, 16);

// Pending verfication of which radio is shipped
// #elif defined(ARDUINO_heltec_wifi_lora_32_V2)
//   #pragma message ("ARDUINO_heltec_wifi_kit_32_V2 awaiting pin map")
//   SX1276 radio = new Module(18, 26, 14, 35);

#elif defined(ARDUINO_heltec_wifi_lora_32_V3)
  #pragma message ("Using Heltec WiFi LoRa32 v3 - Display + USB-C")
  SX1262 radio = new Module(8, 14, 12, 13);
  

// Following not verified  
#elif defined (ARDUINO_heltec_wireless_stick)
  #pragma message ("Using Heltec Wireless Stick")
  SX1278 radio = new Module(14, 4, 12, 16);
  
#elif defined (ARDUINO_HELTEC_WIRELESS_STICK)
  #pragma message ("Using Heltec Wireless Stick")
  SX1276 radio = new Module(18, 26, 14, 35);

#elif defined (ARDUINO_HELTEC_WIRELESS_STICK_V3)
  #pragma message ("Using Heltec Wireless Stick v3")
  SX1262 radio = new Module(8, 14, 12, 13);

#elif defined (ARDUINO_HELTEC_WIRELESS_STICK_LITE)
  #pragma message ("Using Heltec Wireless Stick Lite")
  SX1276 radio = new Module(18, 26, 14, 35);

#elif defined (ARDUINO_HELTEC_WIRELESS_STICK_LITE_V3)
  #pragma message ("Using Heltec Wireless Stick Lite v3")
  SX1262 radio = new Module(34, 14, 12, 13);


// If we don't recognise the board
#else
  #pragma message ("Unknown board - no automagic pinmap available")

  // SX1262  pin order: Module(NSS/CS, DIO1, RESET, BUSY);
  // SX1262 radio = new Module(8, 14, 12, 13);

  // SX1278 pin order: Module(NSS/CS, DIO0, RESET, DIO1);
  // SX1278 radio = new Module(10, 2, 9, 3);
  
  // For Pi Pico + Waveshare HAT - work in progress
  // SX1262 radio = new Module(3, 20, 15, 2, SPI1, RADIOLIB_DEFAULT_SPI_SETTINGS);

#endif

// copy over the EUI's & keys in to the something that will not compile if incorrectly formatted
uint64_t joinEUI =   RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI  =   RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };

// create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);


// result code to text ...
String stateDecode(const int16_t result) {
  switch (result) {
  case RADIOLIB_ERR_NONE:
    return "ERR_NONE";
  case RADIOLIB_ERR_CHIP_NOT_FOUND:
    return "ERR_CHIP_NOT_FOUND";
  case RADIOLIB_ERR_PACKET_TOO_LONG:
    return "ERR_PACKET_TOO_LONG";
  case RADIOLIB_ERR_RX_TIMEOUT:
    return "ERR_RX_TIMEOUT";
  case RADIOLIB_ERR_CRC_MISMATCH:
    return "ERR_CRC_MISMATCH";
  case RADIOLIB_ERR_INVALID_BANDWIDTH:
    return "ERR_INVALID_BANDWIDTH";
  case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
    return "ERR_INVALID_SPREADING_FACTOR";
  case RADIOLIB_ERR_INVALID_CODING_RATE:
    return "ERR_INVALID_CODING_RATE";
  case RADIOLIB_ERR_INVALID_FREQUENCY:
    return "ERR_INVALID_FREQUENCY";
  case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
    return "ERR_INVALID_OUTPUT_POWER";
  case RADIOLIB_ERR_NETWORK_NOT_JOINED:
	  return "RADIOLIB_ERR_NETWORK_NOT_JOINED";

  case RADIOLIB_ERR_DOWNLINK_MALFORMED:
    return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
  case RADIOLIB_ERR_INVALID_REVISION:
    return "RADIOLIB_ERR_INVALID_REVISION";
  case RADIOLIB_ERR_INVALID_PORT:
    return "RADIOLIB_ERR_INVALID_PORT";
  case RADIOLIB_ERR_NO_RX_WINDOW:
    return "RADIOLIB_ERR_NO_RX_WINDOW";
  case RADIOLIB_ERR_INVALID_CID:
    return "RADIOLIB_ERR_INVALID_CID";
  case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
    return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
  case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
    return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
  case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
    return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
  case RADIOLIB_ERR_JOIN_NONCE_INVALID:
    return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
  case RADIOLIB_ERR_N_FCNT_DOWN_INVALID:
    return "RADIOLIB_ERR_N_FCNT_DOWN_INVALID";
  case RADIOLIB_ERR_A_FCNT_DOWN_INVALID:
    return "RADIOLIB_ERR_A_FCNT_DOWN_INVALID";
  case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
    return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
  case RADIOLIB_ERR_CHECKSUM_MISMATCH:
    return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
  case RADIOLIB_LORAWAN_NO_DOWNLINK:
    return "RADIOLIB_LORAWAN_NO_DOWNLINK";
  case RADIOLIB_LORAWAN_SESSION_RESTORED:
    return "RADIOLIB_LORAWAN_SESSION_RESTORED";
  case RADIOLIB_LORAWAN_NEW_SESSION:
    return "RADIOLIB_LORAWAN_NEW_SESSION";
  case RADIOLIB_LORAWAN_NONCES_DISCARDED:
    return "RADIOLIB_LORAWAN_NONCES_DISCARDED";
  case RADIOLIB_LORAWAN_SESSION_DISCARDED:
    return "RADIOLIB_LORAWAN_SESSION_DISCARDED";
  }
  return "See TypeDef.h";
}

// helper function to display any issues
void debug(bool isFail, const __FlashStringHelper* message, int state, bool Freeze) {
  if (isFail) {
    Serial.print(message);
    Serial.print(" - ");
    Serial.print(stateDecode(state));
    Serial.print(" (");
    Serial.print(state);
    Serial.println(")");
    while (Freeze);
  }
}


// helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
  for(uint16_t c = 0; c < len; c++) {
    char b = buffer[c];
    if(b < 0x10) { Serial.print('0'); }
    Serial.print(b, HEX);
  }
  Serial.println();
}


#endif

Thank you.

It’s OK to ask questions that aren’t covered. However it’s polite to show some prior research rather than just copy error messages in the hope of getting 1 on 1 training.

So what does “Dwell time” mean? What did you find out?

As it happens dwell time is shown in one of the pages linked in the notes.md. It’s only notes / a web page - every link was placed there for a reason - have you checked out all the starter materials your were provided with?

Here’s a hint, not all regions allow you to transmit for more than a certain amount of time - which is affected by the Data Rate aka Spreading Factor and the size of the payload. The online calculator in the notes will give you the values you can use.

Hello yes, dwell time is the time allowed per channel to transmit data and in my region it is limited to 400 ms. I have read the notes and as you mentioned, I have checked the online calculator and the spreading factor needs to be between 7-9. If it is from 10-12, the dwell time will be exceeded.

Moreover, I have set the RP001 Regional Parameters 1.1 revision A as asked in the RadioLib notes. On the console Live data, I can see that the SF for the initial uplink is SF10 so I get the error again. I cannot find the place to change the Spreading factor on the code so I would like to know how to go about changing it.

Thank you.

Look at the reference example - it shows how to set the JoinDR aka the SF.

I’m not sure how much AS923 has been exercised - certainly AS915 has.

1 Like

Closing to save duplication with GitHub issue raised: Dwell Time Error - LoRaWAN_Starter Example with AS923 Region · Issue #1180 · jgromes/RadioLib · GitHub

1 Like