RN2903 OTAA Join "denied" on AU915

I am using the @jpmeijers RN2483 Arduino Library and am trying the get OTAA to work successfully with a custom Atmel MEGA328P RN2903 board. I have had this device work successfully with ABP resulting in a join and over 5000 transmissions, which means that there is nothing wrong with range, antennas, my packets, etc.

I am using a slightly adjusted code based heavily ArduinoUnoNano-basic.ino which allows the board to operate successfully in Australia.

My code is as follows:

#include <rn2xx3.h>
#include <AltSoftSerial.h>

AltSoftSerial mySerial;

// create an instance of the rn2xx3 library,
// giving the software serial as port to use
rn2xx3 myLora(mySerial);

// the setup routine runs once when you press reset:
void setup()
{

  // open serial communications and wait for port to open:
  Serial.begin(57600); //serial port to computer
  mySerial.begin(9600); //serial port to radio
  
  Serial.println("It's start'n up mate!");

  initialize_radio();

  myLora.sendRawCommand(F("sys set pindig GPIO0 1"));
  led_on();

  // setting the frequency plan to AU915
  myLora.setFrequencyPlan(TTN_US);

  led_off();
  delay(2000);
}

void initialize_radio()
{
  //reset rn2483
  pinMode(12, OUTPUT);
  digitalWrite(12, LOW);
  delay(500);
  digitalWrite(12, HIGH);

  delay(100); //wait for the RN2xx3's startup message
  mySerial.flush();

  // autobaud the rn2483 module to 9600. The default would otherwise be 57600.
  myLora.autobaud();

  // check communication with radio
  String hweui = myLora.hweui();
  while(hweui.length() != 16)
  {
    Serial.println("Communication with RN2xx3 unsuccessful. Start that baby right up again.");
    Serial.println(hweui);
    delay(10000);
    hweui = myLora.hweui();
  }

  // Setting the frequency plan to AU915
  myLora.setFrequencyPlan(TTN_US);

  // print out the HWEUI so that we can register it via ttnctl
  Serial.println("When using OTAA, register this DevEUI: ");
  Serial.println(myLora.hweui());
  Serial.println("RN2xx3 firmware version:");
  Serial.println(myLora.sysver());

  // configure your keys and join the network
  Serial.println("Trying to join TTN");
  bool join_result = false;

  /*
   * ABP: initABP(String addr, String AppSKey, String NwkSKey);
   * Paste the example code from the TTN console here:
   */
//  const char *devAddr = "KEY";
//  const char *nwkSKey = "KEY";
//  const char *appSKey = "KEY";
//
//  join_result = myLora.initABP(devAddr, appSKey, nwkSKey);

  /*
   * OTAA: initOTAA(String AppEUI, String AppKey);
   * If you are using OTAA, paste the example code from the TTN console here:
   */
  const char *appEui = "KEY";
  const char *appKey = "KEY";

  join_result = myLora.initOTAA(appEui, appKey);

  while(!join_result)
  {
    Serial.println("Unable to join. Are your keys correct and are you in the middle of the outback?");
    delay(30000); //delay a minute before retry
    join_result = myLora.init();
  }
  Serial.println("Successfully joined TTN. You beauty!");

  // Setting the frequency plan to TTN_AU. Not needed for OTAA.
  myLora.setFrequencyPlan(TTN_US);
}

// the loop routine runs over and over again forever:
void loop()
{
    led_on();
    Serial.println("TXing");
    myLora.tx("Testing");
    led_off();
    delay(200);
}

void led_on()
{
  myLora.sendRawCommand(F("sys set pindig GPIO10 1"));
}

void led_off()
{
  myLora.sendRawCommand(F("sys set pindig GPIO10 0"));
}

The credentials I have entered in the TTN console are identical to those in the code and I have also checked to make sure that the Hardware EUI/Device EUI printed in the serial monitor when starting up the board is the same.

When I do an OTAA join, I can see a join request in my gateway’s console but nothing appears in the application or device console. In the device console I have also tested this with and without Frame Counter Checks and the same thing occurs. Below is an output from the console of my gateway:
27%20am

The two payloads are identical for both transmissions. Putting this output in the LoRaWAN 1.0.x packet decoder shows the following:

Assuming hex-encoded packet
00F45201D07ED5B370CCFA23000BA304000F71A146E9E0

Message Type = Join Request
  PHYPayload = 00F45201D07ED5B370CCFA23000BA304000F71A146E9E0

( PHYPayload = MHDR[1] | MACPayload[..] | MIC[4] )
        MHDR = 00
  MACPayload = F45201D07ED5B370CCFA23000BA304000F71
         MIC = A146E9E0

( MACPayload = AppEUI[8] | DevEUI[8] | DevNonce[2] )
      AppEUI = 70B3D57ED00152F4
      DevEUI = 0004A30B0023FACC
    DevNonce = 710F

I have also done some troubleshooting within the library and in rn2xx3.cpp and on line 206 when receivedData is read, the output is denied if I do Serial.println(receivedData);.

I did some research and people have faced this issue before, but not using this library or a similar setup.

If anyone had a suggestion or a way to solve this, I would appreciate it.

When I was doing testing, I made sure that the Device EUI printed in the console was the same as the one I specified in the TTN console.

I have now figured out what happens:

When resetting the frame counts or doing this via changing the App Key (which is what I did to fix it), and then trying powering up board, the board connects to the gateway and therefore TTN. This is also shown through the RN2903 printing out accepted.

If I enable Frame Counter Checks and press the reset button on the board or unplug the micro USB cord, the board will continue transmitting, successfully. It just takes a little while that’s all.

If I disable Frame Counter Checks and press the reset button on the board or I power off the board by unplugging the micro USB cord, the device still connects to TTN without issue.

I do not see a noticeable difference in join time between the two.

Previously, I had the application set such that Frame Counter Checks was disabled and I had to change the App Key to get it working, but I think the major issue was just that I was not patient enough. :upside_down_face:

I believe this issue is the same as one I have had previously, but did not have the knowledge I do now to resolve it, nor did I know what was truely happening. The only difference now is that I have now tested it on OTAA and ABP.

Here is a link to my other post: RN2903 Frame Counter Inconsistency Causing Issues with TTN Console and Accepted Packets

It’s a bit annoying that I have to wait a while as it wastes a bit of power, so I am seeing if anyone would have a reason why join times can take a couple of minutes when the gateway is only about 10 metres from the node?

Just to be sure you grasp the difference: an ABP device does not join. One could say its joins when being programmed, but once you start using it, it does not need to join. Instead, it already knows all the secrets to transmit the uplink right away. However, OTAA implies:

  • Node transmits a Join Request which is hopefully received by one or more gateways (orange icon in TTN Console; for some gateways this icon is only shown in the applications/device’s Data, not in the gateway’s Traffic page).
  • TTN accepting that, as it accepted the AppEUI, DevEUI and validated the MIC.
  • One gateway transmits the Join Accept (green icon in TTN Console, in the gateway’s Traffic page of the gateway that was selected to send the Join Accept; if many gateways received the Join Request, then this might not be your gateway).
  • The device gets the secrets (and for some regions, like EU868, also some network settings) from the OTAA Join Accept.

So: OTAA needs downlink to work too. If ABP works but OTAA does not, then one needs to check both the keys and the downlinks. As for you it works eventually, the keys must be okay. Also, the counters are reset for each OTAA join, so the frame counter check should not have any effect for OTAA.

2 Likes

In LoRaWAN a node does not connect to a gateway, you connect to the network. A gateway does not have the information required to connect to it…

For OTAA the frame counter check does not matter because on JOIN a new session is started. At that time all counters are reset.

2 Likes

Thanks for the clarification. That makes much more sense and clarifies my experience. So is that why connecting via ABP is much quicker and easier than OTAA, because it must received confirmation via the downlink?

Thanks @kersing. Appreciate the reply.

Yes, but OTAA can be as quick as 5 or 6 seconds (RX1 and RX2 delay for a join) too. If OTAA does not succeed in 5 or 6 seconds, then check TTN Console if it was accepted. If true, then assume the Join Accept was transmitted, but that the downlink was not received by the node. Next, the node needs to try again. When trying again, the node might use a higher SF, for which it will also get the downlink on a higher SF, to improve the chances that the Join Request and Join Accept are received. The retry-cycle will take time.

For LMIC, see also MAX_CLOCK_ERROR.

Yes, you are correct. I have got a connect within 10 seconds in my tests, so I wouldn’t be surprised to hear that. Sometimes however this can take a minute or two.

Just curious, when I was testing it now, my console showed the following:

41%20pm

How is it that a Join Request is made a higher SF, being 8 and then a Join Accept is made at a lower SF, being 7 and then uplinks are at an even higher SF, being 10? I would have thought that a Join Request, Join Accept and uplink would have been at the same SF, but I must be mistaken. Could you clarify what is happening and why it happens?

For EU868, the SF would indeed be the same, and I’d expect that for other regions too. But peeking into the specifications for AU915, the SF is indeed different:

…along with:

image

I’ve not tried to understand those… TTN might be wrong what does it say for a Join Accept that is actually received well by your node? but as it seems to work, I guess it’s okay as the node agrees with this… (Also, it might use a higher transmission power for the downlink, just like TTN does for RX2 in EU868, but that’s just a wild guess.)

1 Like

Thanks mate. I still need to wrap my head around this stuff, but I’ll be sure to have a look at it.

Those use a smaller bandwidth, BW125. Apparently all according to specifications, if things work… Life is much easier in EU868 :slight_smile:

Peeking at https://www.thethingsnetwork.org/docs/lorawan/frequency-plans.html#au915-928, specifically:

  • No mention of BW500 (500 kHz bandwidth) for uplinks, though used and received in your case:

    41%20pm

  • The note:

    Note that The Things Network uses 2nd Sub-Band only (channels 8 to 15 and 65). You’ll need to program the specific channels into the devices in order to make them work with TTN.

…makes me wonder: any chance your gateway settings are not 100% okay for TTN? What gateway are you using? With what settings?

Also, according to the AU915 specifications:

If using the over-the-air activation procedure, the end-device should broadcast the JoinReq message alternatively on a random 125 kHz channel amongst the 64 channels defined using DR0 and a random 500 kHz channel amongst the 8 channels defined using DR6. The end device should change channel for every transmission.

So, unless the device is already aware of TTN specifics, then with a basic 8 channel gateway, it might take some time for the device to hit one of the channels that the gateway is even listening to, which might be a better explaination of the long time it needs to join.

1 Like

Thanks for the investigation work. :male_detective: I would never have found that.

The gateway I’m using is the LoRaGO PORT. It is a Raspberry Pi 3 with a LoRaWAN shield on top.

Here are a few links to it:

Main page describing it:
https://sandboxelectronics.com/?product=lorago-port-multi-channel-lorawan-gateway

Installation instructions:
http://sandboxelectronics.com/?p=2696

For my installation in Australia, when the installation was successfully completed, TTN displayed the gateway as online, however connecting to it with a node was not possible. This was due to the software being designed for EU frequencies which operate differently to those in Australia. This issue was resolved by replacing /opt/ttn-gateway/bin/global_conf.json with the AU-global_conf.json file and renaming it to global_conf.json which is available from:

My bad, there is one, and that’s exaclty the one that is used:

  1. 917.5 SF8BW500

I guess the downlink settings that go with that are somehow in the specifications too, as things work for you… In the table I posted earlier above, SF8BW500 matches both DR6 and DR12, and DR6 then indeed maps to DR13 (SF7BW500) when RX1DROffset is 0. Which it must be then…

I have not come across data rates very often, so I was seeing if you could clarify what is meant by the charts you posted.

Let’s start with the second chart, because it makes more sense to me at least:

image

So we have four things:

  • DataRate
  • Spreading factor
  • Bandwidth
  • Bit Rate

This is my current understanding of the situation. Please correct me if I am wrong.

For each data rate, from 0 to 15 there is a unique SF and bandwidth called a “configuration” for both uplinks and downlinks, uplinks being 125 kHz and 500 kHz being downlinks. As the SF decreases the bit rate increases, as expected.

So for each channel, there is a unique corresponding data rate.

I do have a few questions relating to this:

  • Where do channels fit into this? Are these the DataRate?
  • What does RFU mean and what is its purpose?
  • Why is there a single SF8 500 kHz uplink channel and why have it altogether considering the downlinks don’t have it? I’ve seen this before on this page, but there was no justification.

And for the first chart you posted, I am completely lost. Would you be able to clarify what it means? I’m trying to figure out what it is trying to say, but I don’t get it. I do see the mention of the data rate again, however what relationship does this have with the second chart?

image

See https://www.thethingsnetwork.org/docs/lorawan/#modulation-and-data-rate

RFU = Reserved for future use :slight_smile:

As for the “table 39” (incorrectly referenced as “table 16 below” as that was just copied from the US915 specification in the same document):

  • Columns “0” thru “5” go with a specific value for RX1DROffset (which given your screenshot for the Join Request and Join Accept apparently is 0 or 1 for TTN, as DR6 maps to DR13; I’ve not investigated where that RX1DROffset is defined).
  • So, an uplink using DR2 will yield a downlink of DR10 (if RX1DROffset = 0) or DR9 (if RX1DROffset = 1) in RX1, and an uplink using DR6 will use DR13 for a dowlink in RX1.
  • The first table then shows that DR13 is SF7BW500, and so on.
  • SF8BW500 is known as both DR6 and DR12, which is a bit weird (but explicitly documented as being correct). DR12 is not mentioned in table 39, but DR6 is.
1 Like

That’s making a bit more sense.

So if I’m not mistaken that chart shows the corresponding uplink data rates for downlinks and vice versa.

What I do have are a few more question if you wouldn’t mind answering them:

  • What is the difference between a channel and a data rate?
  • What is the purpose of DR6? I understand DR13, but considering it is a different bandwidth to the other downlinks (125 kHz vs 500 kHz), already present in the uplinks and seemingly doubling up in downlinks, it doesn’t make much sense.
  • You said “apparently 0 or 1 is for TTN”. What are the other downstream data rates used for?