jpmeijers / RN2483-Arduino-Library

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

RN2903 + Arduino Nano Hangs when TXing Unconfirmed Mssg #88

Closed danalvarez closed 3 years ago

danalvarez commented 3 years ago

I am using an Arduino Nano + RN2903, wired up as in this guide: https://www.thethingsnetwork.org/forum/t/how-to-build-your-first-ttn-node-arduino-rn2483/1574/69. Only difference is I am using a level shifter to connect TX, RX and reset, between Arduino and RN2903.

The radio seems to initialize OK, I get the following information:

Startup
When using OTAA, register this DevEUI: 
<The EUI is printed here>
RN2xx3 firmware version:
RN2903 1.0.5 Nov 06 2018 10:45:27
Trying to join TTN
Successfully joined TTN
TXing

As you can see, the code stops after TXing, and the LED_BUILTIN remains high, although data is in fact transmitted to my Chirpstack LoRa Server. However, this only works once, and then the Arduino hangs. I am using a very slightly modified version of ArduinoUnoNano_basic.ino. And I am using ABP.

So, why would the module hang after TXing? Is there any other setting I must configure? It seems the code never escapes the myLora.tx("!") function, because the led_off() is never called.

Any help would be greatly appreciated!

TD-er commented 3 years ago

Given you are using a modified version of the example code, I guess it is best to also include the code here, or place a link. Make sure you don't include any 'secrets' in that code when posting it.

Also, have you created your node in TTN v2 or v3? For v3 you need to set the RX1 window to 5 seconds.

jpmeijers commented 3 years ago

A thing you need to make sure of is that the RN2903 is the correct one for your region: https://www.microchip.com/wwwproducts/en/RN2903

US902-928: RN2903A-I/RM
AU915-928: RN2903A-I/RMSA

And then make sure your gateway is also using the same frequency plan.

danalvarez commented 3 years ago

@jpmeijers Inscription in my RN2903 only says RN2903 and below that 15454PQ. I purchased this module: https://www.digikey.com/es/products/detail/microchip-technology/RN-2903-PICTAIL/5975742. I don't exactly know how to determine what version it is. My GW is definitely operating in US902. And since I am able to receive uplinks (at least once, before the code hangs) in for example the 904.1 MHz channel, I assume it should be the RN2903A-I/RM module? SNR looks fine on these uplinks: > +10 SNR. If it were transmitting on an AU915 channel and the GW managed to decode it I'd expect very low SNR.

danalvarez commented 3 years ago

@TD-er I am not using TTN, rather I am using Chirpstack. As I mentioned, I am able to transmit 1 uplink, but then the node hangs in TXing and never turns off the LED (i.e. gets stuck in the loop). One matter that may be of interest is that my Chirpstack server is currently sending a downlink immediately after the uplink, with the MAC commands to set RXParamSetupReq to DR 10 and 923300000 and RXTimingSetupReq to delay 1 (as per this spec https://www.chirpstack.io/network-server/features/rx-parameter-configuration/). I wouldn't expect this to hang the code, because I am using an unconfirmed message, but maybe that's what's happening?

Here is my code, basically I just added a change in Frequency Plan (the code still gets stuck in TXing without this change), changed the baud rate for debug to 9600, commented out the startup message and set my keys for ABP.

/*
 * Author: JP Meijers
 * Date: 2016-02-07
 * Previous filename: TTN-Mapper-TTNEnschede-V1
 *
 * This program is meant to be used with an Arduino UNO or NANO, conencted to an RNxx3 radio module.
 * It will most likely also work on other compatible Arduino or Arduino compatible boards, like The Things Uno, but might need some slight modifications.
 *
 * 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".
 *
 * Connect the RN2xx3 as follows:
 * RN2xx3 -- Arduino
 * Uart TX -- 10
 * Uart RX -- 11
 * Reset -- 12
 * Vcc -- 3.3V
 * Gnd -- Gnd
 *
 * If you use an Arduino with a free hardware serial port, you can replace
 * the line "rn2xx3 myLora(mySerial);"
 * with     "rn2xx3 myLora(SerialX);"
 * where the parameter is the serial port the RN2xx3 is connected to.
 * Remember that the serial port should be initialised before calling initTTN().
 * For best performance the serial port should be set to 57600 baud, which is impossible with a software serial port.
 * If you use 57600 baud, you can remove the line "myLora.autobaud();".
 *
 */
#include <rn2xx3.h>
#include <SoftwareSerial.h>

SoftwareSerial mySerial(10, 11); // RX, TX
uint8_t to_send[1];

//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()
{
  //output LED pin
  pinMode(13, OUTPUT);
  led_on();

  // Open serial communications and wait for port to open:
  Serial.begin(9600); //serial port to computer
  mySerial.begin(9600); //serial port to radio
  Serial.println("Startup");

  initialize_radio();

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

  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. Power cycle the board.");
    Serial.println(hweui);
    delay(10000);
    hweui = myLora.hweui();
  }

  //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());

  // setting fp
  //bool fp = myLora.setFrequencyPlan(TTN_US);
  //Serial.println("FP Set: ");Serial.println(fp);

  //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 = "goes here";
  const char *nwkSKey = "goes here";
  const char *appSKey = "goes here";

  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 = "70B3D57ED00001A6";
  //const char *appKey = "A23C96EE13804963F8C2BD6285448198";

  //join_result = myLora.initOTAA(appEui, appKey);

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

  // setting fp
  bool fp = myLora.setFrequencyPlan(TTN_US);
  Serial.println("FP Set: ");Serial.println(fp);
}

// the loop routine runs over and over again forever:
void loop()
{
    led_on();

    Serial.println("TXing");
    myLora.tx("!"); //one byte, blocking function
    //to_send[0] = 0x08;
    //myLora.txBytes(to_send, sizeof(to_send));

    led_off();
    delay(200);
}

void led_on()
{
  digitalWrite(13, 1);
}

void led_off()
{
  digitalWrite(13, 0);
}
jpmeijers commented 3 years ago

At this point we need to figure out why the tx function never returns. Look at https://github.com/jpmeijers/RN2483-Arduino-Library/blob/401b7fca5530a87d72e1ed61d4c042e4b48fcdd9/src/rn2xx3.cpp#L387 and add a Serial.println(receviedData) there. The radio is likely responding with an error which is not correctly handled, and the while loop tries over and over forever.

TD-er commented 3 years ago

@jpmeijers Could the module refuse to continue if there is a received message which has not been read/fetched?

jpmeijers commented 3 years ago

Unlikely, because an RX message should be caught and read by this: https://github.com/jpmeijers/RN2483-Arduino-Library/blob/401b7fca5530a87d72e1ed61d4c042e4b48fcdd9/src/rn2xx3.cpp#L408

danalvarez commented 3 years ago

Hello, thank you both @jpmeijers and @TD-er for your continued support. I just added the following line right after the String receivedData = _serial.readStringUntil('\n'); line:

String receivedData = _serial.readStringUntil('\n');
Serial.print("Rcvd data type: ");
Serial.println(determineReceivedDataType(receivedData));

However, nothing gets printed after TXing, not even the "Rcvd data type:" string. So I believe the readStringUntil('\n') is not returning (not finding the termination character). Any further ideas of what we might try to figure this out?

If it helps, the downlink my Chirpstack server is sending right after the uplink is the following:

image

danalvarez commented 3 years ago

@jpmeijers

OK, so maybe this helps, I changed the code to the following:

//String receivedData = _serial.readStringUntil('\n');
String receivedData = "foo";
while(true)
{
  Serial.println(_serial.read());
}

And I get this output:

Startup
When using OTAA, register this DevEUI: 
<EUI goes here>
RN2xx3 firmware version:
RN2903 1.0.5 Nov 06 2018 10:45:27
Trying to join TTN
Successfully joined TTN
FP Set: 
1
TXing
-1
-1
-1
-1
-1
-1
-1

The -1 keep going on for a while and then stop. If I set the debugging Serial to 57600 baud I get more -1 printed than when its at 9600 baud. So something with the Serial ports is in conflict/taking up resources as well? I am using SoftwareSerial at pins D10 and D11 for RX and TX with the RN2903.

Note that the section of the print saying FP Set: 1 is where I set the frequency plan to TTN_US via the setFrequencyPlan method.

TD-er commented 3 years ago

Testing at different baud rates is a good idea to check if its behavior remains constant. I sometimes have seen that the communication to the RN2xx3 is not 100% correct when using SW serial. So just to make sure we're not looking at handling a bad command.

Getting more -1 values at higher baud rate makes sense if it is a fault state existing for a fixed amount of time.

danalvarez commented 3 years ago

OK, so I seem to have found the issue, but not the solution... I swapped out my Arduino Nano clone (this one) for an Arduino UNO. Ran the code again and it worked like a charm: continous transmission with no hanging on TXing. So, it seems to be a problem with the Arduino Nano I have. Swapped it for another Nano clone and same problem, so not an issue with that specific unit. I went and also updated the bootloader (because it was using the old bootloader for the ATMEGA328P), and that did not change much, although I did get the Arduino to print this:

Startup
When using OTAA, register this DevEUI: 
<EUI goes here>
RN2xx3 firmware version:
RN2903 1.0.5 Nov 06 2018 10:45:27
Trying to join TTN
ABP Rcvd data: accepted
Successfully joined TTN
FP Set: 
1
TXing
Rcvd data type: 14
Rcvd data: ⸮#=cs⸮
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
Rcvd data type: 14
Rcvd data: 
TXing
Rcvd data type: 14
Rcvd data: 

So it was receiving an UNKNOWN response from the RN2903. In general I have seen that it seems to be an issue with the SoftwareSerial library somehow becoming unresponsive. Also tried the AltSoftSerial library and same issues.

Any ideas guys @jpmeijers @TD-er ? I'd like to get this working on my Nanos instead of the UNO, because of the size of the boards.

TD-er commented 3 years ago

I don't know the Arduino Nano boards well, but doesn't that board have a HW serial port? (the one you look at for your logs) So what you could try to do, is swap the serial ports for theRN2903 and the log (thus you probably need some USB to serial adapter for it). Just to try if that makes a difference. I think the SWserial is not that consistent with the pulse widths (thus timing). Also on the ESP8266, SWserial isn't that stable and I have seen some issues with the RN2483 also, where I got either some bogus reply or the node acting strange. So perhaps those RN modules are very strict on the serial timings.

If you do have a scope, you could also try to see if the levels of the digital signal are OK. Maybe the signal is not received well? (rounded edges, not a square wave pattern) On some boards (I mainly have experience with ESP8266) and in some datasheets I have seen a 500 Ohm (or 470) resistor being used in series with the TX line to prevent "ringing".

danalvarez commented 3 years ago

Hi @TD-er

I actually went and swapped the serial ports as you suggested. Used AltSoftSerial at 9600 baud for debugging and HW serial at 57600 baud for comms with the RN2903. It made a difference, but behaviour was not nominal... The Nano no longer got stuck on TXing, but the RN2903 transmitted 10 times while TXing was only printed out to the console 6 times. Also, the frame counter did not increase, rather every uplink was sent with FCnt = 0. So, something very odd is happening. I think that for the time being I will use the Arduino UNO R3 which functions correctly.

I think the problem must lie in the main difference between my Arduino UNO and Nano: namely, that the Arduino UNO uses an ATmega16U2 to act as a serial-to-USB bridge, while the Nano uses the CH340G. So maybe this is messing with the serial comms? Very odd. I will try to use a Nano with maybe an FTDI chip or PL2303TA and see if there's any difference. Will post here if so.

danalvarez commented 3 years ago

As an update, I've moved on from this by using an Arduino Pro Mini with an external FTDI adapter. In that setup, this does not occur, so I don't know what might have caused the issues with my specific (chinese) version of the Nano. Gonna go ahead and close this as I feel this might have been specific to the type of Nano I was using and not a problem with the library. Great library btw!