jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.59k stars 399 forks source link

RadioLib 6.4.1 LoRaWAN isseu #948

Closed nmaas87 closed 10 months ago

nmaas87 commented 10 months ago

Describe the bug Short feedback for you (@StevenCellist / @jgromes) and the PR #942 , I tried a STM32WL55 module with the latest 6.4.1 patch, as well as with 6.4.0 and 6.3.0 in EU868 state with the LoRaWAN reference example.

6.3.0 - works flawlessly 6.4.0 - node.restore() does not work, but initial joining/OTAA does work 6.4.1 - initial joining/OTAA does not work with reference to the region code / status / error code:

[LoRaWAN] Resuming previous session ... failed, code -1101
[LoRaWAN] Attempting over-the-air activation ... failed, code -1106

I have not tried other modules yet, but maybe there is a bigger issue here at hand?

Debug output below:

[STM32WLx] Initializing ... 
RadioLib Debug Info
Version:  6.4.1.0
Platform: Arduino STM32 (official)
Compiled: Jan 28 2024 12:17:58

CMDW    80  
SI  0   
SO  AA  
CMDW    80  
SI  0   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    1D  3   20  
SI  0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   0   
SO  A2  53  58  31  32  36  31  20  54  4B  46  20  31  41  31  31  0   
Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:
0000320 53 58 31 32 36 31 20 54 4b 46 20 31 41 31 31 00 | SX1261 TKF 1A11.

M   SX126x
CMDW    80  
SI  0   
SO  AA  
CMDW    80  
SI  0   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    80  
SI  0   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    80  
SI  0   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    17  
SI  0   0   0   
SO  A2  0   20  
CMDR    C0  
SI  0   
SO  A2  
CMDW    7   
SI  0   0   
SO  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    97  
SI  0   0   1   40  
SO  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    8F  
SI  0   0   
SO  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    8A  
SI  1   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    93  
SI  20  
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    88  
SI  3   16  A   0   0   0   0   
SO  A2  A2  A2  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    2   
SI  43  FF  
SO  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    8   
SI  0   0   0   0   0   0   0   0   
SO  A2  A2  A2  A2  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    89  
SI  7F  
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    11  
SI  0   0   
SO  A2  1   
CMDR    C0  
SI  0   
SO  A2  
CMDW    8B  
SI  9   6   3   0   
SO  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    11  
SI  0   0   
SO  A2  1   
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   7   40  
SI  14  24  
SO  A2  A2  
CMDR    11  
SI  0   0   
SO  A2  1   
CMDR    C0  
SI  0   
SO  A2  
CMDR    1D  7   36  
SI  0   0   
SO  A2  D   
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   7   36  
SI  D   
SO  A2  
CMDW    8C  
SI  0   8   0   FF  1   0   
SO  A2  A2  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    96  
SI  1   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   8   E7  
SI  18  
SO  A2  
CMDW    9D  
SI  1   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    11  
SI  0   0   
SO  A2  1   
CMDR    C0  
SI  0   
SO  A2  
CMDR    1D  7   36  
SI  0   0   
SO  A2  D   
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   7   36  
SI  D   
SO  A2  
CMDW    8C  
SI  0   8   0   FF  1   0   
SO  A2  A2  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    11  
SI  0   0   
SO  A2  1   
CMDR    C0  
SI  0   
SO  A2  
CMDR    1D  7   36  
SI  0   0   
SO  A2  D   
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   7   36  
SI  D   
SO  A2  
CMDW    8C  
SI  0   8   0   FF  1   0   
SO  A2  A2  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    11  
SI  0   0   
SO  A2  1   
CMDR    C0  
SI  0   
SO  A2  
CMDW    8B  
SI  9   6   3   0   
SO  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    11  
SI  0   0   
SO  A2  1   
CMDR    C0  
SI  0   
SO  A2  
CMDW    8B  
SI  9   4   3   0   
SO  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    98  
SI  6B  6E  
SO  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    86  
SI  1B  20  0   0   
SO  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    1D  8   D8  
SI  0   0   
SO  A2  DE  
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   8   D8  
SI  DE  
SO  A2  
CMDR    1D  8   E7  
SI  0   0   
SO  A2  18  
CMDR    C0  
SI  0   
SO  A2  
CMDW    95  
SI  4   0   1   1   
SO  A2  A2  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDR    1D  8   D8  
SI  0   0   
SO  A2  1E  
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   8   D8  
SI  8   
SO  A2  
CMDW    8E  
SI  A   4   
SO  A2  A2  
CMDR    C0  
SI  0   
SO  A2  
CMDW    D   8   E7  
SI  18  
SO  A2  
CMDW    9D  
SI  0   
SO  A2  
CMDR    C0  
SI  0   
SO  A2  
success!
[LoRaWAN] Attempting over-the-air activation ... Didn't restore session (checksum: 0, mode: 0)
First 16 bytes of NVM:
0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
Wiping EEPROM and starting a clean session
Setting up dynamic channels
Channel UL/DL 0 frequency =  MHz

To Reproduce

/*
  RadioLib LoRaWAN End Device Reference Example

  This example joins a LoRaWAN network and will send
  uplink packets. Before you start, you will have to
  register your device at https://www.thethingsnetwork.org/
  After your device is registered, you can run this example.
  The device will join the network and start uploading data.

  Also, most of the possible and available functions are
  shown here for reference.

  LoRaWAN v1.1 requires the use of EEPROM (persistent storage).
  Please refer to the 'persistent' example once you are familiar
  with LoRaWAN.
  Running this examples REQUIRES you to check "Resets DevNonces"
  on your LoRaWAN dashboard. Refer to the network's 
  documentation on how to do this.

  For default module settings, see the wiki page
  https://github.com/jgromes/RadioLib/wiki/Default-configuration

  For full API reference, see the GitHub Pages
  https://jgromes.github.io/RadioLib/
*/

// include the library
#include <RadioLib.h>

// no need to configure pins, signals are routed to the radio internally
STM32WLx radio = new STM32WLx_Module();

// set RF switch configuration for Nucleo WL55JC1
// NOTE: other boards may be different!
//       Some boards may not have either LP or HP.
//       For those, do not set the LP/HP entry in the table.
static const uint32_t rfswitch_pins[] =
                         {PC3,  PC4,  PC5};
static const Module::RfSwitchMode_t rfswitch_table[] = {
  {STM32WLx::MODE_IDLE,  {LOW,  LOW,  LOW}},
  {STM32WLx::MODE_RX,    {HIGH, HIGH, LOW}},
  {STM32WLx::MODE_TX_LP, {HIGH, HIGH, HIGH}},
  {STM32WLx::MODE_TX_HP, {HIGH, LOW,  HIGH}},
  END_OF_MODE_TABLE,
};

// create the node instance on the EU-868 band
// using the radio module and the encryption key
// make sure you are using the correct band
// based on your geographical location!
LoRaWANNode node(&radio, &EU868);

// for fixed bands with subband selection
// such as US915 and AU915, you must specify
// the subband that matches the Frequency Plan
// that you selected on your LoRaWAN console
/*
  LoRaWANNode node(&radio, &US915, 2);
*/

void setup() {
  Serial.begin(9600);

  // set RF switch control configuration
  // this has to be done prior to calling begin()
  radio.setRfSwitchTable(rfswitch_pins, rfswitch_table);

  // initialize STM32WLx with default settings, except frequency
  Serial.print(F("[STM32WLx] Initializing ... "));
  int state = radio.begin();
  //int state = radio.begin(868.0);
  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while(true);
  }

  // application identifier - pre-LoRaWAN 1.1.0, this was called appEUI
  // when adding new end device in TTN, you will have to enter this number
  // you can pick any number you want, but it has to be unique
  uint64_t joinEUI = 0x12AD1011B0C0FFEE;

  // device identifier - this number can be anything
  // when adding new end device in TTN, you can generate this number,
  // or you can set any value you want, provided it is also unique
  uint64_t devEUI = 0x70B3D57ED005E120;

  // select some encryption keys which will be used to secure the communication
  // there are two of them - network key and application key
  // because LoRaWAN uses AES-128, the key MUST be 16 bytes (or characters) long

  // network key is the ASCII string "topSecretKey1234"
  uint8_t nwkKey[] = { 0x74, 0x6F, 0x70, 0x53, 0x65, 0x63, 0x72, 0x65,
                       0x74, 0x4B, 0x65, 0x79, 0x31, 0x32, 0x33, 0x34 };

  // application key is the ASCII string "aDifferentKeyABC"
  uint8_t appKey[] = { 0x61, 0x44, 0x69, 0x66, 0x66, 0x65, 0x72, 0x65,
                       0x6E, 0x74, 0x4B, 0x65, 0x79, 0x41, 0x42, 0x43 };

  delay(5000);

    Serial.print(F("[LoRaWAN] Resuming previous session ... "));
    state = node.restore();
    if(state == RADIOLIB_ERR_NONE) {
      Serial.println(F("success!"));
    } else {
      Serial.print(F("failed, code "));
      Serial.println(state);
      //while(true);

      node.wipe();

      Serial.print(F("[LoRaWAN] Attempting over-the-air activation ... "));
      state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);

      if(state == RADIOLIB_ERR_NONE) {
        Serial.println(F("success!"));
      } else {
        Serial.print(F("failed, code "));
        Serial.println(state);
        while(true);
      }
    }

  // disable the ADR algorithm
  //node.setADR(false);

  // set a fixed datarate
  //node.setDatarate(5);
  // in order to save the datarate persistent across reboot/deepsleep, use the following:
  /*
    node.setDatarate(5, true);  
  */

  // enable CSMA
  // this tries to minimize packet loss by searching for a free channel
  // before actually sending an uplink 
  //node.setCSMA(6, 2, true);

  // enable or disable the dutycycle
  // the second argument specific allowed airtime per hour in milliseconds
  // 1250 = TTN FUP (30 seconds / 24 hours)
  // if not called, this corresponds to setDutyCycle(true, 0)
  // setting this to 0 corresponds to the band's maximum allowed dutycycle by law
  node.setDutyCycle(true, 1250);

  // enable or disable the dwell time limits
  // the second argument specific allowed airtime per uplink in milliseconds
  // if not called, this corresponds to setDwellTime(true, 0)
  // setting this to 0 corresponds to the band's maximum allowed dwell time by law
  node.setDwellTime(true, 1000);
}

void loop() {
  int state = RADIOLIB_ERR_NONE;

  // set battery fill level - the LoRaWAN network server
  // may periodically request this information
  // 0 = external power source
  // 1 = lowest (empty battery)
  // 254 = highest (full battery)
  // 255 = unable to measure
  uint8_t battLevel = 146;
  node.setDeviceStatus(battLevel);

  // retrieve the last uplink frame counter
  uint32_t fcntUp = node.getFcntUp();

  Serial.print(F("[LoRaWAN] Sending uplink packet ... "));
  String strUp = "Hello World! #" + String(fcntUp);

  // send a confirmed uplink to port 10 every 64th frame
  // and also request the LinkCheck and DeviceTime MAC commands
  if(fcntUp % 64 == 0) {
    state = node.uplink(strUp, 10, true);
    node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_LINK_CHECK);
    node.sendMacCommandReq(RADIOLIB_LORAWAN_MAC_DEVICE_TIME);
  } else {
    state = node.uplink(strUp, 10);
  }
  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
  }

  // after uplink, you can call downlink(),
  // to receive any possible reply from the server
  // this function must be called within a few seconds
  // after uplink to receive the downlink!
  Serial.print(F("[LoRaWAN] Waiting for downlink ... "));
  String strDown;

  // you can also retrieve additional information about 
  // uplink or downlink by passing a reference to
  // LoRaWANEvent_t structure
  LoRaWANEvent_t event;
  state = node.downlink(strDown, &event);
  if(state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));

    // print data of the packet (if there are any)
    Serial.print(F("[LoRaWAN] Data:\t\t"));
    if(strDown.length() > 0) {
      Serial.println(strDown);
    } else {
      Serial.println(F("<MAC commands only>"));
    }

    // print RSSI (Received Signal Strength Indicator)
    Serial.print(F("[LoRaWAN] RSSI:\t\t"));
    Serial.print(radio.getRSSI());
    Serial.println(F(" dBm"));

    // print SNR (Signal-to-Noise Ratio)
    Serial.print(F("[LoRaWAN] SNR:\t\t"));
    Serial.print(radio.getSNR());
    Serial.println(F(" dB"));

    // print frequency error
    Serial.print(F("[LoRaWAN] Frequency error:\t"));
    Serial.print(radio.getFrequencyError());
    Serial.println(F(" Hz"));

    // print extra information about the event
    Serial.println(F("[LoRaWAN] Event information:"));
    Serial.print(F("[LoRaWAN] Direction:\t"));
    if(event.dir == RADIOLIB_LORAWAN_CHANNEL_DIR_UPLINK) {
      Serial.println(F("uplink"));
    } else {
      Serial.println(F("downlink"));
    }
    Serial.print(F("[LoRaWAN] Confirmed:\t"));
    Serial.println(event.confirmed);
    Serial.print(F("[LoRaWAN] Confirming:\t"));
    Serial.println(event.confirming);
    Serial.print(F("[LoRaWAN] Datarate:\t"));
    Serial.print(event.datarate);
    Serial.print(F("[LoRaWAN] Frequency:\t"));
    Serial.print(event.freq, 3);
    Serial.println(F(" MHz"));
    Serial.print(F("[LoRaWAN] Output power:\t"));
    Serial.print(event.power);
    Serial.println(F(" dBm"));
    Serial.print(F("[LoRaWAN] Frame count:\t"));
    Serial.println(event.fcnt);
    Serial.print(F("[LoRaWAN] Port:\t\t"));
    Serial.println(event.port);

    Serial.print(radio.getFrequencyError());

    uint8_t margin = 0;
    uint8_t gwCnt = 0;
    if(node.getMacLinkCheckAns(&margin, &gwCnt)) {
      Serial.print(F("[LoRaWAN] LinkCheck margin:\t"));
      Serial.println(margin);
      Serial.print(F("[LoRaWAN] LinkCheck count:\t"));
      Serial.println(gwCnt);
    }

    uint32_t networkTime = 0;
    uint8_t fracSecond = 0;
    if(node.getMacDeviceTimeAns(&networkTime, &fracSecond, true)) {
      Serial.print(F("[LoRaWAN] DeviceTime Unix:\t"));
      Serial.println(networkTime);
      Serial.print(F("[LoRaWAN] LinkCheck second:\t1/"));
      Serial.println(fracSecond);
    }

  } else if(state == RADIOLIB_ERR_RX_TIMEOUT) {
    Serial.println(F("timeout!"));

  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
  }

  // on EEPROM enabled boards, you can save the current session
  // by calling "saveSession" which allows retrieving the session after reboot or deepsleep
  node.saveSession();

  // wait before sending another packet
  uint32_t minimumDelay = 60000;                  // try to send once every minute
  uint32_t interval = node.timeUntilUplink();     // calculate minimum duty cycle delay (per law!)
    uint32_t delayMs = max(interval, minimumDelay); // cannot send faster than duty cycle allows

  delay(delayMs);
}

Expected behavior Starting connection to LoRaWAN as usual

Additional info (please complete):

StevenCellist commented 10 months ago

Your debug output appears incomplete, there should be much more before it actually fails with -1106. Also, please remove all (or most of) the SPI mess to keep logs readable and the page scrollable :)

nmaas87 commented 10 months ago

Maybe like that? Oh yeah, sorry I saw it was missing most of it...

[STM32WLx] Initializing ...
RadioLib Debug Info
Version:  6.4.1.0
Platform: Arduino STM32 (official)
Compiled: Jan 28 2024 12:17:58

Found SX126x: RADIOLIB_SX126X_REG_VERSION_STRING:
0000320 53 58 31 32 36 31 20 54 4b 46 20 31 41 31 31 00 | SX1261 TKF 1A11.

success!
[LoRaWAN] Attempting over-the-air activation ... Didn't restore session (checksum: 0, mode: 0)
First 16 bytes of NVM:
0000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................
Wiping EEPROM and starting a clean session
Setting up dynamic channels
Channel UL/DL 0 frequency =  MHz
Channel UL/DL 1 frequency =  MHz
Channel UL/DL 2 frequency =  MHz
exe MAC CID = 03, len = 4
ADR REQ: dataRate = 2, txPower = 0, chMask = 0x0000, chMaskCntl = 00, nbTrans = 0
DR 72: LORA (SF: 10, BW: , CR: 5)

ADR failed to configure dataRate = 2!

ADR ANS: status = 0x05
exe MAC CID = 04, len = 1
Max duty cycle: 1/2^7
exe MAC CID = 05, len = 4
Rx param REQ: rx1DrOffset = 0, rx2DataRate = 0, freq =

Rx param ANS: status = 0x07
exe MAC CID = 08, len = 1
RX timing: delay = 1 sec
exe MAC CID = 09, len = 1
TX timing: dlDwell = 0, ulDwell = 0, maxEirp = 16 dBm
exe MAC CID = 0c, len = 1
ADR param setup: limitExp = 6, delayExp = 5
exe MAC CID = 0f, len = 1
Rejoin setup: maxTime = 15, maxCount = 10

There are no channels defined - are you in ABP mode with no defined subband?
failed, code -1106
StevenCellist commented 10 months ago

ADR failed to configure dataRate = 2!

@jgromes, could you have a look? Still on mobile, haven't had time to look at the actual fix you added.

jgromes commented 10 months ago

There was an error in the data rate check, my fault. @nmaas87 I pushed a fix, could you try it out?

nmaas87 commented 10 months ago

Thanks @jgromes - trying it right now and getting back to you

nmaas87 commented 10 months ago

Yes, thanks a lot @jgromes / @StevenCellist - that fixed it :). Can be closed! :)

jgromes commented 10 months ago

@nmaas87 thanks for testing it out. Unfortuantely the bug pretty much breaks LoraWAN in 6.4.1, so we will need to release 6.4.2 patch ...

StevenCellist commented 10 months ago

Hopefully it's so fast after 6.4.1 that nobody notices / bothers :) and thanks you two!!

altinem commented 9 months ago

hello, I have a Heltec wireless stick v3 board. I succesfully initilized SX1262 chip and OTAA activated the board with TTN. I am getting LORAWAN sending uplink packet... failed code -4. I have looked all over the forum and could not find a solution why I am getting this error. I have a sensecap M2 gateway setup as packet forwarder. The gateway is connected to the TTN without issues. Could someone help me why I am getting this error message.

jgromes commented 9 months ago

@altinem did you at least search for what the -4 error means? It's on this page: https://jgromes.github.io/RadioLib/group__status__codes.html, literally the first result I got when googling "radiolib error codes". In there, you will find that -4 is RADIOLIB_ERR_PACKET_TOO_LONG, so my guess is that you attempted to uplink a packet longer than 255 bytes, which the SX126x cannot do. I'm only guessing though since you have not provided the code you are running.

Also, please don't revive old threads that have been resolved and are rather obviously unrelated to your problem. If your problem persists, open a new Issue or Discussion and include all the necessary information, such as the code you are actually running.