Device not activated Lora feather 32u4 RFM9X

Hello everyone,
I am trying to connect an Adafruit Lora feather 32u4 RFM9X. I followed this tutorial:

The problem:
However the output I get on the serial monitor continuously is:

Packet queued
60890147: EV_TXCOMPLETE (includes waiting for RX windows)
VBat: 4.32
Packet queued
62271171: EV_TXCOMPLETE (includes waiting for RX windows)
VBat: 4.32
Packet queued

Nothing shows up in the console (no data), it also says that the status of the device is “never seen”.

What I tried:
I checked out this link where mathijs suggested the LSB and MSB first.
I though maybe the problem is related to range. The nearest gateway is about 500 metres away. The Adafruit page says LoRa range should be 2km with a unidirectional antenna. I am powering the device with just a USB connected to my PC (i.e. no batteries).


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

// LoRaWAN NwkSKey, network session key
// This is the default Semtech key, which is used by the early prototype TTN
// network.MSB!
static const PROGMEM u1_t NWKSKEY[16] = { 0xAB, 0x1A, 0xB1, 0x64, 0x37, 0xAE, 0xF2, 0xBB, 0x93, 0xB3, 0xD8, 0xBC, 0x8B, 0xC4, 0x10, 0x93 };

// LoRaWAN AppSKey, application session key
// This is the default Semtech key, which is used by the early prototype TTN
// network. MSB!
static const u1_t PROGMEM APPSKEY[16] = { 0x64, 0x09, 0x0B, 0x76, 0x6F, 0x39, 0xBD, 0x85, 0x49, 0xFB, 0xF7, 0x26, 0xD4, 0xCC, 0xB4, 0xD5 };

// LoRaWAN end-device address (DevAddr) LSB! 
static const u4_t DEVADDR[4] = { 0x83, 0x19, 0x01, 0x26 } ; // <-- Change this address for every node!

// These callbacks are only used in over-the-air activation, so they are
// left empty here (we cannot leave them out completely unless
// DISABLE_JOIN is set in config.h, otherwise the linker will complain).
void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }

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

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

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

// 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) {
    Serial.print(": ");
    switch(ev) {
        case EV_SCAN_TIMEOUT:
        case EV_BEACON_FOUND:
        case EV_BEACON_MISSED:
        case EV_BEACON_TRACKED:
        case EV_JOINING:
        case EV_JOINED:
        case EV_RFU1:
        case EV_JOIN_FAILED:
        case EV_REJOIN_FAILED:
        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.println(F(" bytes of payload"));
            // Schedule next transmission
            os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
        case EV_LOST_TSYNC:
        case EV_RESET:
        case EV_RXCOMPLETE:
            // data received in ping slot
        case EV_LINK_DEAD:
        case EV_LINK_ALIVE:
            Serial.println(F("Unknown event"));

//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"));
//    }
//    // Next TX is scheduled after TX_COMPLETE event.

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.
        #define VBATPIN A9
        float measuredvbat = analogRead(VBATPIN);
        measuredvbat *= 2;    // we divided by 2, so multiply back
        measuredvbat *= 3.3;  // Multiply by 3.3V, our reference voltage
         measuredvbat /= 1024; // convert to voltage
        byte buffer[8];
        dtostrf(measuredvbat, 1, 2, buffer);
        String res = buffer;
        res.getBytes(buffer, res.length() + 1);
        Serial.print("VBat: " ); Serial.println(measuredvbat);
       LMIC_setTxData2(1, (uint8_t*) buffer, res.length(), 0);
        Serial.println(F("Packet queued"));

    // Next TX is scheduled after TX_COMPLETE event.


void setup() {

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

    // LMIC init
    // Reset the MAC state. Session and pending data transfers will be discarded.

    // Set static session parameters. Instead of dynamically establishing a session
    // by joining the network, precomputed session parameters are be provided.
    #ifdef PROGMEM
    // On AVR, these values are stored in flash and only copied to RAM
    // once. Copy them to a temporary buffer here, LMIC_setSession will
    // copy them into a buffer of its own again.
    uint8_t appskey[sizeof(APPSKEY)];
    uint8_t nwkskey[sizeof(NWKSKEY)];
    memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));
    memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));
    LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);
    // If not running an AVR with PROGMEM, just use the arrays directly
    LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);

    #if defined(CFG_eu868)
    // 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.
    // NA-US channels 0-71 are configured automatically
    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.
    #elif defined(CFG_us915)
    // NA-US channels 0-71 are configured automatically
    // but only one group of 8 should (a subband) should be active
    // TTN recommends the second sub band, 1 in a zero based count.

    // Disable link check validation

    // TTN uses SF9 for its RX2 window.
    LMIC.dn2Dr = DR_SF9;

    // Set data rate and transmit power for uplink (note: txpow seems to be ignored by the library)

    // Start job

void loop() {
1 Like
  • did you mount that wire

  • did you create an application on the TTN console and added your node ?

  • can you see on the ttn console that your node is (trying) connecting ?

  • increase TX_INTERVAL

Hi Borroz,
Thanks for the feedback :slight_smile:

  1. yes mounted the wire
  2. yes
  3. I do not know how you can see that it is trying to connect. How can you see that? All I can see that it is has never been seen.
  4. Increased TX_INTERVAL to 60. No difference.

Many thanks!

go into your console and then : application/devices

select your device and select data :



now start or power up your node.
you should see the yellow lightning (if there is a ‘normal’ multi channel working gateway in range)
a single channel gateway could be listening to the wrong frequencies

the TTN backend should accept your join request if the keys are ok… the blue ‘answer’

now if your node start sending :


1 Like

It is blank. I checked it a few times before, never seen anything show up in here.
Since I see no lighting sign, does that mean there is no gateway in range?


And by the way, the device (node) is near the red cross on the map. So nearest gateway is around 1 km away. Shouldn’t be problematic, should it? image

…which shows:

// LoRaWAN end-device address (DevAddr)
static const u4_t DEVADDR = 0x03FF0001 ; // <-- Change this address for every node!

…but you ended up with:

// LoRaWAN end-device address (DevAddr) LSB! 
static const u4_t DEVADDR[4] = { 0x83, 0x19, 0x01, 0x26 } ; // <-- Change this address for every node!

Are you sure the sketch supports that format?

(Also, it’s really nice to remove outdated comments… And when the first tests succeed, you’ll need to have a look at this, as it sends text: dtostrf(measuredvbat, 1, 2, buffer);)

Yes I changed that because I read somewhere that that might be a fix. Changed it back again to :
static const u4_t DEVADDR = 26011983;
but that doesn’t solve the issue.

Sorry, I don’t see what do you mean by the outdated comments?

And thanks for the tip, your help is much appreciated!

Lacking the prefix 0x now it’s interpreted as the decimal 26011983, which is not the same as hexadecimal 0x26011983:slight_smile:

As for outdated comments, things like:

// This is the default Semtech key, which is used by the early prototype TTN
// network.

Ah right. Changing it to 0x26011983 doesn’t change output either unfortunately.

Bummer. You could (temporarily) change the spreading factor SF7 in:


…into SF12, like in:

LMIC_setDrTxpow(DR_SF12, 14);

…to maximize the range (and the required airtime).

1 Like

Ah great! Now this shows up in the console! Though there is no lightning sign so no gateway in range I guess? The serial output is still the same though. image

The lighting symbol in TTN Console indicates an OTAA Join Request, while you’re using ABP, so there’s no activation needed.

The serial output isn’t wrong, is it?

As for the displayed payload 35 2E 31 36, those are the ASCII characters of the text value 5.16.

1 Like

Ahaa that makes sense. No the serial output isn’t wrong, I expected some acknowledgement but I guess that has to do with the input flags I give to it…

Regarding spreading factor SF, you said “temporarily” change the SF. Why can’t I use this permanently? Since this seems to work quite well… :wink:

Many thanks for your help and getting it to work!

Using a hardcoded SF11 or SF12 is not allowed, as it takes a lot of airtime, increasing the chance for collisions with other users of the network. See Limitations: data rate, packet size, 30 seconds uplink and 10 messages downlink per day Fair Access Policy.

So try to lower that by trying SF10, SF9, SF8, …

Also, you won’t get a confirmation unless you use “conformed downlinks”, which you should use very sparsely (if at all) as explained in the same link.

Next steps:


1 Like

Great, will do that. Thank you! :smiley:

@vlamingBoyz, I think we had some problems with this board as well and I remember we had to put a small time delay in somewhere because there was a problem with the initialization of the RFM95. I don’t remember exactly where, it’s over a year ago, and I couldn’t find the corresponding notes easily. Maybe you can find a post on the forum on this subject because I think we made one…

Another thing is that we didn’t use the reset pin. Never have used it and it works fine, so we always used .rst = LMIC_UNUSED_PIN,

And then a final tip: for the dead cheap prize of about 10 dollars you can buy a very useful tool: is a USB spectrum analyzer that works up to 1 GHz, Just google for DVT-T DAB FM Spectrum Analyzer, and you can easily find it. In this case it will tell you whether or not your RFM95 is actually transmitting! You can verify the channel, and by the length of the transmission, you can also verify the SF used.


Hi @rharte, Thanks for the tip! Will look into that spectrum analyser!

Regarding your previous post about the RFM95, could it be this one? Adafruit LoRa Feather -> Gateway (You wrote in response to someone else’s post).

I will try with the .rst = unused setup.

@vlamingBoyz it was this one made by my colleague Rene Pluijmers: