Compiling problem with platformio in VS

Hello, I’m new in all of this and I’m a bit lost with the programming of Lora devices.

I’m currently owning an Arduino Uno and a heltec wifi lora 32 V2 and downloaded the MCCI LoRaWAN LMIC library to make a test in The things Network using an example of that library via OTAA.

When I compile it marks an error error: expected initializer before 'APPEUI' and this is in DEVEUI and APPKEY, followed with other errors. I’m not sure how to fix this, anyone has a problem similar to this? I appreciate any help, and sorry for my bad english, is not my first language. Thank you very much!

We would need to see your exact platformio.ini and code so that we can help you. Are you using arduino-lmic/ttn-otaa.ino at master · mcci-catena/arduino-lmic · GitHub?

1 Like

Yes, the platformio.ini code is this:

[env:heltec_wifi_lora_32_V2]

platform = espressif32

board = heltec_wifi_lora_32_V2

framework = arduino

The code I’m using is the OTAA example of the library MCCI LoRaWAN LMIC library from IBM, this is the code:

#include <lmic.h>

#include <hal/hal.h>

#include <SPI.h>

//

// For normal use, we require that you edit the sketch to replace FILLMEIN

// with values assigned by the TTN console. However, for regression tests,

// we want to be able to compile these scripts. The regression tests define

// COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non-

// working but innocuous value.

//

#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

// 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]={  FILL  };

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]={  FILL } ;

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.

static const u1_t PROGMEM APPKEY[16] = { FILL  };

void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}

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 = 60;

// Pin mapping

const lmic_pinmap lmic_pins = {

    .nss = 6,

    .rxtx = LMIC_UNUSED_PIN,

    .rst = 5,

    .dio = {2, 3, 4},

};

void printHex2(unsigned v) {

    v &= 0xff;

    if (v < 16)

        Serial.print('0');

    Serial.print(v, HEX);

}

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("AppSKey: ");

              for (size_t i=0; i<sizeof(artKey); ++i) {

                if (i != 0)

                  Serial.print("-");

                printHex2(artKey[i]);

              }

              Serial.println("");

              Serial.print("NwkSKey: ");

              for (size_t i=0; i<sizeof(nwkKey); ++i) {

                      if (i != 0)

                              Serial.print("-");

                      printHex2(nwkKey[i]);

              }

              Serial.println();

            }

            // Disable link check validation (automatically enabled

            // during join, but because slow data rates change max TX

        // size, we don't use it in this example.

            LMIC_setLinkCheckMode(0);

            break;

        /*

        || This event is defined but not used in the code. No

        || point in wasting codespace on it.

        ||

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

        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:

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

        /*

        || This event is defined but not used in the code. No

        || point in wasting codespace on it.

        ||

        || case EV_SCAN_FOUND:

        ||    Serial.println(F("EV_SCAN_FOUND"));

        ||    break;

        */

        case EV_TXSTART:

            Serial.println(F("EV_TXSTART"));

            break;

        case EV_TXCANCELED:

            Serial.println(F("EV_TXCANCELED"));

            break;

        case EV_RXSTART:

            /* do not print anything -- it wrecks timing */

            break;

        case EV_JOIN_TXCOMPLETE:

            Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));

            break;

        default:

            Serial.print(F("Unknown event: "));

            Serial.println((unsigned) ev);

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

    }

    // Next TX is scheduled after TX_COMPLETE event.

}

void setup() {

    Serial.begin(9600);

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

    // Start job (sending automatically starts OTAA too)

    do_send(&sendjob);

}

void loop() {

    os_runloop_once();

}

So you haven’t filled out the key parameters for your node in the code? You need to create a device in the your LoRa Network Server (LNS) that you’re using, like TTN or ChirpStack or whatever.

Oh sorry, but for security I removed it. Already filled out those parameters.

Compiles without problems for me.

[env:heltec_wifi_lora_32_V2]
platform = espressif32
board = heltec_wifi_lora_32_V2
framework = arduino

Copy pasting arduino-lmic/ttn-otaa.ino at master · mcci-catena/arduino-lmic · GitHub as main.ino in the source folder and replacing the keys leads to a successful compilation.

I also converted it to a .cpp file in this case by simply putting #include <Arduino.h> and void do_send(osjob_t* j); at line 39, so that code completion fully works. Still compiles of course.

Can you show more error details using the Verbose Build task and the full error message?

Now it works, I have to add the #include <Arduino.h> library and move the do_send function above onEvent

There is no error when compiling and uploading, but when monitoring it gives:

�,�␜␗l␙�␀Starting
Guru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x400d4410: ffffffff ffffffff ffffffff
Core 1 register dump:
PC      : 0x400d4416  PS      : 0x00060130  A0      : 0x800d4470  A1      : 0x3ffb1f00  
A2      : 0x3ffc0140  A3      : 0x000000ff  A4      : 0x00000008  A5      : 0x0000ff00  
A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x3f4010fc  A9      : 0x3ffb1ee0  
A10     : 0x000000ff  A11     : 0x00000000  A12     : 0x00000002  A13     : 0x0000ff00  
A14     : 0x00ff0000  A15   
--- exit ---

Well it could still be

  • a wrong pinmap
  • faulty library code, somehow

IllegalInstruction in code at 0x400d4410 which is filled with 0xfffffff is weird, how’d it even get there.

Can you:

  • add build_flags = -DLMIC_DEBUG_LEVEL=2 to the platformio.ini
  • add monitor_filters = esp32_exception_decoder to the platformio.ini so that the exception is decoded
  • add monitor_speed = 115200 and change Serial.begin(9600); to Serial.begin(115200); in the code, unifies the baud rate with the bootloader

and recompile and reupload the firmware. What info does appear now?

1 Like

Ok, I did it. It happens for some reason that I get weird errors when programming.

Rebooting...
ets Jun  8 2016 00:22:57

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:2
load:0x3fff0018,len:4
load:0x3fff001c,len:1044
load:0x40078000,len:8896
load:0x40080400,len:5828
entry 0x400806ac
Starting
Guru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x400d46d0: ffffffff ffffffff ffffffff
Core 1 register dump:
PC      : 0x400d46d6  PS      : 0x00060130  A0      : 0x800d4730  A1      : 0x3ffb1f00  
A2      : 0x3ffc0140  A3      : 0x000000ff  A4      : 0x00000008  A5      : 0x0000ff00
A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x3f4010fc  A9      : 0x3ffb1ee0  
A10     : 0x000000ff  A11     : 0x00000000  A12     : 0x00000002  A13     : 0x0000ff00
A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x0000001a  EXCCAUSE: 0x00000000  
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff  

Backtrace: 0x400d46d6:0x3ffb1f00 0x400d472d:0x3ffb1f20 0x400d3683:0x3ffb1f40 0x400d369a:0x3ffb1f60 0x400d1139:0x3ffb1f80 0x400d5bcb:0x3ffb1fb0 0x40088215:0x3ffb1fd0
  #0  0x400d46d6:0x3ffb1f00 in Arduino_LMIC::hal_init_with_pinmap(Arduino_LMIC::HalPinmap_t const*) at C:\Users\neko_\.platformio\lib\MCCI LoRaWAN LMIC library_ID5774\src\hal/hal.cpp:366
      (inlined by) Arduino_LMIC::hal_init_with_pinmap(Arduino_LMIC::HalPinmap_t const*) at C:\Users\neko_\.platformio\lib\MCCI LoRaWAN LMIC library_ID5774\src\hal/hal.cpp:451
  #1  0x400d472d:0x3ffb1f20 in hal_init_ex at C:\Users\neko_\.platformio\lib\MCCI LoRaWAN LMIC library_ID5774\src\hal/hal.cpp:366
  #2  0x400d3683:0x3ffb1f40 in os_init_ex at C:\Users\neko_\.platformio\lib\MCCI LoRaWAN LMIC library_ID5774\src\lmic/oslmic.c:43
  #3  0x400d369a:0x3ffb1f60 in os_init at C:\Users\neko_\.platformio\lib\MCCI LoRaWAN LMIC library_ID5774\src\lmic/oslmic.c:51
  #4  0x400d1139:0x3ffb1f80 in setup() at src/main.cpp:236
  #5  0x400d5bcb:0x3ffb1fb0 in loopTask(void*) at C:\Users\neko_\.platformio\packages\framework-arduinoespressif32\cores\esp32/main.cpp:14
  #6  0x40088215:0x3ffb1fd0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)

I still don’t understand what I am missing, if compiles good and upload without problems, why i get this error when monitoring? Is the device?

Line 366 of src\hal\hal.cpp says something different for me, nothing about hal_init_with_pinmap():

Can you update the library in PIO Home → Libraries → MCCI LoRaWAN LMIC library → Update to 3.2.0?

1 Like

Its already updated, also tried to change the board to heltec_wifi_lora_32 and got the same error if that helps.

Okay on an ESP32 with no LoRa Radio connected I get the same output

Starting
Guru Meditation Error: Core  1 panic'ed (IllegalInstruction). Exception was unhandled.
Memory dump at 0x400d4548: ffffffff ffffffff ffffffff
Core 1 register dump:
PC      : 0x400d454e  PS      : 0x00060130  A0      : 0x800d45a8  A1      : 0x3ffb1f00
A2      : 0x3ffc0140  A3      : 0x000000ff  A4      : 0x00000008  A5      : 0x0000ff00
A6      : 0x00ff0000  A7      : 0xff000000  A8      : 0x3f4010fc  A9      : 0x3ffb1ee0
A10     : 0x000000ff  A11     : 0x00000000  A12     : 0x00000002  A13     : 0x0000ff00  
A14     : 0x00ff0000  A15     : 0xff000000  SAR     : 0x0000001a  EXCCAUSE: 0x00000000
EXCVADDR: 0x00000000  LBEG    : 0x400014fd  LEND    : 0x4000150d  LCOUNT  : 0xffffffff

Backtrace: 0x400d454e:0x3ffb1f00 0x400d45a5:0x3ffb1f20 0x400d3507:0x3ffb1f40 0x400d351e:0x3ffb1f60 0x400d1134:0x3ffb1f80 0x400d5a43:0x3ffb1fb0 0x40088215:0x3ffb1fd0
  #0  0x400d454e:0x3ffb1f00 in Arduino_LMIC::hal_init_with_pinmap(Arduino_LMIC::HalPinmap_t const*) at C:\Users\Maxi\.platformio\lib\MCCI LoRaWAN LMIC library\src\hal/hal.cpp:366
      (inlined by) Arduino_LMIC::hal_init_with_pinmap(Arduino_LMIC::HalPinmap_t const*) at C:\Users\Maxi\.platformio\lib\MCCI LoRaWAN LMIC library\src\hal/hal.cpp:451
  #1  0x400d45a5:0x3ffb1f20 in hal_init_ex at C:\Users\Maxi\.platformio\lib\MCCI LoRaWAN LMIC library\src\hal/hal.cpp:366
  #2  0x400d3507:0x3ffb1f40 in os_init_ex at C:\Users\Maxi\.platformio\lib\MCCI LoRaWAN LMIC library\src\lmic/oslmic.c:43
  #3  0x400d351e:0x3ffb1f60 in os_init at C:\Users\Maxi\.platformio\lib\MCCI LoRaWAN LMIC library\src\lmic/oslmic.c:51
  #4  0x400d1134:0x3ffb1f80 in setup() at src/main.cpp:242
  #5  0x400d5a43:0x3ffb1fb0 in loopTask(void*) at C:\Users\Maxi\.platformio\packages\framework-arduinoespressif32\cores\esp32/main.cpp:14
  #6  0x40088215:0x3ffb1fd0 in vPortTaskWrapper at /home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)

Rebooting...
ets Jun  8 2016 00:22:57

with the same line numbers. So let’s just make sure that the pins are correct because that sketch does have constant pin numbers instead of the automatic ones.

  1. Make sure you have board = heltec_wifi_lora_32_V2 in the platformio.ini
  2. Remove or comment out the section
// Pin mapping
const lmic_pinmap lmic_pins = {
    .nss = 6,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 5,
    .dio = {2, 3, 4},
};

in the main.cpp
3. Add #include <arduino_lmic_hal_boards.h> as an include at the top
4. In the setup(), instead of

    // LMIC init
    os_init();

write

   auto* pinMap = Arduino_LMIC::GetPinmap_ThisBoard();
   os_init_ex(pinMap);

and retry uploading.

If that stil doesn’t work try Arduino_LMIC::GetPinmap_heltec_lora32() instead of the Arduino_LMIC::GetPinmap_ThisBoard().

2 Likes

Aha, I think we have the problem. Same as in Heltec ESP32 · Issue #173 · matthijskooijman/arduino-lmic · GitHub

If the automatic pin map doesn’t work you can use the one as seen above.

Also you must edit C:\Users\<User>\.platformio\lib\MCCI LoRaWAN LMIC library\project_config\lmic_project_config.h so that it has the correct configuration for the EU868 band and SX1276 radio.

Make usre it has

#define CFG_eu868 1
#define CFG_sx1276_radio 1

end everything else commented out.

2 Likes

Changing the pin mapping, adding the include and chaning the LMIC init make things work.

Starting
RXMODE_RSSI
3886: engineUpdate, opmode=0x8
Packet queued
3926: EV_JOINING
3932: engineUpdate, opmode=0xc
5186: engineUpdate, opmode=0xc
5208: EV_TXSTART
5241: TXMODE, freq=868500000, len=23, SF=7, BW=125, CR=4/5, IH=0
320857: setupRx1 txrxFlags 00 --> 01
start single rx: now-rxtime: 1
321485: RXMODE_SINGLE, freq=868500000, SF=7, BW=125, CR=4/5, IH=0
rxtimeout: entry: 322013 rxtime: 321481 entry-rxtime: 532 now-entry: 3 rxtime-txend: 312375
383356: setupRx2 txrxFlags 0x1 --> 02
start single rx: now-rxtime: 1
383985: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
rxtimeout: entry: 398337 rxtime: 383981 entry-rxtime: 14356 now-entry: 3 rxtime-txend: 374875
398349: processRx2Jacc txrxFlags 0x2 --> 00
398409: EV_JOIN_TXCOMPLETE: no JoinAccept
398643: engineUpdate, opmode=0xc

I’m noticing is not doing the join I’m using TTN in order to make the configuration and the gateway is not registering. The gateway is connected but the device is not.

Okay so TX frequency looks good, but with SF7 it has a small initial reach. If the GW is too far away it might not hear anything.

You may be able to call

    //for EU868
    //DR0 = SF12 BW125
    //DR1 = SF11 BW125
    //..
    LMIC_setDrTxpow(LORAWAN_DR0, 12);

after the the LMIC_reset() call.

The join procedure will do some retries on higher SF which will take its time. ABP configuration does not have such a problem. You might want to try and adapt the ABP sketch to work and switch your device to ABP too.

Otherwise it might also be a general gateway problem. Do you control the gateway?

Oh and also this might be a problem. TTN does RX2 downlink on spreading factor 9 if I remember correctly. Dunno why “TTN LMIC” doesn’t do this automatically oO. You might want to add

LMIC.dn2Dr = DR_SF9;

as seen in TTN Ulm - LoRaWAN und LoRa in Ulm | Nodes.

Also the join SF might be changable by calling

    LMICcore_setDrJoin(DRCHG_SET, LORAWAN_DR0);

And one caveat are timing issues with which the node might not receive anything. As seen in OTAA does not work on 8MHz ? · Issue #22 · matthijskooijman/arduino-lmic · GitHub that can be tackled with

// Let LMIC compensate for +/- 10% clock error
LMIC_setClockError(MAX_CLOCK_ERROR * 10 / 100);

or more error.

They are next to each other

I added all the code you told me, still getting the no JoinAccept

--- Miniterm on COM3  115200,8,N,1 ---
--- Quit: Ctrl+C | Menu: Ctrl+T | Help: Ctrl+T followed by Ctrl+H ---
Starting
RXMODE_RSSI
3903: engineUpdate, opmode=0x8
Packet queued
3944: EV_JOINING
3950: engineUpdate, opmode=0xc
475354: engineUpdate, opmode=0xc
475376: EV_TXSTART
475409: TXMODE, freq=868500000, len=23, SF=7, BW=125, CR=4/5, IH=0
789775: setupRx1 txrxFlags 00 --> 01
start single rx: now-rxtime: 2
790403: RXMODE_SINGLE, freq=868500000, SF=7, BW=125, CR=4/5, IH=0
rxtimeout: entry: 793428 rxtime: 790399 entry-rxtime: 3029 now-entry: 3 rxtime-txend: 311126
852024: setupRx2 txrxFlags 0x1 --> 02
start single rx: now-rxtime: 2
852654: RXMODE_SINGLE, freq=869525000, SF=12, BW=125, CR=4/5, IH=0
rxtimeout: entry: 869054 rxtime: 852649 entry-rxtime: 16405 now-entry: 2 rxtime-txend: 373376
869065: processRx2Jacc txrxFlags 0x2 --> 00
869125: EV_JOIN_TXCOMPLETE: no JoinAccept
869359: engineUpdate, opmode=0xc

Maybe there is a problem with the gateway?

…Isn’t this a 1-channel Dragino gateway? What channel settings (frequency, spreading factor, code-rate and bandwidth) did you setup? (like in https://wiki.dragino.com/index.php?title=Connect_to_TTN#Configure_LG01_LoRa_Radio_Parameter)

If it’s a 1ch GW then the node has to also be restricted to only transmit on that channel.

2 Likes

Hello, I made some changes regarding what you say, I change the gateway to the Dragino LG308 to have more channels and change to ABP configuration in order to make it work. It now connect and send packages but the device only shows uplink, when I run a monitoring only sends the first package with the “hello world” and then empty in every other package.

The code I’m using is this one, it comes from the same example in the same library but for ABP:

/*******************************************************************************

 * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman

 * Copyright (c) 2018 Terry Moore, MCCI

 *

 * 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 ABP (Activation-by-personalisation), where a DevAddr and

 * Session keys are preconfigured (unlike OTAA, where a DevEUI and

 * application key is configured, while the DevAddr and session keys are

 * assigned/generated in the over-the-air-activation procedure).

 *

 * 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 a DevAddr, NwkSKey and

 * AppSKey. Each device should have their own unique values for these

 * fields.

 *

 * Do not forget to define the radio type correctly in

 * arduino-lmic/project_config/lmic_project_config.h or from your BOARDS.txt.

 *

 *******************************************************************************/

 // References:

 // [feather] adafruit-feather-m0-radio-with-lora-module.pdf

#include <arduino_lmic_hal_boards.h>

#include <Arduino.h>

#include <lmic.h>

#include <hal/hal.h>

#include <SPI.h>

//

// For normal use, we require that you edit the sketch to replace FILLMEIN

// with values assigned by the TTN console. However, for regression tests,

// we want to be able to compile these scripts. The regression tests define

// COMPILE_REGRESSION_TEST, and in that case we define FILLMEIN to a non-

// working but innocuous value.

//

#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

// LoRaWAN NwkSKey, network session key

// This should be in big-endian (aka msb).

static const PROGMEM u1_t NWKSKEY[16] = { FILL};

// LoRaWAN AppSKey, application session key

// This should also be in big-endian (aka msb).

static const u1_t PROGMEM APPSKEY[16] = { FILL };

// LoRaWAN end-device address (DevAddr)

// See http://thethingsnetwork.org/wiki/AddressSpace

// The library converts the address to network byte order as needed, so this should be in big-endian (aka msb) too.

static const u4_t DEVADDR = FILL; // <-- 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 arduino-lmic/project_config/lmic_project_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 = 60;

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.

}

// Pin mapping

// Adapted for Feather M0 per p.10 of [feather]

/*const lmic_pinmap lmic_pins = {

    .nss = 8,                       // chip select on feather (rf95module) CS

    .rxtx = LMIC_UNUSED_PIN,

    .rst = 4,                       // reset pin

    .dio = {6, 5, LMIC_UNUSED_PIN}, // assumes external jumpers [feather_lora_jumper]

                                    // DIO1 is on JP1-1: is io1 - we connect to GPO6

                                    // DIO1 is on JP5-3: is D2 - we connect to GPO5

};*/

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

            break;

        /*

        || This event is defined but not used in the code. No

        || point in wasting codespace on it.

        ||

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

        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(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:

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

        /*

        || This event is defined but not used in the code. No

        || point in wasting codespace on it.

        ||

        || case EV_SCAN_FOUND:

        ||    Serial.println(F("EV_SCAN_FOUND"));

        ||    break;

        */

        case EV_TXSTART:

            Serial.println(F("EV_TXSTART"));

            break;

        case EV_TXCANCELED:

            Serial.println(F("EV_TXCANCELED"));

            break;

        case EV_RXSTART:

            /* do not print anything -- it wrecks timing */

            break;

        case EV_JOIN_TXCOMPLETE:

            Serial.println(F("EV_JOIN_TXCOMPLETE: no JoinAccept"));

            break;

        default:

            Serial.print(F("Unknown event: "));

            Serial.println((unsigned) ev);

            break;

    }

}

void setup() {

//    pinMode(13, OUTPUT);

    while (!Serial); // wait for Serial to be initialized

    Serial.begin(115200);

    delay(100);     // per sample code on RF_95 test

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

    auto* pinMap = Arduino_LMIC::GetPinmap_heltec_lora32();

   os_init_ex(pinMap);

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

    LMIC_reset();

    // 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 (0x13, DEVADDR, nwkskey, appskey);

    #else

    // If not running an AVR with PROGMEM, just use the arrays directly

    LMIC_setSession (0x13, DEVADDR, NWKSKEY, APPSKEY);

    #endif

    #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. The LMIC doesn't let you change

    // the three basic settings, but we show them here.

    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) || defined(CFG_au915)

    // NA-US and AU 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.

    // https://github.com/TheThingsNetwork/gateway-conf/blob/master/US-global_conf.json

    LMIC_selectSubBand(1);

    #elif defined(CFG_as923)

    // Set up the channels used in your country. Only two are defined by default,

    // and they cannot be changed.  Use BAND_CENTI to indicate 1% duty cycle.

    // LMIC_setupChannel(0, 923200000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);

    // LMIC_setupChannel(1, 923400000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_CENTI);

    // ... extra definitions for channels 2..n here

    #elif defined(CFG_kr920)

    // Set up the channels used in your country. Three are defined by default,

    // and they cannot be changed. Duty cycle doesn't matter, but is conventionally

    // BAND_MILLI.

    // LMIC_setupChannel(0, 922100000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_MILLI);

    // LMIC_setupChannel(1, 922300000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_MILLI);

    // LMIC_setupChannel(2, 922500000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_MILLI);

    // ... extra definitions for channels 3..n here.

    #elif defined(CFG_in866)

    // Set up the channels used in your country. Three are defined by default,

    // and they cannot be changed. Duty cycle doesn't matter, but is conventionally

    // BAND_MILLI.

    // LMIC_setupChannel(0, 865062500, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_MILLI);

    // LMIC_setupChannel(1, 865402500, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_MILLI);

    // LMIC_setupChannel(2, 865985000, DR_RANGE_MAP(DR_SF12, DR_SF7),  BAND_MILLI);

    // ... extra definitions for channels 3..n here.

    #else

    # error Region not supported

    #endif

    // Disable link check validation

    LMIC_setLinkCheckMode(0);

    // TTN uses SF9 for its RX2 window.

    LMIC.dn2Dr = DR_SF9;

    // Set data rate and transmit power for uplink

    LMIC_setDrTxpow(DR_SF7,14);

    // Start job

    do_send(&sendjob);

}

void loop() {

    unsigned long now;

    now = millis();

    if ((now & 512) != 0) {

      digitalWrite(13, HIGH);

    }

    else {

      digitalWrite(13, LOW);

    }

    os_runloop_once();

}

What do the uplinks look like in the device data on TTN or the gateway?