RN2903 Frame Counter Inconsistency Causing Issues with TTN Console and Accepted Packets

On TTN, if I create a new application and device for my LoRaWAN RN2903 node, and replicate this in my code which uses the RN2483-Arduino-Library by jpmeijers, LoRaWAN data transmissions work without issue.

However, if I power off my node and reconnect it to TTN, the gateway receives data transmissions via the TTN gateway data console, however under the data section of the console for my device (node,) no data is presented. It is only when I reset the frames counter for the node and restart the node that I see data in the node console again.

Alternatively, this can be resolved by specifying a new “App Session Key” and “Network Session Key” in TTN and replicating it in the code.

I have tested this node on three different gateways and the same problem arises, therefore it has to be an issue related to the node or TTN.

From my understanding, the device when unplugged “loses” or doesn’t remember the number of frames it has sent, leading to an inconsistency between the TTN and my node meaning the packets won’t be accepted. This is likely why I’m not seeing the data in the node’s console, but am in the gateway because the gateway’s console only reports on what it sees, not if it is accepted.

I have not had similar problems with other nodes such as the TTGO SX1276 ESP32 which even though is different hardware does use the Arduino IDE.

Is there a way to prevent needing to reset my frame counter every time I’m wanting to power off and power on my node? This would make deployment, troubleshooting and testing much easier.

I am located in Australia and use the AU915 frequency plan.

My hardware setup consists of an Adafruit WICED Feather Developer Edition with a LoRaWAN FeatherWing add-on board which has a RN2903 on board.

For reference, my code is below:

/*
 * Author: JP Meijers
 * Date: 2016-09-07
 *
 * This program is meant to be used on a The Things Uno board.
 *
 * Transmit a one byte packet via TTN. This happens as fast as possible,
 * while still keeping to the 1% duty cycle rules enforced by the RN2483's built
 * in LoRaWAN stack. Even though this is allowed by the radio regulations of the
 * 868MHz band, the fair use policy of TTN may prohibit this.
 *
 * CHECK THE RULES BEFORE USING THIS PROGRAM!
 *
 * CHANGE ADDRESS!
 * Change the device address, network (session) key, and app (session) key to
 * the values that are registered via the TTN dashboard.
 * The appropriate line is "myLora.initABP(XXX);" or "myLora.initOTAA(XXX);"
 * When using ABP, it is advised to enable "relax frame count" on the dashboard.
 *
 */
#include <rn2xx3.h>

//create an instance of the rn2483 library, using the given Serial port
rn2xx3 myLora(Serial1);

// the setup routine runs once when you press reset:
void setup()
{
  pinMode(PC5, OUTPUT);
  digitalWrite(PC5, HIGH);

  // Open serial communications and wait for port to open:
  Serial.begin(57600); //serial port to computer
  Serial1.begin(57600); //serial port to radio

  // make sure usb serial connection is available,
  // or after 10s go on anyway for 'headless' use of the
  // node.
  while ((!Serial) && (millis() < 10000));

  Serial.println("Startup");

  initialize_radio();

  //transmit a startup message
  myLora.tx("TTN Mapper on TTN Uno node");
}

void initialize_radio()
{
  delay(100); //wait for the RN2xx3's startup message
  Serial1.flush();

  //print out the HWEUI so that we can register it via ttnctl
  String hweui = myLora.hweui();
  while(hweui.length() != 16)
  {
    Serial.println("Communication with RN2xx3 unsuccessful. Power cycle the TTN UNO board.");
    delay(10000);
    hweui = myLora.hweui();
  }
  Serial.println("When using OTAA, register this DevEUI: ");
  Serial.println(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);
  join_result = myLora.initABP("", "", "");

  while(!join_result)
  {
    Serial.println("Unable to join. Are your keys correct, and do you have TTN coverage?");
    delay(10000); //delay a minute before retry
    join_result = myLora.init();
  }
  Serial.println("Successfully joined TTN");

}

// the loop routine runs over and over again forever:
void loop()
{
    Serial.println("TXing");
    myLora.tx("!"); //one byte, blocking function
    delay(2000);
}
  • disable frame counter checks (see console device/settings)

  • or store values before switching power off and read them when powering device on again

Thanks for the reply. Sounds like those should be a way to resolve the problem. Just a couple of questions regarding it.

  1. Is disabling frame counter checks a security vulnerability? It’s obviously there for a reason, so by ignoring it, would that mean anyone with my keys could transmit code because no checks are being done on how many frames have been counted (transmissions already completed)?

  2. Have you had any experience with storing the values? In the Arduino programming environment I do not believe that you can program it to save values over time, yet this is achieved by the TTGO. I can only assume this is something which needs to be adjusted on the library side than the sketch I’ve put above.

Alternatively, you can use OTAA instead of ABP…

2 Likes

OTAA is safer and always the preferred method

1 - yes it can be a ’ risk ’

2 - see http://ww1.microchip.com/downloads/en/DeviceDoc/40001811A.pdf
2.4.4 mac save

1 Like

Thanks for the suggestion. I have since tried this using OTAA and face the same issue. See this post.

I have had a look into mac save and it is present in the library in two places, these being in the the initOTAA and initABP functions.

I have since realised that this isn’t a problem. In this post I made, I basically said I was not patient enough.