Lmic esp32 no join request

Hi,
I’m trying to send some data with my heltec Lora board.
But I have the problem that with the code I “wrote” the gateway is not getting a join request.
Im using an Heltec Lora v2 board and im having my own gateway with LoraWan at EU868

That’s the code:

#include <lmic.h>
#include <Wire.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_BME280.h>
#include <hal/hal.h>
#include <SPI.h>

float temp;
float pressure;
float humidity;
float wind;

int wind_cnt;
int anopin = 36; //PIN for anemometer input

Adafruit_BME280 bme;

static const u1_t PROGMEM APPEUI[8] = {DELETED};
void os_getArtEui (u1_t* buf) {
  memcpy_P(buf, APPEUI, 8);
}

static const u1_t PROGMEM DEVEUI[8] = {DELETED};
void os_getDevEui (u1_t* buf) {
  memcpy_P(buf, DEVEUI, 8);
}

static const u1_t PROGMEM APPKEY[16] = {DELETED};
void os_getDevKey (u1_t* buf) {
  memcpy_P(buf, APPKEY, 16);
}
boolean join_success = false;
uint8_t tx_payload[7];

static osjob_t sendjob;

// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 180; //for testing

//LoRa pin mapping ESP32 (HELTEC LORA Board V2)
const lmic_pinmap lmic_pins = {
  .nss = 18,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = 14,
  .dio = {26, 34, 35},
};

void printHex2(unsigned v) {
  v &= 0xff;
  if (v < 16)
    Serial.print('0');
  Serial.print(v, HEX);
}

void onEvent (ev_t ev) {
  Serial.print(os_getTime());
  Serial.print(": ");
  switch (ev) {
    case EV_SCAN_TIMEOUT:
      Serial.println(F("EV_SCAN_TIMEOUT"));
      break;
    case EV_BEACON_FOUND:
      Serial.println(F("EV_BEACON_FOUND"));
      break;
    case EV_BEACON_MISSED:
      Serial.println(F("EV_BEACON_MISSED"));
      break;
    case EV_BEACON_TRACKED:
      Serial.println(F("EV_BEACON_TRACKED"));
      break;
    case EV_JOINING:
      Serial.println(F("EV_JOINING"));
      break;
    case EV_JOINED:
      Serial.println(F("EV_JOINED"));
      {
        u4_t netid = 0;
        devaddr_t devaddr = 0;
        u1_t nwkKey[16];
        u1_t artKey[16];
        LMIC_getSessionKeys(&netid, &devaddr, nwkKey, artKey);
        Serial.print("netid: ");
        Serial.println(netid, DEC);
        Serial.print("devaddr: ");
        Serial.println(devaddr, HEX);
        Serial.print("AppSKey: ");
        for (size_t i = 0; i < sizeof(artKey); ++i) {
          if (i != 0)
            Serial.print("-");
          printHex2(artKey[i]);
        }
        Serial.println("");
        Serial.print("NwkSKey: ");
        for (size_t i = 0; i < sizeof(nwkKey); ++i) {
          if (i != 0)
            Serial.print("-");
          printHex2(nwkKey[i]);
        }
        Serial.println();
        join_success = true;
      }
      // Disable link check validation (automatically enabled
      // during join, but because slow data rates change max TX
      // size, we don't use it in this example.
      LMIC_setLinkCheckMode(0);
      break;
    case EV_JOIN_FAILED:
      Serial.println(F("EV_JOIN_FAILED"));
      break;
    case EV_REJOIN_FAILED:
      Serial.println(F("EV_REJOIN_FAILED"));
      break;
    case EV_TXCOMPLETE:

      Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
      if (LMIC.txrxFlags & TXRX_ACK)
        Serial.println(F("Received ack"));
      if (LMIC.dataLen) {
        Serial.print(F("Received "));
        Serial.print(LMIC.dataLen);
        Serial.println(F(" bytes of payload"));
      }
      // Schedule next transmission
      os_setTimedCallback(&sendjob, os_getTime() + sec2osticks(TX_INTERVAL), do_send);
      break;
    case EV_LOST_TSYNC:
      Serial.println(F("EV_LOST_TSYNC"));
      break;
    case EV_RESET:
      Serial.println(F("EV_RESET"));
      break;
    case EV_RXCOMPLETE:
      // data received in ping slot
      Serial.println(F("EV_RXCOMPLETE"));
      break;
    case EV_LINK_DEAD:
      Serial.println(F("EV_LINK_DEAD"));
      break;
    case EV_LINK_ALIVE:
      Serial.println(F("EV_LINK_ALIVE"));
      break;
    case EV_TXSTART:
      Serial.println(F("EV_TXSTART"));
      break;
    case EV_TXCANCELED:
      Serial.println(F("EV_TXCANCELED"));
      break;
    case EV_RXSTART:
      /* do not print anything -- it wrecks timing */
      break;
    case EV_JOIN_TXCOMPLETE:
      Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));
      break;

    default:
      Serial.print(F("Unknown event: "));
      Serial.println((unsigned) ev);
      break;
  }
}

void do_send(osjob_t* j) {
  // Check if there is not a current TX/RX job running
  if (LMIC.opmode & OP_TXRXPEND) {
    Serial.println(F("OP_TXRXPEND, not sending"));
  } else {
    // Prepare upstream data transmission at the next possible time.

    getSensorData();
    generate_payload(temp, pressure, humidity, wind);

    Serial.print("Payload: ");
    int x = 0;
    while (x < sizeof(tx_payload)) {
      printHex2(tx_payload[x]);
      Serial.print(" ");
      x++;
    }
    Serial.println();

    LMIC_setTxData2(1, tx_payload, sizeof(tx_payload), 0);
    Serial.println(F("Packet queued"));
  }
  // Next TX is scheduled after TX_COMPLETE event.
}

void setup() {
  delay(5000);
  Serial.begin(115200);
  pinMode(anopin, INPUT_PULLDOWN);
  bme.begin(0x76); //define I2C-Address

  //SPI pin mapping ESP32 (HELTEC LORA Board V2)
  SPI.begin(5, 19, 27, 18);
  getSensorData();

#ifdef VCC_ENABLE
  // For Pinoccio Scout boards
  pinMode(VCC_ENABLE, OUTPUT);
  digitalWrite(VCC_ENABLE, HIGH);
  delay(1000);
#endif

  // LMIC init
  os_init();
  // Reset the MAC state. Session and pending data transfers will be discarded.
  LMIC_reset();

  // Start job (sending automatically starts OTAA too)
  do_send(&sendjob);

  //Set FS for RX2 (SF9 = TTN,TTS EU)
  LMIC.dn2Dr = DR_SF9;

}

void loop() {
  os_runloop_once();
}

void getSensorData() {
  temp = bme.readTemperature();
  pressure = bme.readPressure() / 100;
  humidity = bme.readHumidity();

  meassure_wind();
}

void meassure_wind() {
  wind_cnt = 0;
  attachInterrupt(anopin, intrrupt_cnt, RISING);
  delay(3000); //Time for measure counts
  detachInterrupt(anopin);
  wind = ((float)wind_cnt / (float)3 * 2.4) / 2; //Convert counts & time to km/h
}

void intrrupt_cnt() {//On count detected
  wind_cnt++;//Add one count
}

void generate_payload(float temperature, float airpressure, float humidity, float windspeed) {

  uint8_t payload[7];

  int tmp = ((int)(temperature * 100)) + 5000;
  int pre = (int)(airpressure * 10);
  byte hum = (int)(humidity * 2);
  int wnd = (int)(windspeed * 10);

  payload[0] = tmp >> 8;
  payload[1] = tmp;
  payload[2] = pre >> 8;
  payload[3] = pre;
  payload[4] = hum;
  payload[5] = wnd >> 8;
  payload[6] = wnd;

  int i = 0;
  while (i < sizeof(payload)) {
    tx_payload[i] = payload[i];
    i++;
  }
}

And im getting no join accept or an request.

13:10:01.018 -> 31814096: EV_JOIN_TXCOMPLETE: no JoinAccept
13:10:01.018 -> 31814103: EV_JOIN_FAILED

I could not figure out why it is not working.
Maybe you guys will see an error…

thank you very much!

Hi,
Which LMIC library are you using, which (example) sketch exactly (provide link) are you using and which Heltec board exactly is this about?

EV_JOIN_TXCOMPLETE indicates a join request was sent but a join accept was not received/recognized. For causes and solutions please search te forum.

This issue has been addressed on the forum endless times already.
Always search the forum for existing information first before creating a new topic.

Also have a look at:

and:

Big ESP32 + SX127x topic part 3

What is the exact gateway make and model?

Do you see any raw packets in the gateway’s TTN pages, from your node or others, if you leave that view open while your node tries to transmit?

What do you see in the gateway’s computer’s own internal logs? Is the packet forwarder running? Does it receive any packets, even bad CRC ones?

Thank you for your reply!
I have found a Topic for my problem but I assume that’s because I did not search enough.
I will search again.

I am using the Lmic library from Terry Moore with an Heltec Lora esp32 V2.
(SX1276(V2), 868-915MHz)

Again thank you for your help and your tips!

I’m working with a MikroTik wAP LoRa8 Gateway which is working with a lot of Nodes.

No that’s my problem and that’s what I don´t understand…
I’m getting nothing on the Gateway Live data Tab… That’s what’s making me wonder what I did wrong…

Well, iv never looked into this log… Thank you for that tip there are some messages which are interesting. I’ve even got a “Join request” as message type but the CRC status is an error… What does this mean?
Another message type is “Proprietary” but both of these messages are without an Device address so I don’t know if these two messages are from the same Device…

Thank you for your help!

Make sure your nde is sufficiently distanced from the GW to avoid overload - how far appart are they? What RSSI value is seen for this errored message?

You say the gateway is working with lots of nodes but you are getting nothing in the live tab, so what nodes are you referring to?

Look in your console under your gateways, what do you see here?

If you select the relevant message, be it a join request, an uplink or downlink, you will get a lot of information from it.

Well, I meant I’m getting nothing from the Heltec board with the code I meant in the original posting.
I’m getting multiple messages from multiple LoraNodes in the live tab from the Gateway… just not from the “weather station” I’m trying to build.

Yes, I know this but that’s the problem. I’m getting nothing from this Device in the Live Data from the console. Not even the join request…

“This part of the post is obsolete!”
Only if I’m logged into the Mikrotik device itself I can see something from a device trying to connect…
but its I important to say that’s not every time I’m resetting the Heltec board so I’m not sure if it’s this device but this request only shows up if I’m trying to connect so I would assume it’s the device.

That is a screenshot from the log directly from the Gateway. These messages are not showing up in ttn.

After I posted this I got the same join request without a Device address but the heltec board isn’t even powered right now.

Thank you for your help!

Have you checked the antenna on the Heltec board?

How far is the Helteck from the gateway antenna?

When you power the Helteck the join request should be with in a couple of seconds, should show up in the Mikrotik and your TTN console.

Double check your ID in your code and make sure the LSB and MSB is correct.

// End-device Identifier (u1_t[8]) in lsb format

#define OTAA_DEVEUI 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

// Application Identifier (u1_t[8]) in lsb format

#define OTAA_APPEUI 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

// Application Key (u1_t[16]) in msb format

#define OTAA_APPKEY 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00

Good morning.

As far as I can check this I’m pretty sure everything is fine. The antenna does not seem to be damaged and it is properly attached to the board itself.

The gateway is about 40m away and there is a building between me and the Gateway. I will check if this is a problem after this post.

No. It does not show up. In the ttn console there is nothing about the board and not in the Mikrotik as far as i can see.

static const u1_t PROGMEM APPEUI[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00;
void os_getArtEui (u1_t* buf) {
  memcpy_P(buf, APPEUI, 8);
}

static const u1_t PROGMEM DEVEUI[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void os_getDevEui (u1_t* buf) {
  memcpy_P(buf, DEVEUI, 8);
}

static const u1_t PROGMEM APPKEY[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
void os_getDevKey (u1_t* buf) {
  memcpy_P(buf, APPKEY, 16);

I copied the keys directly from the Application I created from TTn. Before that, I converted it to the format needed.

This should be sufficient attenuation and not too much, maybe try to move a few meters to make sure, not too close.

Here again there is a button in the console doing the job for you. The ‘<>’ and then the ‘lsb’ or ‘msb’

image

Okay I will try and move a bit.

Yes, that’s what I meant with: “I copied it from ttn”
So the key should be okay.

I will answer you back after I moved the board a bit for testing.

Did you check your endianness - the OTAA Dev & Join EUI’s need to be ‘the other way round’.

OH… they need to be the other way around?
Do I understand this correctly? for example, the DEVeui “12345” is “54321” if I’m pasting it into the Arduino IDE?

If that’s the case I did not know this…

Yes & No, they need to be the other way round regardless of which IDE you are using - that’s what the message means in the code:

// This EUI must be in little-endian format, so least-significant-byte
// first. When copying an EUI from ttnctl output, this means to reverse
// the bytes. For TTN issued EUIs the last bytes should be 0xD5, 0xB3,
// 0x70.
static const u1_t PROGMEM APPEUI[8]={ FILLMEIN };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

// This should also be in little endian format, see above.
static const u1_t PROGMEM DEVEUI[8]={ FILLMEIN };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

When you click the <> to get the EUI in array format, there are a couple of little horizontal arrows and the letters ‘msb’, click the arrows, it will turn them in to ‘lsb’ and you are good to click the clipboard button.

Errors in node registration details are important, but won’t matter until raw packets are being received at the times when the node is trying to transmit.

What is the public/private syncword preamble setting in the gateway’s internal configuration? For TTN both the gateway and the node need to be set to public.

How are you configuring the node to operate on the EU868 regional settings?

Normally I’d say you should temporarily modify it to print all radio settings when it transmits, but it’s harder to do that in a C library built in the context of Arduino code. (And even where it is achievable, note the “temporary” - often logging like that would break receive timing, so it’s something you’d add to make sure transmissions worked and then remove again before worrying about receive)

1 Like

Okay, Thank you for explaining this to me… I did not know this but did it right. I copied it by pressing “<>” and copying the “msb” format.
So the Keys are pasted in the right format.

Good morning and thank you for your Time!

The Gateway is set to “public” in the Mikrotik configuration and I had no problems with the gateway so far with other Nodes.

I’m not sure where I can find this setting in the code above. I have to admit that I did not write the part with the LoraWan connection and the Payload by my self.
I can’t find the setting in the code above…

I moved it so I’m in direct sight of the building with the gateway but still about 50 metres away from it.
Nothing changed at all…

When you start up the Heltec, monitor the serial port and you should see the join request and the telemetry.

1 Like