Over-the-air-activation OTAA with LMIC

first thought : the TTN uno board doesn’t use LMIC while the Adafruit feather does.
So these should be 2 totally different sketches … not only the keys.

Thanks for the thought.

Indeed. I used entirely different code on the TTN Uno and the Feather M0. In the sketch for the Feather M0 I got messages through to my ttn console if I used the DevEUI that I previously used for the Uno. If I then only change the DevEUI in that sketch (a new one generated by TTN), it doesn’t work.

In the TTN Uno DevEUI is determined by the manufacturer. Do I understand correctly that for the LMIC route with an RFM95 it is not and it needs to be assigned in the sketch? If so, why does one DevEUI work (the one I accidentally copied from an entirely different node) and another (generated by ttn) does not?

you copied the key to the new lmic device… TTN thinks it still the first device you registered , with TTN UNO the keys are in the main module the rn2483, so if you use the generated key for that node and add it to a sketch for another TTN uno it won’t work.

Understood. This helps me understand a little bit better.

So, because of re-using the DevEUI of the Uno, TTN thinks I am still using that TTN UNO node, whereas I am actually using the feather M0. Since TTN receives the messages, this at least tells me that all the Feather hard- and software works.

What is puzzling me is when I then (i) register a new device on TTN in the same application, (ii) have TTN generate a new DevEUI, (iii) change only the DevEUI in the sketch, and (iv) upload the sketch to the feather, I don’t see any messages coming on on the TTN console for that application.

https://www.thethingsnetwork.org/docs/devices/

Ah, thank you. So the TTN generate button is for ABP only! Does the feather/RFN95 have an hardware defined DevEUI and how do I find out about it? Guess I have some more reading/understanding to do.

1 Like

or use search here on the site

When you register a new device the APP key will be different, did you update both the EUI to the generated value and the App key?

I never thought of the App key being different (assuming, wrongly so, that it registers to the same application). Will give it a try. Thank you!

… SOLVED … Many thanks!

Hello! I have a custom single channel LoRa Gateway and I started with ABP which worked fine. Now I am trying the OTAA and although I can see the first packet both on my gateway console

Packet RSSI: -67, RSSI: -94, SNR: 9, Length: 23
rxpk update: {“rxpk”:[{“tmst”:4046223465,“chan”:0,“rfch”:0,“freq”:868.100000,“stat”:1,“modu”:“LORA”,“datr”:“SF7BW125”,“codr”:“4/5”,“lsnr”:9,“rssi”:-67,“size”:23,“data”:“AAluftWgAgp4UZD9jbfr4eSA77r9ZZs=”}]}

and on the TTN gateway console

{
  "gw_id": "eui-b827ebffff0292e1",
  "payload": "AAHQs3DyQJAE95/ZURhoXq2/oqb2UMM=",
  "dev_eui": "AD5E681851D99FF7",
  "lora": {
    "spreading_factor": 7,
    "bandwidth": 125,
    "air_time": 61696000
  },
  "coding_rate": "4/5",
  "timestamp": "2019-01-23T18:05:42.068Z",
  "rssi": -67,
  "snr": 9,
  "app_eui": "049040F270B3D001",
  "frequency": 868100000
}

But I don’t see the rest of the process to continue. In example the Serial monitor repeats this state EV_TXSTART

20:05:34.479 -> Starting
20:05:34.547 -> Packet queued
20:05:34.547 -> 196: EV_JOINING
20:05:41.512 -> 438616: EV_TXSTART
20:06:50.618 -> 4768566: EV_TXSTART
20:07:57.008 -> 8927362: EV_TXSTART
...

I have copy pasted very carefully the OTAA credentials to the sketch.
Also I have made these configurations to “agree” with EU frequencies and the Arduino Uno as “Mobilefish” suggests

// project-specific definitions
//#define CFG_eu868 1
#define CFG_eu868 1
//#define CFG_au921 1
//#define CFG_as923 1
// #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP /* for as923-JP */
//#define CFG_in866 1
#define CFG_sx1276_radio 1
//#define LMIC_USE_INTERRUPTS
#define DISABLE_PING
#define DISABLE_BEACONS
#define LMIC_DEBUG_LEVEL 0
#define USE_IDEETRON_AES

Also, how the different app eui and dev eui accross three continuous messages is explained?


Anyway, no matter my efforts I still have not achieved a OTAA connection, if anyone could help me that would be great. Thank you!

Single channel gateways are not LoRaWAN specs conform. You can’t use a single channel gateway for OTA.

Unless TTN has changed detection for single channel gateways, then: if the single channel gateway supports downlinks, then it also supports OTAA.

But indeed, single channel gateways are not compliant and using them needs a lot of tweaking, especially in the nodes to force them to use only that single channel (and SF).

As TTN is not even showing the Join Accept in the gateway’s Traffic page, maybe:

  • It does not recognize the AppEUI/DevEUI or cannot validate the MIC from the Join Request. Am I right to assume nothing shows in the application’s Data page in TTN Console? That might indicate the AppKey, AppEUI and/or DevEUI are wrong. (See Hex, lsb or msb?)
  • It refuses the DevNonce, see OTAA shows "Activation DevNonce not valid: already used".
  • It refuses the single channel gateway to transmit the Join Accept, as it somehow detected it does not support downlinks. Does your gateway even support downlinks?

Clicking on a Join Request might give you some more information in the Trace details.

Is one of them even what you’re expecting? (Every TTN provided AppEUI starts with 0x70B3D57ED, so it seems the third might be the expected one?) Are you sure all are transmitted by your device?

You’ll need to show us the code, and tell us which LMIC you’re using, and tell us what earlier suggestions from this topic you’ve tried. (It seems GitHub - mcci-catena/arduino-lmic: LoraWAN-MAC-in-C library, adapted to run under the Arduino environment might be the most up to date?)

And if yes: what if you move the node a few meters away from the gateway?

First of all thank you for the fast response! I will try to give you as many details I can.

About typos an lsb/msb on the keys, I have checked them so many times that I don’t think it’s that.
As for the DevNonce message, I don’t see it in the TTN console.
As for the downlinks, that is interesting and maybe the problem is here. How do I check if my gateway supports downlinks? Is this part of the configuration of the packet forwarder or the configuration in TTN gateway settings?

About the transmitted packets that I see in the TTN gateway console, there is one for every time I power on the node. Also, the code of my node is based on the https://github.com/mcci-catena/arduino-lmic

#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>

#ifdef COMPILE_REGRESSION_TEST
# define FILLMEIN 0
#else
# warning "You must replace the values marked FILLMEIN with real values from the TTN control panel!"
# define FILLMEIN (#dont edit this, edit the lines that use FILLMEIN)
#endif

static const u1_t PROGMEM APPEUI[8]={ 0x09, 0x6E, 0x01, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
void os_getArtEui (u1_t* buf) { memcpy_P(buf, APPEUI, 8);}

static const u1_t PROGMEM DEVEUI[8]={ 0xA0, 0x02, 0xF2, 0x40, 0x0A, 0x78, 0x90, 0x04 };
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

static const u1_t PROGMEM APPKEY[16] = { 0x01, 0x12, 0xC5, 0x5E, 0x1B, 0x05, 0xBD, 0x22, 0x60, 0xF9, 0xC7, 0x48, 0x0F, 0x55, 0x03, 0x63 };
void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}

static uint8_t mydata[] = "Hello, world! OTAA";
static osjob_t sendjob;

const unsigned TX_INTERVAL = 20;

const lmic_pinmap lmic_pins = {
    .nss = 6,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 5,
    .dio = {2, 3, 4},
};

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("artKey: ");
              for (int i=0; i<sizeof(artKey); ++i) {
                Serial.print(artKey[i], HEX);
              }
              Serial.println("");
              Serial.print("nwkKey: ");
              for (int i=0; i<sizeof(nwkKey); ++i) {
                Serial.print(nwkKey[i], HEX);
              }
              Serial.println("");
            }
            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"));
            }
            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:
            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;
        default:
            Serial.print(F("Unknown event: "));
            Serial.println((unsigned) ev);
            break;
    }
}

void do_send(osjob_t* j){
    if (LMIC.opmode & OP_TXRXPEND) {
        Serial.println(F("OP_TXRXPEND, not sending"));
    } else {
        LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
        Serial.println(F("Packet queued"));
    }
}

void setup() {
    Serial.begin(9600);
    Serial.println(F("Starting"));

    #ifdef VCC_ENABLE
    pinMode(VCC_ENABLE, OUTPUT);
    digitalWrite(VCC_ENABLE, HIGH);
    delay(1000);
    #endif

    os_init();
    LMIC_reset();

    do_send(&sendjob);
}

void loop() {
    os_runloop_once();
}

I’m sure the software comes with some documentation? It’s not so much in the configuration of the gateway/packet forwarder, but simply a feature which should be documented when supported. When in doubt then tell us what you’re using.

APPEUI looks good, that should indeed be LSB in LMIC, so end with 0x7ED5B370 for TTN. Good.

DEVEUI should be LSB too, but APPKEY should be MSB. Did you check that? (As an aside, I’d leave the comments for the EUIs and key in place…)

And that one has the same AppEUI each time, I assume? So the other two from the screenshot are just some other LoRa or LoRaWAN packets that the gateway received?

So there’s nothing special in the Trace part of the Join Request, when clicking it in TTN Console?

given your code seems to look generic how are you restricting your device frequency to match your single channel gateway?

1 Like

I am using the tftelkamp/single_chan_pkt_fwd library for the gateway. And if downlinks are essential for OTAA to work then that explains it, because it is quite clear in the Read.me file that downlinks are not yet supported.

So, taking this into consideration, could you please suggest me another library for a simple Raspberry Pi single channel gateway?

Also, where could I read more details on how ABP and OTAA work under the hood?

Thank you for the answer! Well, I am not sure if that is enough, but I am doing the following.
Is there anything else I should pay attention to?

In gateway:

// Set spreading factor (SF7 - SF12)
sf_t sf = SF7;
// Set center frequency
uint32_t freq = 868100000; // in Mhz! (868.1)

In node (at least in the ABP version):

LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
// While keeping the rest of frequencies commented out.

Check out this thread :Can LMIC 1.6 be set up to use a single channel and SF?

The issue at the end of the day is that none of these libraries have been written with single channel gateways in mind, fighting against the tide :slight_smile:

I would fall back to https://github.com/matthijskooijman/arduino-lmic library first and prove the ABP code is doing what 100% it should, check uploads, downloads, acknowledgments etc, then turn to the OTAA example code (not the same as ABP) - check out the examples. Be careful you are starting from the example code supplied from its library too.

MCCI lmic library seems to extend some functionality - but I would not use first, this library caught me out on the config file for a day or so, it seems to work fine now - default is set to USA frequencies etc.

Check this fork of the single channel software, with the mods described here. Not necessarily you solve everything, but at least downlinks are supported. And receiving downlinks could also be problematic on the node (some slow platform need clock error relaxation).