ESP isn´t sending data to my Gateway

Hello,

I want to use a Dragino LG308-868 LoRaWAN gateway to push some data from my sensors into TTN. The gateway is configured and connected with my TTN account. The next step is to push some data from my ESP over the gateway into TTN, but my application (I´m using the LoRaWAN LMIC library) doesn´t transmit the data:

Starting   
RXMODE_RSSI
3767: engineUpdate, opmode=0x808
Packet queued
3805: EV_JOINING
3812: engineUpdate, opmode=0xc  
3835: Unknown event
3908: TXMODE, freq=905300000, len=23, SF=10, BW=125, CR=4/5, IH=0
start single rx: now-rxtime: 3
339467: RXMODE_SINGLE, freq=927500000, SF=10, BW=500, CR=4/5, IH=0
rxtimeout: entry: 340367 rxtime: 339460 entry-rxtime: 907 now-entry: 5 rxtime-txend: 312375
start single rx: now-rxtime: 3
401967: RXMODE_SINGLE, freq=923300000, SF=12, BW=500, CR=4/5, IH=0
rxtimeout: entry: 405555 rxtime: 401960 entry-rxtime: 3595 now-entry: 4 rxtime-txend: 374875
405576: Unknown event
405584: engineUpdate, opmode=0xc
441847: engineUpdate, opmode=0xc
441863: Unknown event
441930: TXMODE, freq=904600000, len=23, SF=8, BW=500, CR=4/5, IH=0

I use the following keys from TTN (OTAA) and the following application code:

image

#define LMIC_DEBUG_LEVEL 1
#include <Arduino.h>
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>

// 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] = { 0x90, 0x74, 0x03, 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] = { 0x2C, 0x4F, 0xEE, 0xBE, 0x3A, 0x12, 0x70, 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] = { 0x47, 0x5B, 0x31, 0xDF, 0x77, 0x4F, 0xD8, 0x78, 0x23, 0x30, 0xCE, 0x97, 0x43, 0x8F, 0x3A, 0xDD };
void os_getDevKey (u1_t* buf){ memcpy_P(buf, APPKEY, 16); }
static uint8_t mydata[] = "Hello, world!";
static osjob_t sendjob;
const unsigned TX_INTERVAL = 60;
const lmic_pinmap lmic_pins = {
  .nss = 5,
  .rxtx = LMIC_UNUSED_PIN,
  .rst = 14,
  .dio = {2, 22, LMIC_UNUSED_PIN},
};

void do_send(osjob_t* j);
void onEvent(ev_t Event)
{
    Serial.print(os_getTime());
    Serial.print(": ");
    switch(Event)
    {
        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(uint8_t i = 0; i < sizeof(artKey); ++i)
              {
                Serial.print(artKey[i], HEX);
              }
              Serial.println("");
              Serial.print("nwkKey: ");
              for(uint8_t i = 0; i < sizeof(nwkKey); ++i)
              {
                Serial.print(nwkKey[i], HEX);
              }
              Serial.println("");
              LMIC_setSeqnoUp(140);
            }

            // 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.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:
            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)
{
    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"));
    }
}
void setup()
{
    Serial.begin(115200);
    Serial.println("Starting");
    os_init();
    LMIC_reset();
    LMIC_setLinkCheckMode(0);
    LMIC_setDrTxpow(DR_SF7, 14);
    LMIC_selectSubBand(1);
    do_send(&sendjob);
}
void loop()
{
    os_runloop_once();
}

So what is wrong with this code?

You would benefit from turning in an additional level of logging so we can find out what all those “Unknown event”'s are coming from - #define LMIC_DEBUG_LEVEL 1 should enable this if it’s after your includes.

Which LMIC library are you using?

Your screen shot would be the details for an ABP connection …

1 Like

Hello,

it seems that I have copied the wrong part of the screenshot. I´m sorry! But I have updated my question with the correct screenshot, the library and some debug outputs.

OK, not exactly the position suggested for the #define but it’s working.

Where in the world are you? i.e., is the default US region correct? (Unlikely given the gateway)

From the main readme:

The library requires that the compile environment or the project config file define exactly one of CFG_... variables. As released, project_config/lmic_project_config.h defines CFG_us915

Personally, I bypass changing the library and have this AFTER the #includes in the sketch (.ino):

#define CFG_eu868 1
#define CFG_sx1276_radio 1

Please don’t edit your post, reply underneath, helps us keep track …

Hello,

I´m sitting in Europe, so it seems that the frequency might be wrong because you say the US is standard.
I have added the includes:

#include <Arduino.h>
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#define CFG_eu868 1
#define CFG_sx1276_radio 1
// 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] = { 0x90, 0x74, 0x03, 0xD0, 0x7E, 0xD5, 0xB3, 0x70 };
void os_getArtEui (u1_t* buf){ memcpy_P(buf, APPEUI, 8); }
...

But the error still exists:

Starting   
RXMODE_RSSI
3796: engineUpdate, opmode=0x808
Packet queued
3834: EV_JOINING
3841: engineUpdate, opmode=0xc
3864: Unknown event
3936: TXMODE, freq=904500000, len=23, SF=10, BW=125, CR=4/5, IH=0
start single rx: now-rxtime: 4
339497: RXMODE_SINGLE, freq=925100000, SF=10, BW=500, CR=4/5, IH=0
rxtimeout: entry: 340396 rxtime: 339489 entry-rxtime: 907 now-entry: 5 rxtime-txend: 312375
start single rx: now-rxtime: 4
401997: RXMODE_SINGLE, freq=923300000, SF=12, BW=500, CR=4/5, IH=0
rxtimeout: entry: 405584 rxtime: 401989 entry-rxtime: 3595 now-entry: 5 rxtime-txend: 374875
405605: Unknown event
405613: engineUpdate, opmode=0xc
434046: engineUpdate, opmode=0xc
434062: Unknown event

The module is still using the wrong frequency. But why?

Btw. I´m using Plattform IO as a development tool and not the Arduino IDE and I have moved the define to the build flags in platformio.ini:

build_flags =
  -DLMIC_DEBUG_LEVEL=1

No, US is not the standard, US is the default if using the Arduino IDE. But the very next sentence in the instructions / readme is:

If you build with PlatformIO or other environments, and you do not provide a pointer to the platform config file, src/lmic/config.h will define CFG_eu868 .

Which, now we know you are using PlatformIO, is pertinent - perhaps you could review the instructions to check for other issues before going further.

And check out the TTN docs - the EU frequencies are around 868MHz, your debug log shows it is trying frequencies in the 915MHz range which ideally would have raised some alarm bells.

I missed the ARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS symbol. The following config enables the 868 MHz frequency:

-DARDUINO_LMIC_PROJECT_CONFIG_H_SUPPRESS
-DCFG_eu868=1
-DCFG_sx1276_radio=1

The code is working now :slight_smile:

Thank you!