Join not accepted: denied with Sodaq Explorer

I’m working with the Sodaq Explorer board and trying to connect it to a nearby Gateway. When using the
SendOTAA sketch I get this message in the Serial Monitor:

Sending: mac join otaa 
Join not accepted: denied

and

Sending: mac join otaa 
Response is not OK: no_free_ch

But when I’m running the Simple LoRa sketch from the Sodaq website, packets are send successfully to the TTN network.

Anyone have any clue as to why the first sketch does not work?

N.B.'s:
The Simple LoRa sketch is in effect a sketch for the Sodaq ONE board.

The TTN SendOTAA sketch uses:
#include <TheThingsNetwork.h>

The Simple LoRa sketch sketch uses:
#include “Arduino.h”
#include <Sodaq_RN2483.h>

Keys are OK and Gateway is in within range.

this is not enough info to ‘debug’

  • show output of your TTN application console when device is joining (trying too)
  • show your full FORMATTED sketch or a link to it
  • what type of gateway do you use (you don’t ‘connect’ to a gateway- it’s not wifi)
  • what are the used antenna’s and what is the distance between GW and node

@BoRRoZ
Thanks for your reply. Here you go!

  • show output of your TTN application console when device is joining (trying too)

The output of the sketch in Serial Monitor

Click to see the full output
-- STATUS
EUI: 0004A30B001F9A2B
Battery: 3325
AppEUI: 70B3D57ED00168DA
DevEUI: 0004A30B001F9A2B
Data Rate: 0
RX Delay 1: 1000
RX Delay 2: 2000
-- JOIN
Model: RN2483
Version: 1.0.4
Sending: mac set deveui 0004A30B001F9A2B
Sending: mac set adr off
Sending: mac set deveui 0004A30B001F9A2B
Sending: mac set appeui 70B3D57ED00168DA
Sending: mac set appkey D861DB7C58D63473D48A6887FAD93A68
Sending: mac save 
Sending: mac set rx2 3 869525000
Sending: mac set ch drrange 1 0 6
Sending: mac set ch dcycle 0 799
Sending: mac set ch dcycle 1 799
Sending: mac set ch dcycle 2 799
Sending: mac set ch dcycle 3 799
Sending: mac set ch freq 3 867100000
Sending: mac set ch drrange 3 0 5
Sending: mac set ch status 3 on
Sending: mac set ch dcycle 4 799
Sending: mac set ch freq 4 867300000
Sending: mac set ch drrange 4 0 5
Sending: mac set ch status 4 on
Sending: mac set ch dcycle 5 799
Sending: mac set ch freq 5 867500000
Sending: mac set ch drrange 5 0 5
Sending: mac set ch status 5 on
Sending: mac set ch dcycle 6 799
Sending: mac set ch freq 6 867700000
Sending: mac set ch drrange 6 0 5
Sending: mac set ch status 6 on
Sending: mac set ch dcycle 7 799
Sending: mac set ch freq 7 867900000
Sending: mac set ch drrange 7 0 5
Sending: mac set ch status 7 on
Sending: mac set pwridx 1
Sending: mac set retx 7
Sending: mac set dr 5
Sending: mac join otaa 
Join not accepted: denied
Check your coverage, keys and backend status.
Sending: mac join otaa 
Join not accepted: denied
Check your coverage, keys and backend status.
Sending: mac join otaa 
Join not accepted: denied
Check your coverage, keys and backend status.
Sending: mac join otaa 
Response is not OK: no_free_ch
Send join command failed
Sending: mac join otaa 
Response is not OK: no_free_ch
Send join command failed
Sending: mac join otaa 
Response is not OK: no_free_ch

The output of TTN Console

lora_ttn_console

  • show your full FORMATTED sketch or a link to it

Simple LoRa sketch

Click to see the full code
/*
 * Compatible with:
 * SODAQ MBILI
 * SODAQ Autonomo
 * SODAQ ONE
 * SODAQ ONE BETA
 * SODAQ EXPLORER
 */

#include "Arduino.h"
#include <Sodaq_RN2483.h>

#define debugSerial SERIAL_PORT_MONITOR

#if defined(ARDUINO_AVR_SODAQ_MBILI)
#define loraSerial Serial1
#define BEE_VCC 20

#elif defined(ARDUINO_SODAQ_AUTONOMO) || defined(ARDUINO_SODAQ_ONE) || defined(ARDUINO_SODAQ_ONE_BETA)
#define loraSerial Serial1

#elif defined(ARDUINO_SODAQ_EXPLORER)
#define loraSerial Serial2

#else
// please select a sodaq board
debugSerial.println("Please select a sodaq board!!");
#endif

// ABP
const uint8_t devAddr[4] = { 0x00, 0x00, 0x00, 0x00 };
const uint8_t appSKey[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
const uint8_t nwkSKey[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };

// OTAA
uint8_t DevEUI[8] = { 0x00, 0x04, 0xA3, 0x0B, 0x00, 0x1F, 0x9A, 0x2B };
uint8_t AppEUI[8] = { 0x70, 0xB3, 0xD5, 0x7E, 0xD0, 0x01, 0x68, 0xDA };
uint8_t AppKey[16] = { 0xD8, 0x61, 0xDB, 0x7C, 0x58, 0xD6, 0x34, 0x73, 0xD4, 0x8A, 0x68, 0x87, 0xFA, 0xD9, 0x3A, 0x68 };

void setupLoRaABP(){  
  if (LoRaBee.initABP(loraSerial, devAddr, appSKey, nwkSKey, false))
  {
    debugSerial.println("Communication to LoRaBEE successful.");
  }
  else
  {
    debugSerial.println("Communication to LoRaBEE failed!");
  }
}

void setupLoRaOTAA(){
  if (LoRaBee.initOTA(loraSerial, DevEUI, AppEUI, AppKey, false))
  {
    debugSerial.println("Communication to LoRaBEE successful.");
  }
  else
  {
    debugSerial.println("OTAA Setup failed!");
  }
}

void setup() {
  //Power up the LoRaBEE
  #if defined(ARDUINO_AVR_SODAQ_MBILI) || defined(ARDUINO_SODAQ_AUTONOMO)
  pinMode(BEE_VCC, OUTPUT);
  digitalWrite(BEE_VCC, HIGH);
  #endif
  delay(3000);

  while ((!SerialUSB) && (millis() < 10000)){
    // Wait 10 seconds for the Serial Monitor
  }

  //Set baud rate
  debugSerial.begin(57600);
  loraSerial.begin(LoRaBee.getDefaultBaudRate());

  // Debug output from LoRaBee
  // LoRaBee.setDiag(debugSerial); // optional

  //connect to the LoRa Network
  setupLoRa();
}

void setupLoRa(){
  // ABP
//  setupLoRaABP();
  // OTAA
  setupLoRaOTAA();
  LoRaBee.setSpreadingFactor(9);
}

void sendPacket(String packet){
  switch (LoRaBee.send(1, (uint8_t*)packet.c_str(), packet.length()))
    {
    case NoError:
      debugSerial.println("Successful transmission.");
      break;
    case NoResponse:
      debugSerial.println("There was no response from the device.");
      setupLoRa();
      break;
    case Timeout:
      debugSerial.println("Connection timed-out. Check your serial connection to the device! Sleeping for 20sec.");
      delay(20000);
      break;
    case PayloadSizeError:
      debugSerial.println("The size of the payload is greater than allowed. Transmission failed!");
      break;
    case InternalError:
      debugSerial.println("Oh No! This shouldn't happen. Something is really wrong! Try restarting the device!\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case Busy:
      debugSerial.println("The device is busy. Sleeping for 10 extra seconds.");
      delay(10000);
      break;
    case NetworkFatalError:
      debugSerial.println("There is a non-recoverable error with the network connection. You should re-connect.\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case NotConnected:
      debugSerial.println("The device is not connected to the network. Please connect to the network before attempting to send data.\r\nThe network connection will reset.");
      setupLoRa();
      break;
    case NoAcknowledgment:
      debugSerial.println("There was no acknowledgment sent back!");
      // When you this message you are probaly out of range of the network.
      break;
    default:
      break;
    }
}

void loop() {
  // put your main code here, to run repeatedly:
  String packet = "SODAQ";
  sendPacket(packet);

  delay(10000);
}

SendOTAA sketch

Click to see the full code
#include <TheThingsNetwork.h>


// Set your AppEUI and AppKey
const char *appEui = "70B3D57ED00168DA";
const char *appKey = "D861DB7C58D63473D48A6887FAD93A68";

#define loraSerial Serial2
#define debugSerial SerialUSB

// Replace REPLACE_ME with TTN_FP_EU868 or TTN_FP_US915
#define freqPlan TTN_FP_EU868

TheThingsNetwork ttn(loraSerial, debugSerial, freqPlan);

void setup()
{
  loraSerial.begin(57600);
  debugSerial.begin(9600);

  // Wait a maximum of 10s for Serial Monitor
  while (!debugSerial && millis() < 10000)
    ;

  debugSerial.println("-- STATUS");
  ttn.showStatus();

  debugSerial.println("-- JOIN");
  ttn.join(appEui, appKey);
  ttn.onMessage(message);
  pinMode(LED_BUILTIN, OUTPUT);
}

void loop()
{
  uint16_t temp = getTemperature();
   
  byte payload[2];
  payload[0] = highByte(temp);
  payload[1] = lowByte(temp);

  ttn.sendBytes(payload, sizeof(payload));

  // Delay between readings - 10 000 = 10 secons
  delay(10000);
}

uint16_t getTemperature()
{
  //10mV per C, 0C is 500mV
  float mVolts = (float)analogRead(TEMP_SENSOR) * 3300.0 / 1023.0;
  int temp = (mVolts - 500) * 10;
  
  debugSerial.print((mVolts - 500) / 10);
  debugSerial.println(" Celcius");
  return int(temp);
  
}

void message(const uint8_t *payload, size_t size, port_t port) {
  if (payload[0] == 0) {
    digitalWrite(LED_BUILTIN, LOW);
  } else if (payload[0] == 1) {
    digitalWrite(LED_BUILTIN, HIGH);
  }
}
  • what type of gateway do you use (you don’t ‘connect’ to a gateway- it’s not wifi)
    I don’t know the type of gateway, it’s a public one.
    Yeah, yeah, I know you don’t connect. Messages are passed by the gateway to TTN, where they are refused a join.

  • what are the used antenna’s and what is the distance between GW and node
    Which antenna’s are you referring to? The Sodaq Explorer board has an embedded (PCB) LoRa antenna, that’s all I can find on the Sodaq website.The gateway’s antenna is unknown to me.
    Distance between gateway and node is 500 meter

P.S.: I leave the keys in the code/output for clarity. Will change them shortly.

1 Like

well done… have a look later today

Just found a confusing difference in the join requests between the two sketches in the TTN Console.
With the SendOTAA sketch join requests, the dev addr keeps changing.
With the Simple LoRa sketch (single) join request the dev addr is the same as can be seen in the Device Overview.

N.B.: in the SendOTAA sketch no dev addr is specified. However, in the Simple LoRa sketch it is specified.

dev-addr

for OTAA the dev adress changes (for ABP it’s always the same)

see https://www.thethingsnetwork.org/docs/lorawan/address-space.html

traffic

Just to be sure: an OTAA device should not re-join for each uplink; see for example:

1 Like

I was just writing this (hope I didn’t make a mistake… Arjan is watching :roll_eyes:
Supprised that TTN is no longer mentioned on their site… :open_mouth:

If you are not within The Things Network coverage area your device will not connect and transmit data to the The Things Network platform.

! - http://docs.microshare.io/docs/1/advanced/lorawan-devices/sodaq_explorer/#ttn-sodaq-explorer-arduino-sketchcode

1 - what you can do to check if the application and your device is registered without a problem in general is simulating a datapacket :

  • open a browser window with :

console / applications / your application / data

and leave this page open !

  • open another browser window in a second TAB with :

console / applications / devices / your device / overview

bottom page ’ simulate uplink ’
select a port e.g 2
set a Payload e.g FF FF

and press SEND

now go back to the first page and there you should see the payload you send.

2 -

…but I actually only read your last post, @koennetwork, so I missed that you’re getting a join error. Such error should only occur for OTAA, which needs a Join Request to be received by one or more gateways, and the Join Accept to be transmitted by one gateway and received by the node. So, the numerous OTAA attempts might just be caused by the device not receiving the OTAA Join Accept for some reason.

In other words: maybe the device will actually only join once, if it succeeds, in which case my previous references don’t make much sense.

Seeing the OTAA join in the application data implies that the device has the correct settings, and that TTN accepts those. With incorrect settings, TTN would not know to which application the device belongs.

If you click on the join message, you might see some details about the gateway. Given its id you can get more details, for example from http://noc.thethingsnetwork.org:8085/api/v2/gateways or http://noc.thethingsnetwork.org:8085/api/v2/gateways/the-gateway-id

Tested: all OK.

But when using the Simple LoRa sketch, the OTAA join is accepted by TTN and a join response is received by the device. Furthermore, data can then be send to the TTN servers.
As you might have noticed, the Simple LoRa sketch uses these libraries:

#include "Arduino.h"
#include <Sodaq_RN2483.h>

And the SendOTAA sketch uses:

#include <TheThingsNetwork.h>

It is my guess, that this is the cause of the problem, although I still don’t understand why the SendOTAA sketch won’t work.

Found this for the gateway in Haarlem:

“eui-0000024b080606d8”:{“timestamp”:“2019-01-18T23:42:09.650702719Z”,“uplink”:“723433”,“downlink”:“2650”,“location”:{“latitude”:52.38169,“longitude”:4.6297584,“altitude”:12},“frequency_plan”:“EU_863_870”,“platform”:“Kerlink IoT Station”,“gps”:{“latitude”:52.38169,“longitude”:4.6297584,“altitude”:12},“time”:“1547854929650702719”,“rx_ok”:723433,“tx_in”:2650}

did you try to add


#include <TheThingsNetwork.h>
#include <Sodaq_RN2483.h>

another thing is. use the latest rn2483 firmware, if necessary upgrade
for more info see http://forum.sodaq.com/c/explorer

Ah, that one is provided by Sodaq itself (and you’re using it for OTAA), but the other is based on an example provided by the Things Network, for their arduino-device-lib.

To summarize:

For both libraries you’re seeing OTAA joins in TTN Console. OTAA works with the Sodaq library, so we know that the gateway and the settings in TTN Console seem fine. (And the Haarlem gateway is a full-blown gateway.) The keys in both sketches seem to match (the TTN library takes the DevEUI from the RN2483, but that looks good too, and as the failing join is still shown in TTN Console, TTN accepts the configuration). So the handling in the backend should be the same for both sketches, if the Join Requests are simular.

Maybe the SF used for the Join Request (and hence for the Join Accept) is different; click the entry in TTN Console to see and compare the details. If it’s SF12:

However, I guess it’s not SF12:

…which shows TTN’s library starts with SF7 (data rate 5). Maybe the Sodaq library starts with a higher SF? (Longer air time, better reach.)

It might also help to know if the Join Accepts for both libraries are sent in RX1 (5 seconds after the Join Request) or RX2 (6 seconds), which might be different if they use a different SF. For RX1, TTN will use the same SF as the Join Request, so SF7, which somehow might not be received by the device.

In the TTN library you can change the default SF using the constructor’s optional parameters:

TheThingsNetwork ttn(Stream& modemStream, Stream& debugStream, fp_ttn_t fp,
   uint8_t sf = 7, uint8_t fsb = 2);

I also wonder if some settings in the RN2483 are configured differently for both libraries, while it seems that the TTN library does not reset it to its factory state first (at least: the log does not show that), somehow affecting its ability to receive the Join Accept? Using the Soday “LoRa Serial Passthrough” sketch you could issue sys reset, but maybe that’s really the same as a reset caused by a power cycle/programming.

I added #include <Sodaq_RN2483.h> but, as expected, it made no difference. If the Sodaq_RN2483 library would have been used by the sketch and it was not included, the sketch would have thrown a compilation error.

It’s indeed SF7, but the specific Haarlem gateway just got an SF12 too. I’d assume you started with the TTN library’s version? Is the SF12 the Sodaq version?

image

…where only the SF12 version also shows uplinks, using SF9:

image

I’m thinking also of a factory reset for the module ’ sys factoryReset’

and delete TTN device and application
then register again with different names.

I’m quite sure deleting and re-registering is not needed; all is fine for one sketch, but not for the other. So as for TTN, the handling should be the same, if the Join Requests are alike. The difference must be in the Join Requests, which I think is what the gateway’s Traffic shows as well.

(Or in the device’s libraries, but not caused by TTN, I think.)

because he stated that it worked before… so I’m thinking there must be a setting somewhere
in this sodaq otaa example they use include <Sodaq_RN2483.h> only

Could be a setting in the RN2483 indeed, but not anything related to TTN Console, I think.