Over-the-air-activation OTAA with LMIC

Without the adjustment, it seems that the RX1 window is opened slightly early:

>>> (445987-131511)*16 - 62000
4969616 us

This takes the time between TX and RX, measured in 16us clocks, subtracting 62ms for the TX airtime. The RX window starts at 5 seconds after TX end, reception is intended to start around the centre of the preamble (so slightly later than the RX window start). Perhaps the 62ms isn’t exactly correct, it would be interesting to see what LMIC calculates for that here, as well as what is written to txend here.

What hardware are you using?

Hardware: Arduino Uno with a Dragino Lora Shield (1.2, http://wiki.dragino.com/index.php?title=Lora_Shield)

Please find the requested debug info below:

Starting OTAA New sample
RXMODE_RSSI
219: engineUpdate, opmode=0x808
Packet queued
1294: EV_JOINING
2463: engineUpdate, opmode=0xc
98637: engineUpdate, opmode=0xc
airtime: 3856
98954: TXMODE, freq=868100000, len=23, SF=7, BW=125, CR=4/5, IH=0
LMIC.txend: 100062
412597: RXMODE_SINGLE, freq=868100000, SF=7, BW=125, CR=4/5, IH=0
478073: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
488145: engineUpdate, opmode=0xc
4354565: engineUpdate, opmode=0xc
airtime: 3856
4354885: TXMODE, freq=868300000, len=23, SF=7, BW=125, CR=4/5, IH=0
LMIC.txend: 4355736
4668271: RXMODE_SINGLE, freq=868300000, SF=7, BW=125, CR=4/5, IH=0
4733747: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
4743819: engineUpdate, opmode=0xc
8915252: engineUpdate, opmode=0xc
airtime: 7072
8915571: TXMODE, freq=868500000, len=23, SF=8, BW=125, CR=4/5, IH=0
LMIC.txend: 8919699
9232331: RXMODE_SINGLE, freq=868500000, SF=8, BW=125, CR=4/5, IH=0
9297710: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
9307782: engineUpdate, opmode=0xc
16254266: engineUpdate, opmode=0xc
airtime: 7072
16254587: TXMODE, freq=868100000, len=23, SF=8, BW=125, CR=4/5, IH=0
LMIC.txend: 16258587
16571218: RXMODE_SINGLE, freq=868100000, SF=8, BW=125, CR=4/5, IH=0
16636599: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
16646543: engineUpdate, opmode=0xc
24929268: engineUpdate, opmode=0xc
airtime: 12864
24929590: TXMODE, freq=868300000, len=23, SF=9, BW=125, CR=4/5, IH=0
LMIC.txend: 24939311
25252134: RXMODE_SINGLE, freq=868300000, SF=9, BW=125, CR=4/5, IH=0
25317322: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
25428487: Setup channel, idx=3, freq=867100000
25428532: Setup channel, idx=4, freq=867300000
25430381: Setup channel, idx=5, freq=867500000
25433436: Setup channel, idx=6, freq=867700000
25436491: Setup channel, idx=7, freq=867900000
25439699: EV_JOINED
netid = 921102
25441955: engineUpdate, opmode=0x808
airtime: 11584
25445369: TXMODE, freq=867100000, len=20, SF=9, BW=125, CR=4/5, IH=0
Packet queued
25446374: engineUpdate, opmode=0x888
LMIC.txend: 25452531
25515354: RXMODE_SINGLE, freq=867100000, SF=9, BW=125, CR=4/5, IH=0
25577918: RXMODE_SINGLE, freq=869525000, SF=9, BW=125, CR=4/5, IH=0
25831583: EV_TXCOMPLETE (includes waiting for RX windows)
25831631: engineUpdate, opmode=0x800

I have been away for a while (holiday and more). I just tested this and it works nicely with SF7. Thank you for the bug fixing!

I have the following issue with LMIC on my RPi3:

pi@rpi3:~/arduino-lmic/examples/raspi/ttn-otaa $ sudo ./ttn*
ttn-otaa Starting
RFM95 device configuration
CS=GPIO8 RST=GPIO22 LED=GPIO23 DIO0=Unused DIO1=Unused DIO2=Unused
DevEUI : B8xxxxxxxxxxxxxxxx
AppEUI : 70B3D5xxxxxxxxxxx
AppKey : Fxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
RXMODE_RSSI
14:21:41: 606: engineUpdate, opmode=0x8
Packet queued
14:21:41: EV_JOINING
614: engineUpdate, opmode=0xc
411793: engineUpdate, opmode=0xc
411856: TXMODE, freq=868100000, len=23, SF=7, BW=125, CR=4/5, IH=0
728365: RXMODE_SINGLE, freq=868100000, SF=7, BW=125, CR=4/5, IH=0
793841: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
804257: engineUpdate, opmode=0xc
4523130: engineUpdate, opmode=0xc
4523187: TXMODE, freq=868300000, len=23, SF=7, BW=125, CR=4/5, IH=0
4839701: RXMODE_SINGLE, freq=868300000, SF=7, BW=125, CR=4/5, IH=0
4905177: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
4915592: engineUpdate, opmode=0xc
9366812: engineUpdate, opmode=0xc
9366868: TXMODE, freq=868500000, len=23, SF=8, BW=125, CR=4/5, IH=0
9686656: RXMODE_SINGLE, freq=868500000, SF=8, BW=125, CR=4/5, IH=0
9752036: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
9762451: engineUpdate, opmode=0xc
16799609: engineUpdate, opmode=0xc
16799665: TXMODE, freq=868100000, len=23, SF=8, BW=125, CR=4/5, IH=0
17119450: RXMODE_SINGLE, freq=868100000, SF=8, BW=125, CR=4/5, IH=0
17184830: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
17195250: engineUpdate, opmode=0xc
24465252: engineUpdate, opmode=0xc
24465342: TXMODE, freq=868300000, len=23, SF=9, BW=125, CR=4/5, IH=0
24791158: RXMODE_SINGLE, freq=868300000, SF=9, BW=125, CR=4/5, IH=0
24856346: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
24866796: engineUpdate, opmode=0xc
37921119: engineUpdate, opmode=0xc
37921220: TXMODE, freq=868500000, len=23, SF=9, BW=125, CR=4/5, IH=0
38247020: RXMODE_SINGLE, freq=868500000, SF=9, BW=125, CR=4/5, IH=0
38312208: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
38322631: engineUpdate, opmode=0xc
52958651: engineUpdate, opmode=0xc
52958746: TXMODE, freq=868100000, len=23, SF=10, BW=125, CR=4/5, IH=0
53295229: RXMODE_SINGLE, freq=868100000, SF=10, BW=125, CR=4/5, IH=0
53360033: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
53370481: engineUpdate, opmode=0xc
79742695: engineUpdate, opmode=0xc
79742784: TXMODE, freq=868300000, len=23, SF=10, BW=125, CR=4/5, IH=0
80079247: RXMODE_SINGLE, freq=868300000, SF=10, BW=125, CR=4/5, IH=0
80144051: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
80154480: engineUpdate, opmode=0xc
104734138: engineUpdate, opmode=0xc
104734201: TXMODE, freq=868500000, len=23, SF=11, BW=125, CR=4/5, IH=0
105099740: RXMODE_SINGLE, freq=868500000, SF=11, BW=125, CR=4/5, IH=0
105163776: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
105174191: engineUpdate, opmode=0xc
157643148: engineUpdate, opmode=0xc
157643206: TXMODE, freq=868100000, len=23, SF=11, BW=125, CR=4/5, IH=0
158008747: RXMODE_SINGLE, freq=868100000, SF=11, BW=125, CR=4/5, IH=0
158072783: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
158083201: engineUpdate, opmode=0xc
216662614: engineUpdate, opmode=0xc
216662672: TXMODE, freq=868300000, len=23, SF=12, BW=125, CR=4/5, IH=0
217070939: RXMODE_SINGLE, freq=868300000, SF=12, BW=125, CR=4/5, IH=0
217133439: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
217143858: engineUpdate, opmode=0xc
323541538: engineUpdate, opmode=0xc
323541596: TXMODE, freq=868500000, len=23, SF=12, BW=125, CR=4/5, IH=0
323949866: RXMODE_SINGLE, freq=868500000, SF=12, BW=125, CR=4/5, IH=0
324012366: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
15:48:06: EV_JOIN_FAILED

I have checked the keys many time over and over again. Anything else I should be looking at please?

Hi, just preparing for the Node building workshop (Setup with Pro Mini and RFM95/LMIC). I use the latest library. OTAA join lasts 7 minutes, if i use the ‘dirty’ fix: setDrJoin(DRCHG_SET,DR_SF7) in LMIC: several seconds!! Do you know why this dirty fix is stil needed? I will document the workshop, so it would be nice not to have too much ‘dirty fixes’. thanks, Frank @matthijs any clue?

Does this still work in the new backend? If yes: How?

Having an AppKey that can be used for initial OTAA for unknown nodes makes central provisioning possible…

Please tell what should I do to DEVADDR since I don’t need to fill it up. should I make it as note?? or fill it with something else??
thank you

For OTAA I just make DEVADDR { 0x00 } in LMIC. Like:

unsigned char DevAddr[4] = { 0x00 };

Maarten

did you change other part of the code?? or just change something else. I follow your method but it seems doesn’t work for my device. I am using RPi and Dragino LoRa GPS HAT… thanks

Thanks, I have some more question. for OTAA do I need change other part of the code or I just need to add APPKEY, APPEUI and DEVEUI to the code?? do I need to remove or add anything else??

When using LMIC you have to call

LMIC_startJoining();

at the end of your setup() to make sure that the joining process will start. And make sure you do not have the following ABP code in your sketch:

LMIC_setSession (0x1, msbf4_read(DevAddr), (uint8_t*)NwkSkey, (uint8_t*)AppSkey);

As the join will do different and necessary things.

Using LMIC: DevAddr and AppSKey remain empty { 0x00 } but APPEUI and DEVEUI and NwkSKey are filled with the data you get when registering a OTAA device with console.thethingsnetwork.org.

Now you have to check on the EV_JOINED event to make sure that you catch it when the join is successful. I recommend to do not any other stuff (like sending or low power etc) before you receive this event.

Thanks for help! but I come up with another problem “OhOh, Unknow interrupt flags for FSK” This is in radio.c void radio_irq_handler()…

I still see this behaviour with an arduino Uno R3 and the Dragino 1.4 shield. It takes approximately 7 attempts and 5-9 minutes to join, after the join the connection is very stable. Have tested with different antenna’s and locations.

I guess the emphasis is at “to make sure that the joining process will start”?

Without explicitly calling this, the very first message that is sent should also trigger OTAA. That’s also written in a comment of Matthijs’ ttn-ota.ino example, and works for me:

void setup() {
    ...
    os_init();
    LMIC_reset();

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

Is there a way that I can test if the JOIN was successful? In other words if the EV_JOINED event happened?
I.e. by testing LMIC.opmode or OP_TXRXPEND or similar?

Hi @lukas and @Kibet

Starting
Packet queued
181: EV_JOINING

I used lora gateway esp8266 single channel.

I’m having this problem. How do I solve it?
Does this issue require a gateway response?
Have you solved this problem yet?

Hi Kibet:disappointed_relieved:,

I am having the same error, I made a lot of changes in my code but is not working at all, the thing here is that I am using a Mini Ultra Pro card with a RFM95W which does not provide DEVEUI address due to this boad (V1) has no EUI-64 chip, so, it reads only zeros, I tried to load a number by my self but still the EV_JOINING is stuck. All I have read since now points out that this number it does not matter too much, and so far my node does not receive anyting at the back end, I only visualize yellow requests in my gateway, which is a mulltichannel Conduit.

Could you please share with me the code you used to make your node work? I have spent two weeks trying to make this to work out without any good result.

Thanks a lot.
Regards.

Hi all,
I’m testing lora node (Arduino UNO + Dragino) with OTAA.

By default the OTAA code use the first 3 lora channels. In some post/code example there was that if you want to use all the 8 lora channels it needs to set the channel in this way:

LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI); // g-band
LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7), BAND_CENTI); // g-band
LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK, DR_FSK), BAND_MILLI); // g2-band

I tryed but both on the lora server side and on the gateway I can see that the node uses only 3 channels (the default channels 0,1,2).

Thanks in advance for your help!!
Following the code that I use:

/*******************************************************************************
Original script is Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
 *******************************************************************************/

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

static const u1_t APPEUI[8]  = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // REVERSE ORDER
static const u1_t DEVEUI[8]  = { 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // REVERSE ORDER
static const u1_t APPKEY[16] = { 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 };

// provide APPEUI (8 bytes, LSBF)
void os_getArtEui (u1_t* buf) {
  memcpy(buf, APPEUI, 8);
}

// provide DEVEUI (8 bytes, LSBF)
void os_getDevEui (u1_t* buf) {
  memcpy(buf, DEVEUI, 8);
}

// provide APPKEY key (16 bytes)
void os_getDevKey (u1_t* buf) {
  memcpy(buf, APPKEY, 16);
}

static uint8_t mydata[] = "Hello, TTN over OTAA!";
static osjob_t sendjob;
static osjob_t initjob;

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

// Pin mapping
const lmic_pinmap lmic_pins = {
  .nss = 10,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = 9,
  .dio = {2, 6, 7},
};

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"));
      do_send(&sendjob);
      break;
    case EV_RFU1:
      Serial.println(F("EV_RFU1"));
      break;
    case EV_JOIN_FAILED:
      Serial.println(F("EV_JOIN_FAILED"));
      break;
    case EV_REJOIN_FAILED:
      Serial.println(F("EV_REJOIN_FAILED"));
      // Re-init
      os_setCallback(&initjob, initfunc);      
      break;
    case EV_TXCOMPLETE:
      Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
      if (LMIC.dataLen) {
        // data received in rx slot after tx
        Serial.print(F("Data Received: "));
        //Serial.write(LMIC.frame + LMIC.dataBeg, LMIC.dataLen);
        Serial.println();
      }
      // 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;
    default:
      Serial.println(F("Unknown event"));
      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.
    LMIC_setTxData2(1, mydata, sizeof(mydata) - 1, 0);
    Serial.println(F("Packet queued"));
  }
}

// initial job
static void initfunc (osjob_t* j) {
    // reset MAC state
    LMIC_reset();
    // start joining
    LMIC_startJoining();
    // init done - onEvent() callback will be invoked...
}

void setup() {
  Serial.begin(115200);
  Serial.println(F("Starting"));
  // LMIC init
  os_init();
  // Reset the MAC state. Session and pending data transfers will be discarded.
  os_setCallback(&initjob, initfunc);

  LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);

  // Set up the channels used by the Things Network, which corresponds
  // to the defaults of most gateways. Without this, only three base
  // channels from the LoRaWAN specification are used, which certainly
  // works, so it is good for debugging, but can overload those
  // frequencies, so be sure to configure the full frequency range of
  // your network here (unless your network autoconfigures them).
  // Setting up channels should happen after LMIC_setSession, as that
  // configures the minimal channel set.
  
  LMIC_setupChannel(0, 868100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(1, 868300000, DR_RANGE_MAP(DR_SF12, DR_SF7B), BAND_CENTI);      // g-band
  LMIC_setupChannel(2, 868500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(3, 867100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(4, 867300000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(5, 867500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(6, 867700000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(7, 867900000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);      // g-band
  LMIC_setupChannel(8, 868800000, DR_RANGE_MAP(DR_FSK,  DR_FSK),  BAND_MILLI);      // g2-band
  // TTN defines an additional channel at 869.525Mhz using SF9 for class B
  // devices' ping slots. LMIC does not have an easy way to define set this
  // frequency and support for class B is spotty and untested, so this
  // frequency is not configured here.

  // Disable link check validation
  LMIC_setLinkCheckMode(0);

  // required for downlink
  LMIC.dn2Dr = SF9;

  // Set data rate and transmit power (note: txpow seems to be ignored by the library)
  LMIC_setDrTxpow(DR_SF7, 14);

  os_runloop();
  // Never get here
}

void loop() {
  // Never get here
}

please FORMAT your forum post… especially the loooooooooooooong copy/pasted code :roll_eyes:

Ok done!
waiting for some help…

1 Like