Got Adafruit Feather 32u4 LoRa Radio to work and here is how

commented out references to BMP280 and add pin definitions

//#include "i2c_BMP280.h"
//#define Serial Serial1
#include <avr/sleep.h>
#include <avr/wdt.h>
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include "LowPower.h"
#include "i2c.h"

#define Serial Serial1
//BMP280 bmp280;

#include <Arduino.h>

int sleepcycles = 7;  // every sleepcycle will last 8 secs, total sleeptime will be sleepcycles * 8 sec
bool joined = false;
bool sleeping = false;
#define LedPin 2     // pin 13 LED is not used, because it is connected to the SPI port

// 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 DEVEUI[8]  = { 0x89, 0x49, 0x65, 0x98, 0xEF, 0xAB, 0x12, 0x00 };
static const u1_t APPEUI[8] = { 0xCB, 0x81, 0x00, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };

// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
// The key shown here is the semtech default key.
static const u1_t APPKEY[16] = { 0x0A, 0xC2, 0x09, 0xCD, 0x16, 0x5E, 0x1E, 0x7D, 0xA3, 0xA1, 0xD6, 0x38, 0x23, 0xFD, 0x65, 0x0C };

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 osjob_t sendjob;
static osjob_t initjob;

// Pin mapping is hardware specific.
// Pin mapping Doug Larue PCB
// Pin mapping
const lmic_pinmap lmic_pins = {
    .nss = 8,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 4,
    .dio = {7, 6, LMIC_UNUSED_PIN},
};

void onEvent (ev_t ev) {
  int i,j;
  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"));
      // Disable link check validation (automatically enabled
      // during join, but not supported by TTN at this time).
      LMIC_setLinkCheckMode(0);
      digitalWrite(LedPin,LOW);
      // after Joining a job with the values will be sent.
      joined = true;
      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:
      sleeping = true;
        if (LMIC.dataLen) {
        // data received in rx slot after tx
        // if any data received, a LED will blink
        // this number of times, with a maximum of 10
        Serial.print(F("Data Received: "));
        Serial.println(LMIC.frame[LMIC.dataBeg],HEX);
        i=(LMIC.frame[LMIC.dataBeg]);
        // i (0..255) can be used as data for any other application
        // like controlling a relay, showing a display message etc.
        if (i>10){
          i=10;     // maximum number of BLINKs
        }
          for(j=0;j<i;j++)
          {
            digitalWrite(LedPin,HIGH);
            delay(200);
            digitalWrite(LedPin,LOW);
            delay(400);
          }
      }
      Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
      delay(50);  // delay to complete Serial Output before Sleeping

      // Schedule next transmission
      // next transmission will take place after next wake-up cycle in main loop
      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;
  }
}
  float temperature=10,pascal=999;

void do_send(osjob_t* j) {
  byte buffer[2]={11,22};

    uint16_t t_value, p_value, s_value;
/*    bmp280.awaitMeasurement();
    bmp280.getTemperature(temperature);
    bmp280.getPressure(pascal);
    bmp280.triggerMeasurement();*/
    pascal=pascal/100;
    Serial.print(" Pressure: ");
    Serial.print(pascal);
    Serial.print(" Pa; T: ");
    Serial.print(temperature);
    Serial.println(" C");
    temperature+=1;
    // getting sensor values
  
    temperature = constrain(temperature,-24,40);  //temp in range -24 to 40 (64 steps)
    pascal=constrain(pascal,970,1034);    //pressure in range 970 to 1034 (64 steps)*/
        t_value=int16_t((temperature*(100/6.25)+2400/6.25)); //0.0625 degree steps with offset
                                                      // no negative values
        Serial.print(F("decoded TEMP: "));
        Serial.print(t_value,HEX);
        p_value=int16_t((pascal-970)/1); //1 mbar steps, offset 970.
        Serial.print(F(" decoded Pascal: "));
        Serial.print(p_value,HEX);
        s_value=(p_value<<10) + t_value;  // putting the bits in the right place
        Serial.print(F(" decoded sent: "));
        Serial.println(s_value,HEX);
        buffer[0]=s_value&0xFF; //lower byte
        buffer[1]=s_value>>8;   //higher byte
    // 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, (uint8_t*) buffer, 2 , 0);
    Serial.println(F("Sending: "));
  }
}

// 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()
  {
    delay(1000);
    while (!Serial);
  delay(250);
  Serial.begin(9600);  Serial1.begin(9600);
  delay(250);
  Serial.println(F("Starting now"));
    //Serial.print("Probe BMP280: ");
   // if (bmp280.initialize()) Serial.println("Sensor found");
   // else
   // {
    //    Serial.println("Sensor missing");
    //    //while (1) {}
   // }

    // onetime-measure:
   /// bmp280.setEnabled(0);
   // bmp280.triggerMeasurement();
    
  // if LED is connected to pin 10, it has to be defined before any SPI initialization else
  // it will be used as SS (Slave Select) and controlled by the SPI module
      pinMode(LedPin, OUTPUT);
//LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100);
  os_init();
  // Reset the MAC state. Session and pending data transfers will be discarded.
  os_setCallback(&initjob, initfunc);
  LMIC_reset();
LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100);
}

unsigned long time;
void loop()
{
//Serial1.print("*");
    // start OTAA JOIN
    if (joined==false)
    {

      os_runloop_once();

    }
    else
    {
      do_send(&sendjob);    // Sent sensor values
      while(sleeping == false)
      {
        os_runloop_once();
      }
      sleeping = false;
      for (int i=0;i<sleepcycles;i++)
      {
          LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);    //sleep 8 seconds
      }
    }

      digitalWrite(LedPin,((millis()/100) % 2) && (joined==false)); // only blinking when joining and not sleeping
}```
4 Likes

after deepsleep doesn’t the 32U4 looses USB serial connection ?
(9600 is slow - use for hw serial 57600 and up)

after compiling… how much mem left ?

I don’t see any LMIC_setDrTxpow in your code; what SF are you using? Did you see LMiC's TX_COMPLETE event takes 20-30 seconds to fire - #11 by arjanvanb?

1 Like

Perhaps it will be helpful: updating IBM’s LMIC library version from “1.5.0+arduino1” to “1.5.0+arduino2” seems to shrink the size of the code…

not making much progress on the Adafruit feather 32U4 device
I am now testing using the example code from
\Documents\Arduino\libraries\arduino-lmic-master\examples\ttn-otaa
which on the Dragino Lora Shield and the TTN node joins and transmits and receives data without problems

for the Adafruit feather 32U4 the code was modified to use the correct pins

// Lora OTAA for Adafruit Feather 32u4 

/*
// Pin mapping
const lmic_pinmap lmic_pins = {
    .nss = 8,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 4,
    .dio = {7, 6, LMIC_UNUSED_PIN},
   // .dio = {3, 6, LMIC_UNUSED_PIN},
};*/


/*******************************************************************************
 * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
 *
 * Permission is hereby granted, free of charge, to anyone
 * obtaining a copy of this document and accompanying files,
 * to do whatever they want with them without any restriction,
 * including, but not limited to, copying, modification and redistribution.
 * NO WARRANTY OF ANY KIND IS PROVIDED.
 *
 * This example sends a valid LoRaWAN packet with payload "Hello,
 * world!", using frequency and encryption settings matching those of
 * the The Things Network.
 *
 * This uses OTAA (Over-the-air activation), where where a DevEUI and
 * application key is configured, which are used in an over-the-air
 * activation procedure where a DevAddr and session keys are
 * assigned/generated for use with all further communication.
 *
 * Note: LoRaWAN per sub-band duty-cycle limitation is enforced (1% in
 * g1, 0.1% in g2), but not the TTN fair usage policy (which is probably
 * violated by this sketch when left running for longer)!

 * To use this sketch, first register your application and device with
 * the things network, to set or generate an AppEUI, DevEUI and AppKey.
 * Multiple devices can use the same AppEUI, but each device has its own
 * DevEUI and AppKey.
 *
 * Do not forget to define the radio type correctly in config.h.
 *
 *******************************************************************************/


//#define Serial Serial1
#include <lmic.h>
#include <hal\hal.h>
#include <SPI.h>
//#define Serial Serial1
// 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]={ 0xCB, 0x81, 0x00, 0xD0, 0x7E, 0xD5, 0xB3, 0x70  };
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]={  0x89, 0x49, 0x65, 0x98, 0xEF, 0xAB, 0x12, 0x00};
void os_getDevEui (u1_t* buf) { memcpy_P(buf, DEVEUI, 8);}

// This key should be in big endian format (or, since it is not really a
// number but a block of memory, endianness does not really apply). In
// practice, a key taken from ttnctl can be copied as-is.
// The key shown here is the semtech default key.
static const u1_t PROGMEM APPKEY[16] = { 0x0A, 0xC2, 0x09, 0xCD, 0x16, 0x5E, 0x1E, 0x7D, 0xA3, 0xA1, 0xD6, 0x38, 0x23, 0xFD, 0x65, 0x0C  };
void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}

static uint8_t mydata[] ={01,02};//"Hello, world!";
static osjob_t sendjob;

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

// Pin mapping
const lmic_pinmap lmic_pins = {
    .nss = 8,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 4,
    .dio = {7, 6, LMIC_UNUSED_PIN},
   // .dio = {3, 6, LMIC_UNUSED_PIN},
};

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"));

            // Disable link check validation (automatically enabled
            // during join, but not supported by TTN at this time).
            LMIC_setLinkCheckMode(0);
            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"));
            break;
            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.println(F("Received "));
              Serial.print(LMIC.dataLen);
              Serial.println(F(" bytes of payload"));
              Serial.print(F("Data Received: "));
              for(int i=0;i< LMIC.dataLen;i++)
                 { Serial.print(" 0x"); Serial.print((LMIC.frame+LMIC.dataBeg)[i],  HEX);}
              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 {
        mydata[0]++;mydata[1]++;
        // Prepare upstream data transmission at the next possible time.
        LMIC_setTxData2(1, mydata, sizeof(mydata)-1, 0);
        Serial.println(F("Packet queued"));
    }
    // Next TX is scheduled after TX_COMPLETE event.
}

void setup() {
    delay(1000);
    while(!Serial);
    delay(1000);
    Serial.begin(115200);
    Serial.println(F("Starting"));

    #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();
LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);
    // Start job (sending automatically starts OTAA too)
    do_send(&sendjob);
Serial.println(LMIC.freq);
}

void loop() {
    os_runloop_once();
}

while working on the TTN node I had changed the default SF7 to SF9 - changing it back to SF7 helped the connecting and also moving the gateway further away helped
I have three of the Adafruit feather 32u4 devices - all give inconsistent results
sometimes join fails, when it works data is sometimes transmitted, sooner or later the device hangs at Packet queued if I place my hand near the device it then wakes up and displays
12127800: EV_TXCOMPLETE (includes waiting for RX windows)
FAILURE
D:\xxx\Documents\Arduino\libraries\arduino-lmic-master\src\lmic\lmic.c:1890

any ideas?

I have been working with a module that’s equal to adafruits feather 32u4.

snip/

LMIC_reset();

// 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.

#if defined(CFG_eu868)
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
#endif

/snip

2 key tips to make it work with the generic lmic examples:

  1. Don’t use OTAA - use APB
  2. Reset the Frame Counter every time you reset your device (otherwise you see traffic from your device on your gateway (yes, its better to have one around for testing) but it never reaches your device due to the frame counter check)

I posted similar instructions for the feather m0 lora here: Adafruit feather m0 lora 900 end-to-end instructions

the APB example from \IBM_LIMC_Framerwork\ttn-abp gives
Starting
Packet queued
it then hangs - when I place my hand near the device it then gives
13145803: EV_TXCOMPLETE (includes waiting for RX windows)
FAILURE
D:\OneDrive - Environmental Products and Services Ltd\Documents\Arduino\libraries\arduino-lmic-master\src\lmic\lmic.c:1890

  1. Check if DIO1 connection to D6 is wired correctly. Measure from RFM95 DIO1 pin, not the pin at the end of the longer pin header as there seem to be boards where connection between the RFM and that pin is missing.
  2. Could you try with the code at https://github.com/kersing/node-workshop/blob/master/lora32u4.md? I’ve been using it for two workshops without issues. (The only issue constantly reoccurring is people not using LSB for the EUIs and MSB for the APPKEY)
3 Likes

Kersing noted
Check if DIO1 connection to D6 is wired correctly. Measure from RFM95 DIO1 pin, not the pin at the end of the longer pin header as there seem to be boards where connection between the RFM and that pin is missing.
this proved to be the case on all three boards I have (one from the UK two from China) in that the RFM95 DIO1 pin was not connected!
Connecting DIO1 to pin 6 on one of my boards worked transmitting and receiving data

Starting
CFG_eu868
Packet queued
126195: EV_JOINING
888098: EV_JOINED
4901286: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
8783081: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
12664725: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
39774617: EV_TXCOMPLETE (includes waiting for RX windows)
Received
2 bytes of payload
Data Received:  0x11 0x22
Packet queued
43656533: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
47476518: EV_TXCOMPLETE (includes waiting for RX windows)
Received
2 bytes of payload
Data Received:  0xFB 0xFC
Packet queued
51358293: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
55239949: EV_TXCOMPLETE (includes waiting for RX windows)
Packet queued
59060251: EV_TXCOMPLETE (includes waiting for RX windows)
Received
4 bytes of payload
Data Received:  0x34 0x56 0x78 0x90

1 Like

Had the same issues, as after some time I again built up the Feather 32u4 LoRa on a breadboard. Like @kersing already said, it is important to do the wiring from DIO1 to Pin 6 correctly.
I actually made the mistake to make the wire connection to pin PD6 (which is the sixth pin counted down from the connector for the LiPo battery. Instead, use pin 6 as counted in the Arduino IDE, which has label “6” printed on the board and is the fourth pin (on the side of the LiPo connector) counted from the opposite direction of the LiPo connector).

I have three of the 32u4 Lora boards two from china and one from UK
two of the boards worked OK with OTTA once I connected the FRM95 DIO1 to pin 6 the other did not
Looking with a scope DIO1 to pin 6 was going high as expected once the Tx was complete
In the end I connected DIO1 to pin 5 and changed the FRM95 pin mapping to reflect this and it then worked OK joining, transmitting and recieving data using the Things network
it looks like there is a PCB fault in that 6 is not connected correctly on this particular PCB

I assume that the original Adafruit 32u4 Lora boards do not have these problems

You also might want to have a look at the LMIC stack by @Charles Hallard. This stack allows you to use any DIO configuration including no DIO’s attached to the microprocessor at all.

1 Like

But beware that one has last changed Aug 11, 2016, while the original meanwhile has greatly decreased the time for the EV_TXCOMPLETE event to fire, which might be nice to have.

To see the differences with @matthijs’ original:

https://github.com/matthijskooijman/arduino-lmic/compare/master...hallard:master

Agree, it would be great to have this nice feature integrated in the “mainstream” stack from @matthijs
I guess that’s what the pull request by @charles was meant for :blush:

UPDATE: Simpler now and worked right away:

I used Arduino 1.8.5 on a Mac - your milage may vary.

1 Get an Adafruit Feather 32u4 lora with the right frequency range for your region (866 for Europe)

2 Follow instructions on the adafruit site to hook up antenna and power supply

3 Connect pin 6 with IO1 (as labeled on the feather)

4 In Arduino 1.8.5 IDE do not use the built-in support for finding and downloading the lmic library - instead rather download the zip file from github instead at https://github.com/matthijskooijman/arduino-lmic

5 Open the apb example from this library from the examples menu and change the following lines:

const lmic_pinmap lmic_pins = {
.nss = 8,
.rxtx = LMIC_UNUSED_PIN,
.rst = 4,
.dio = {7,6,LMIC_UNUSED_PIN},
};

6 Get an account on the things network, create a new application in it and create a new device. Change the device to use abp instead of otaa. Copy all of the settings required from the device to your source code.

7 reset the frame counter for the device (you might need to do this again once you reset your device)

→ It worked at first attempt with a Gateway now installed at the top of my house to serve my local community in Heidelberg-Schlierbach.

8 Do whatever you want to hook up any sensor and send its data

One day I will dare to go back to otaa - but not now.

1 Like

I have similar problems with LoRa32U4 and OTAA.

Setup:
LoRa32U4 II by BSFrance (868MHz) (with LoRa module replaced, see my next post).
Using LMIC-Arduino library version 1.5.0+arduino-2
RAK831 based gateway.
Distance between node and gateway is around 4m (with a concrete floor in between).

Activation using ABP just works.
Activation using OTAA first fails, but after waiting several minutes the OTAA join succeeds
(on a different spreading factor).

t0: First OTAA join attempt (SF7) failed.
t1: Second attempt (SF7) failed.
t2: Third attempt (SF8) failed.
t3: Fourth attempt (SF8) failed.
t4: Fifth attempt (SF9) SUCCEEDED.
From there communication went as expected.

LoRa32U4 OTAA issues

What causes this?

The LoRa32U4 contains an ATmega32U4 3.3V MCU.
I then tried the same test with a board with a similar (not identical) MCU: Arduino Pro Mini 3.3V connected to a Hope RFM95 LoRa module.
This setup showed problems with OTAA identical to the LoRa32U4, but the join succeeded only at SF 10 (SF 9 failed).
What’s happening here? What causes this?

When I used the exact same RFM95 module with ESP8266 and ESP32 based boards the issues with OTAA did not occur and OTAA just succeeded using SF 7.

Maybe power / speed of the MCU is at play here. But in that case I would have expected others to have similar problems and this to be a know issue.

Pin mappings used for LoRa32U4:

LED - 13 (LED_BUILTIN)

RFM9x/SX127x LoRa module
NSS - 8
MOSI - 16/MOSI
MISO - 14/MISO
SCK - 15/SCK
RST - 4
DIO0 - 7
DIO1 - 6 (Not wired onboard, must be explicitly wired).

OLED display
SDA - 2/SDA
SCL - 3/SCL

1 Like

The SX1276 LoRa module on my LoRa32U4 II (by BSFrance) was very poorly aligned. Soldering pads of the LoRa module almost seemed to shortcut neighbouring pads on the LoRa32U4 PCB.
Because I was having unexpected OTAA issues (described above) where OTAA join requests failed, the misaligned LoRa module appeared a plausible cause. So I removed the LoRa module from the LoRa32U4 board.

I was told that my LoRa32U4 II was a 868MHz version.
The bottom of the removed SX1276 LoRa module was marked 915MHz however. This also appeared a possible cause for OTAA requests.
To fix it I mounted a compatible Hope RFM95 868MHz module onto the LoRa32U4 board. I hoped this would fix the OTAA join issues but it did not.

After some further testing I experienced the behavior described in my previous post: that the join succeeds only starting at SF 9.

(I did not wait minutes when the original SX1276 LoRa module was still mounted, so I cannot comment on if the original module would have joined on higher spreading factors).

Have you relaxed the timing by using

   LMIC_setClockError(MAX_CLOCK_ERROR * 1 / 100);

between the LMIC reset and the join attempt?

3 Likes