Unable to join network: Rx 2 timeout

I don’t think the police or the courts care, and you end up with an asymmetric radio system and you end up needing a lot of them for your devices. Just use a normal stubby antenna or piece of wire.

1 Like

Where does it suggest that then?

Meh! Layers of code to drill through - good spot.

Maybe you could try RadioLib - people have got the Pico working, I have a Pico + radio combo on my bench (somewhere) to test it for the official RadioLib docs so there will be some sorting out as we don’t have it gift wrapped just yet but it should be simpler than unravelling the abandonware that is the port - looks like someone got a Pico when they first came out, did the port, realised that battery life was going to be poor and just left it on the 3 year old release of LoRaMAC-node.

Radiolib really good! I’ll give it a try. Defentitely seems like a better solution compared to the port as you said.

Out of interest, what MCUs would you suggest that are more power efficient?

Not so much efficiency, it’s more about the sleep current which for the Pico is in mA’s and for pretty much everything else is in uA.

For RadioLib which needs more Flash than AVR normally offers, I’d go with SAMD or STM32. ESP32 does do low power sleep - which is what a LW device normally spends a lot of time doing - but has a longer restart time from deep sleep.

Ok I’ve basically just spliced together bits from the Arduino OTAA example and tweaked it to work with the Pico. Here’s what Ive got so far:

// main.cpp

#include <string.h>
#include <stdio.h>
#include <pico/stdlib.h>
#include "tusb.h"

#include "config.h"

int uplinkDelay = 3600; // 1 hour

int main() {

  // Init serial and wait for a connection:
  stdio_init_all();
  while (!tud_cdc_connected()) {
      tight_loop_contents();
  }
  
  printf("Radiolib LoRaWAN example for Raspberry Pi Pico\n");

  // Initialise the radio
  int16_t state = radio.begin();
  debug(state != RADIOLIB_ERR_NONE, "Initialise radio failed", state, true);

  // Initialise the LoRaWAN node and try to join the network
  node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);

  printf("Joining LoRaWAN network...\n");

  state = node.activateOTAA();
  debug(state != RADIOLIB_ERR_NONE, "Join failed", state, true);

  printf("Joined LoRaWAN network successfully!\n");

  while(true) {
    // Send uplink every uplinkDelay seconds
    printf("Sending uplink...\n");
    uint8_t value1 = radio.random(100);
    uint16_t value2 = radio.random(2000);

    uint8_t uplinkPayload[3];
    uplinkPayload[0] = value1;
    uplinkPayload[1] = highByte(value2);
    uplinkPayload[2] = lowByte(value2);
    
    int16_t state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));    
    debug((state != RADIOLIB_LORAWAN_NO_DOWNLINK) && (state != RADIOLIB_ERR_NONE), "Error in sendReceive", state, false);

    printf("Uplink complete, next in ");
    printf("%d", uplinkDelay);
    printf(" seconds. \n");
  
    // Sleep until next uplink
    sleep_ms(uplinkDelay * 1000UL);
  }
}
//config.h

#pragma once

#include <RadioLib.h>

#include "PicoHal.h"

// Pin definitions:
#define SPI_PORT spi0
#define SPI_MISO 16
#define SPI_MOSI 19
#define SPI_SCK 18

#define RFM_NSS 8
#define RFM_RST 9
#define RFM_DIO0 7
#define RFM_DIO1 10

// LoRaWAN keys:
#define RADIOLIB_LORAWAN_JOIN_EUI  0x0000000000000000

#ifndef RADIOLIB_LORAWAN_DEV_EUI
#define RADIOLIB_LORAWAN_DEV_EUI   0x70B3D57ED0069153
#endif
#ifndef RADIOLIB_LORAWAN_APP_KEY
#define RADIOLIB_LORAWAN_APP_KEY   0xE1, 0x03, 0x8F, 0x0B, 0xF6, 0x3D, 0x80, 0x80, 0x3D, 0x3B, 0xC6, 0x15, 0xA5, 0x24, 0x58, 0xD4
#endif
#ifndef RADIOLIB_LORAWAN_NWK_KEY
#define RADIOLIB_LORAWAN_NWK_KEY   0xC8, 0x7F, 0xC4, 0xFA, 0xF7, 0xD6, 0xFB, 0x72, 0x3E, 0x94, 0x0A, 0x7A, 0x33, 0xE0, 0x46, 0xC7
#endif

// Region and sub-band:
const LoRaWANBand_t Region = AU915;
const uint8_t subBand = 2;  // TTN uses FSB 2 in Australia so I'm assuming 2 here

// Create the hardware abstraction layer:
PicoHal* hal = new PicoHal(SPI_PORT, SPI_MISO, SPI_MOSI, SPI_SCK);

// Create the radio module:
SX1276 radio = new Module(hal, RFM_NSS, RFM_DIO0, RFM_RST, RFM_DIO1);

// Init the lorawan keys:
uint64_t joinEUI =   RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI  =   RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };

// create the LoRaWAN node
LoRaWANNode node(&radio, &Region, subBand);

// Error code helpers
// I pasted this from arduino example and changed a few things to make it work with the Pico. Probably not the most elegant but it works for now.

const char* stateDecode(const int16_t result) {
  switch (result) {
  case RADIOLIB_ERR_NONE:
    return "ERR_NONE";
  case RADIOLIB_ERR_CHIP_NOT_FOUND:
    return "ERR_CHIP_NOT_FOUND";
  case RADIOLIB_ERR_PACKET_TOO_LONG:
    return "ERR_PACKET_TOO_LONG";
  case RADIOLIB_ERR_RX_TIMEOUT:
    return "ERR_RX_TIMEOUT";
  case RADIOLIB_ERR_CRC_MISMATCH:
    return "ERR_CRC_MISMATCH";
  case RADIOLIB_ERR_INVALID_BANDWIDTH:
    return "ERR_INVALID_BANDWIDTH";
  case RADIOLIB_ERR_INVALID_SPREADING_FACTOR:
    return "ERR_INVALID_SPREADING_FACTOR";
  case RADIOLIB_ERR_INVALID_CODING_RATE:
    return "ERR_INVALID_CODING_RATE";
  case RADIOLIB_ERR_INVALID_FREQUENCY:
    return "ERR_INVALID_FREQUENCY";
  case RADIOLIB_ERR_INVALID_OUTPUT_POWER:
    return "ERR_INVALID_OUTPUT_POWER";
  case RADIOLIB_ERR_NETWORK_NOT_JOINED:
	  return "RADIOLIB_ERR_NETWORK_NOT_JOINED";
  case RADIOLIB_ERR_DOWNLINK_MALFORMED:
    return "RADIOLIB_ERR_DOWNLINK_MALFORMED";
  case RADIOLIB_ERR_INVALID_REVISION:
    return "RADIOLIB_ERR_INVALID_REVISION";
  case RADIOLIB_ERR_INVALID_PORT:
    return "RADIOLIB_ERR_INVALID_PORT";
  case RADIOLIB_ERR_NO_RX_WINDOW:
    return "RADIOLIB_ERR_NO_RX_WINDOW";
  case RADIOLIB_ERR_INVALID_CID:
    return "RADIOLIB_ERR_INVALID_CID";
  case RADIOLIB_ERR_UPLINK_UNAVAILABLE:
    return "RADIOLIB_ERR_UPLINK_UNAVAILABLE";
  case RADIOLIB_ERR_COMMAND_QUEUE_FULL:
    return "RADIOLIB_ERR_COMMAND_QUEUE_FULL";
  case RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND:
    return "RADIOLIB_ERR_COMMAND_QUEUE_ITEM_NOT_FOUND";
  case RADIOLIB_ERR_JOIN_NONCE_INVALID:
    return "RADIOLIB_ERR_JOIN_NONCE_INVALID";
  case RADIOLIB_ERR_N_FCNT_DOWN_INVALID:
    return "RADIOLIB_ERR_N_FCNT_DOWN_INVALID";
  case RADIOLIB_ERR_A_FCNT_DOWN_INVALID:
    return "RADIOLIB_ERR_A_FCNT_DOWN_INVALID";
  case RADIOLIB_ERR_DWELL_TIME_EXCEEDED:
    return "RADIOLIB_ERR_DWELL_TIME_EXCEEDED";
  case RADIOLIB_ERR_CHECKSUM_MISMATCH:
    return "RADIOLIB_ERR_CHECKSUM_MISMATCH";
  case RADIOLIB_LORAWAN_NO_DOWNLINK:
    return "RADIOLIB_LORAWAN_NO_DOWNLINK";
  case RADIOLIB_LORAWAN_SESSION_RESTORED:
    return "RADIOLIB_LORAWAN_SESSION_RESTORED";
  case RADIOLIB_LORAWAN_NEW_SESSION:
    return "RADIOLIB_LORAWAN_NEW_SESSION";
  case RADIOLIB_LORAWAN_NONCES_DISCARDED:
    return "RADIOLIB_LORAWAN_NONCES_DISCARDED";
  case RADIOLIB_LORAWAN_SESSION_DISCARDED:
    return "RADIOLIB_LORAWAN_SESSION_DISCARDED";
  }
  return "See https://jgromes.github.io/RadioLib/group__status__codes.html";
}

// helper function to display any issues
void debug(bool failed, const char* message, int state, bool halt) {
  if(failed) {
    printf("%s", message);
    printf(" - ");
    printf("%s", stateDecode(state));
    printf(" (");
    printf("%d", state);
    printf(") \n");
    while(halt) { sleep_ms(1); }
  }
}

// helper function to display a byte array
void arrayDump(uint8_t *buffer, uint16_t len) {
  for(uint16_t c = 0; c < len; c++) {
    char b = buffer[c];
    if(b < 0x10) { printf("0"); }
    printf("%d",b);
  }
  printf(" ");
}

#define lowByte(w) ((uint8_t) ((w) & 0xff))
#define highByte(w) ((uint8_t) ((w) >> 8))

The library seems really nice but I’ve got a new problem - After sending a join request, it looks like TTN rejects it and and the error “Devnonce is too small” is listed in the console. This is with version 1.1.0 and RP001 revision A.

I’ve still got a few things to try and it seems like a fairly common problem so I I’ll do some searching on the forum and the github discussions. But I’m guessing I should start a new thread with this?

Read the notes in the starter - they are totally comphrehensive written by @AwesomeDude. You will in fact be the first person to ask about this because, well, the notes are so awesome.

Simpler to carry on with this thread.

Ok after a long hiatus I’m returning to this. I completely redesigned my board and swapped the pico out for an ESP32. The slow boot time after sleep shouldn’t be an issue for my project. The new RP2350 looks very interesting though, with the power consumption during deep sleep supposedly being much better than the 2040.

I got radiolib up and running on the ESP32 but I’m having the same problem with the node not receiving the join-accept packet. The radiolib error code I’m getting is -1116 but occasionally -1118. I can see the join request getting sent in the console and the gateway accepting it and sending the accept packet, but the node doesn’t receive it.

I double and triple checked the keys and EUIs to make sure they are correct.

If the JR is being turned in to a JA it’s nothing to do with the EUI’s & key and everything to do with the reception of the JA by the device - the forum is littered with “node doesn’t get JA” type posts - TL;DR: node too close to gateway or poor/faulty antenna

Ah yes of course. That makes sense.

I have tried using pieces of wire as a small antenna and moved well away from the gateway when testing, but still mixed results - sometimes -1118 and sometimes -1116.

May I ask, what exactly does the -1118 status code mean? I see it translates to RADIOLIB_LORAWAN_NEW_SESSION but I don’t really understand if it indicates success or not. I assume only a zero should be returned if it was successful.

Also what does a positive 1 status code mean when attempting to send uplink?

Which version are you using? And which example are you running - or have derived your code from?

LORAWAN_NEW_SESSION (-1118) means you have joined - which is a good thing.

LORAWAN_NO_DOWNLINK (-1116) is no downlink - which is just saying that after the uplink there was no downlink which is pretty normal.

The examples try to highlight this but I can see how they aren’t really as obvious as they could be. I shall have the documentation maintainer flogged & add some clarity.

RADIOLIB_ERR_NONE is 0 but that doesn’t help report what occurred when you called a function that does something that could come have a number of states - the join could restore a previous session (-1117) or start a new one (-1118) or if the JA is not heard, return LORAWAN_NO_DOWNLINK (-1116).

Something very very weird has occurred because there isn’t a return to allow that - I’d have to see your code to be able to figure out the details.

You have mixed versions of RadioLib - a new one has come out over a week ago (7.0). The new version has breaking changes w.r.t. LoRaWAN and comes with updated examples that are slightly more informative than the one you are using.

In 7.0, this is a valid return code for uplinks, as that means a downlink was received (in Rx1).

(RadioLib’s LoRaWAN API is now as good as fixed going forward.)

Only the very brave use point Zero releases - I was looking at 6.6.0.

The API is fixed or the code? :crazy_face:

I’ll figure out some sort of flow chart for the return codes!

7.0.1 is about the be released indeed…

No hard promises there… :wink: but hopefully both!

Are you sure -1116 is a good thing? because after attempting to send an uplink straight after i get a -1101 status code. Here is the code I’m using. I’m using radiolib 7.0.0:

#include <RadioLib.h>
#include "EspHal.h"

EspHal* hal = new EspHal(14, 12, 13);

const uint32_t uplinkIntervalSeconds = 5UL * 60UL;

#define RADIOLIB_LORAWAN_JOIN_EUI  REMOVED
#define RADIOLIB_LORAWAN_DEV_EUI   REMOVED

#define RADIOLIB_LORAWAN_APP_KEY   REMOVED
#define RADIOLIB_LORAWAN_NWK_KEY  REMOVED

uint64_t joinEUI =   RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI  =   RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };

const LoRaWANBand_t Region = AU915;
const uint8_t subBand = 2;

// NSS pin:   4
// DIO0 pin:  2
// NRST pin:  17
// DIO1 pin:  5
SX1276 radio = new Module(hal, 4, 2, 17, 5);

LoRaWANNode node(&radio, &Region, subBand);

static const char *TAG = "main";

extern "C" void app_main(void) {

   printf("radiohead test example\n");

   int state;

   printf("Initializing radio...\n");
   state = radio.begin();
   printf("Radiolib returned status code: %d\n", state);

   printf("Initializing LoRaWAN node...\n");
   state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
   printf("Radiolib returned status code: %d\n", state);

   printf("Joining LoRaWAN network...\n");
   state = node.activateOTAA();
   printf("Radiolib returned status code: %d\n", state);

   printf("Ready! \n");

   while (true) {
      printf("Attempting to send uplink...\n");
      
      uint8_t value1 = 123;
      uint8_t uplinkPayload[1];
      uplinkPayload[0] = value1;

      state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
      printf("Radiolib returned status code: %d\n", state);

      vTaskDelay(uplinkIntervalSeconds * 1000 / portTICK_PERIOD_MS);
   }
}

Also when I get the occasional -1118 status code and it sends an uplink successfully, I get no payload in the console, just and empty json object.

Bit hard to say, I was referring to 6.6.0, you are referring to 7.0.0. And as we dropped NO_DOWNLINK in 7.0.0 it’s seems a bit moot.

Also, we are now on 7.0.1 …

I suspect you are hoping to learn LW via an implementation with hammering rather than via the Learn section, which could potentially work, we can see how this unpacks. But you knowing what is meant to happen via the Learn section, which I believe the brave & handsome documentation chap linked to in the notes.md will explain far more than I can here.

If memory serves, -1101, is a not joined - which could be keys or could be not heard the JA. I very dare you to look up these codes, they are in TypeDef.h, there is also a ‘what’s that error code’ lookup in config.h. LW is sufficiently complex that porting to your own example without making use of the supplied examples is somewhat inefficient. Using the PIO/Arduino examples, however distasteful, gives you a view of what is expected to happen before you roll your own.

It would also be super useful if you could tell us where these codes occur for you by including the serial output - and vary the message so it tells us what it was doing when it got the status code and add timestamps so we know what the timings look like.

You also may find that various restrictions on how quickly you can use up airtime may play a part - sending an uplink hot on the tail of a join isn’t part of the federal plan of AU, I’d give it 10 seconds, I can lookup what I normally get away with later.

Please can you provide a screens shot of the console and if you click the line you can also share the details of the entry. The payload won’t actually be turned in to JSON unless you have a Payload Formatter but you should expect to see your 0x7B value. The only items to redact are keys - App, Nwk or API - everything else is transmitted at some point in plain text over the air so is not a security risk.

The flow chart for return codes is WIP - it’s currently “regen katten en honden” here so all hands to the pumps.

Yeah I have a habit of going into things like this head-first. I’ll take a look at the learn section and see if I can get something out of that.

I have been consulting this page for the meaning of the error codes although it doesn’t seem to be apparent what radiolib version this corresponds to.

Agreed, I have few of other boards I can test with, or even try to just run the arduino framework on my esp32 board so I can run the example in the library directly. I’ll let you know my findings.

However, about the example I posted above, I was basically copy-pasting the arduino example line-for-line. There was very little I had to change to adapt to ESP-IDF. I pretty much just added the esp-hal from the esp-idf example in radiolib and simplified the serial output.

I have updated the example to describe what is happening and timestamps:

#include <RadioLib.h>
#include "EspHal.h"

EspHal* hal = new EspHal(14, 12, 13);

const uint32_t uplinkIntervalSeconds = 5UL * 60UL;

#define RADIOLIB_LORAWAN_JOIN_EUI  REDACTED

#define RADIOLIB_LORAWAN_DEV_EUI   REDACTED

#define RADIOLIB_LORAWAN_APP_KEY   REDACTED

#define RADIOLIB_LORAWAN_NWK_KEY   REDACTED

uint64_t joinEUI =   RADIOLIB_LORAWAN_JOIN_EUI;
uint64_t devEUI  =   RADIOLIB_LORAWAN_DEV_EUI;
uint8_t appKey[] = { RADIOLIB_LORAWAN_APP_KEY };
uint8_t nwkKey[] = { RADIOLIB_LORAWAN_NWK_KEY };

const LoRaWANBand_t Region = AU915;
const uint8_t subBand = 2;

// NSS pin:   4
// DIO0 pin:  2
// NRST pin:  17
// DIO1 pin:  5
SX1276 radio = new Module(hal, 4, 2, 17, 5);

LoRaWANNode node(&radio, &Region, subBand);

static const char *TAG = "main";

extern "C" void app_main(void) {
   printf("[%ld ms] starting the radiohead\n", esp_log_timestamp());

   int state;

   printf("[%ld ms] Initializing radio (radio.begin())...\n", esp_log_timestamp());
   state = radio.begin();
   printf("[%ld ms] Radiolib returned status code: %d\n", esp_log_timestamp(), state);

   printf("[%ld ms] Initializing LoRaWAN node (node.beginOTAA())...\n", esp_log_timestamp());
   state = node.beginOTAA(joinEUI, devEUI, nwkKey, appKey);
   printf("[%ld ms] Radiolib returned status code: %d\n", esp_log_timestamp(), state);

   printf("[%ld ms] Joining LoRaWAN network (node.activateOTAA())...\n", esp_log_timestamp());
   state = node.activateOTAA();
   printf("[%ld ms] Radiolib returned status code: %d\n", esp_log_timestamp(), state);

   while (true) {
      printf("[%ld ms] Attempting to send uplink (node.sendRecieve())...\n", esp_log_timestamp());

      uint8_t value1 = 123;
      uint8_t uplinkPayload[1];
      uplinkPayload[0] = value1;

      state = node.sendReceive(uplinkPayload, sizeof(uplinkPayload));
      printf("[%ld ms] Radiolib returned status code: %d\n", esp_log_timestamp(), state);

      vTaskDelay(uplinkIntervalSeconds * 1000 / portTICK_PERIOD_MS);
   }
}

Here is the serial output of a successful uplink:

[331 ms] Starting the radiohead
[334 ms] Initializing radio (radio.begin())...
I (338) gpio: GPIO[14]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (347) gpio: GPIO[12]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (357) gpio: GPIO[13]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (366) gpio: GPIO[4]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (375) gpio: GPIO[2]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (384) gpio: GPIO[5]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (394) gpio: GPIO[17]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
[415 ms] Radiolib returned status code: 0
[415 ms] Initializing LoRaWAN node (node.beginOTAA())...
[416 ms] Radiolib returned status code: 0
[417 ms] Joining LoRaWAN network (node.activateOTAA())...
[6010 ms] Radiolib returned status code: -1118
[6010 ms] Ready! 
[6010 ms] Attempting to send uplink (node.sendRecieve())...
E (6395) gpio: gpio_install_isr_service(502): GPIO isr service already installed
[11483 ms] Radiolib returned status code: 1

And here is when it fails. Understandably the uplink attempt returns -1101 since the join process already failed.

[331 ms] Starting the radiohead
[334 ms] Initializing radio (radio.begin())...
I (338) gpio: GPIO[14]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (347) gpio: GPIO[12]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (357) gpio: GPIO[13]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (366) gpio: GPIO[4]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (375) gpio: GPIO[2]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (384) gpio: GPIO[5]| InputEn: 1| OutputEn: 0| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (394) gpio: GPIO[17]| InputEn: 1| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
[415 ms] Radiolib returned status code: 0
[415 ms] Initializing LoRaWAN node (node.beginOTAA())...
[416 ms] Radiolib returned status code: 0
[417 ms] Joining LoRaWAN network (node.activateOTAA())...
[7067 ms] Radiolib returned status code: -1116
[7067 ms] Ready! 
[7067 ms] Attempting to send uplink (node.sendRecieve())...
[7067 ms] Radiolib returned status code: -1101

I checked the log of a successful uplink packet int the console and you were right about the payload formatter not being configured correctly. The unformatted payload correctly returns the hex 7B which corresponds to my payload of “123”.

Or, as explicitly suggested, you could look in TypeDef.h as you know it matches with the rest of the code in the version of the library you are using? :man_shrugging:

Not so much updated as added - a line describing what happens next and then a line with the results code makes for overly verbose logs. Now the primary bug-fixer-in-chief of the LW module likes Big Logs, He Cannot Lie, but his tester likes the logs succinct.

Perhaps have “HH:MM:SS did a thing, result = 1234”

Well something failed, dare I say you failed to look at TypeDef.h to see that -1116 is RADIOLIB_ERR_NO_JOIN_ACCEPT which means it did not receive a JA - having read the Learn section, you’ll know all about the join sequence and having looked at the console that pesky Join Accept thingy ties in with the Learn section about joining.

Then you artfully bounce in to forum or Google search for No Join Accept and see a blizzard of similar topics from those debugging No Join Accept - occasionally due to key or DevNonce issues, but almost always due to RF proximity.

The real acid test would be, is there a JA on device console - that says the config is fine but the device didn’t hear the JA for some reason.

Blush - but why did you have a payload formatter setup in the first place?

We are very close to having Amnesty International file a case against either or both of us for cruel or unusual punishment - traditionally we call a halt at post #20, last time you got to #28 with a request you read the notes.md written by @AwesomeDude. Along the way you tried LoRaMac-node on a Pico and then LMIC. Now you are on an ESP32 and hand rolling an ESP-IDF version. It has been suggested you read the Learn section. This is post #38. Math tells me that we have entered some form of Mission Impossible episode, the original proper one, not the films. Perhaps maybe you would make progress using the RadioLib LoRaWAN_Starter using PlatformIO using the Arduino framework - you don’t need to use a hammer to get that going, that’s already been done many times since last November, many many times. After you’ve done the LW Dance of Success, then you can make an alteration at a time building up knowledge & confidence.

I’m legal obliged to suggest you do not take up skydiving as a hobby. I’m not sure it will end well. :wink:

A cracking idea!

Ok, I will try to do something more like that in the future. It was only a test example though, I didn’t intend on it to be made into something pretty.

Well yes I knew that, but my whole conundrum was about why this is happening. Why the node isn’t receiving the JA even though I can see it being sent why the gateway in the console. Still sounds awfully a lot like a range issue though, huh? The SNR and RSSI in the console further confirmed this, indicating that the signal was quite strong, maybe still too strong even though I had stubby antennas on both ends and a a 20m gap.

I got on my bike and rode several kilometers away with the node and it worked very well. I was even able to connect to other gateways. So maybe this was a range issue all along? I still got an occasional -1116 but I assume thats just the connection not always being perfect.

Hopping between 3 different microcontrollers and going between an abandoned loramac port, LMIC, and radiolib definitely wasn’t the smartest idea.

At this rate, I shall just code my parachute in mid-air! Although I hear radiolib comes with a deploy_parachute() function. Just gotta make sure I’ve flashed the firmware before I jump!

Hope it was a pedal bike - but it does sound like your stubby antennas and 20m are not quite enough but perhaps several kilometres for a test is overkill.

The JA not being heard due to proximity is a common theme on the forum - almost a fortnightly occurrence. But it is hugely variable by quality of antenna and who & how the radio was built. The dizzying array of devices & gateways on my desk shouldn’t work in theory, but does in practise. But if it’s looking dicey, I can move stuff around.

The PR has not been merged because @stevencellist refuses to run any unit tests on it.