jpmeijers / RN2483-Arduino-Library

Arduino C++ code to communicate with a Microchip RN2483 module
Apache License 2.0
84 stars 60 forks source link

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

Open ElectronicallyE opened 5 years ago

ElectronicallyE commented 5 years ago

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, 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.

UPDATE I have discovered that this can be resolved via stopping frame counter checks, however this is still does not really address the main problem as checking would still cause the same problem.

I have been told there is a way you can see the frame counts via the "mac save" detailed in section 2.4.4 in the Microchip RN2903 Documentation. Does this have to be implemented in the library or should I do this in my sketch below?

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);
}