Due to high demand, expect some shipping delays at this time - orders may not ship for up to 2-3 business days.
0

Feather M0 LoRa TTN V3
Moderators: adafruit_support_bill, adafruit

Forum rules
If you're posting code, please make sure your code does not include your Adafruit IO Active Key or WiFi network credentials.
Please be positive and constructive with your questions and comments.

Feather M0 LoRa TTN V3

by jimmyg0801 on Thu Apr 21, 2022 4:31 pm

I bought this board because of Adafruit's reputation of being a quality supplier of devices.

So far, I am frustrated that I cannot find any code example of connecting this board the Things Network Stack (TTN V3). Can anyone tell me if it can work and where I can get an example code THAT WORKS on PlatformIO?

jimmyg0801
 
Posts: 6
Joined: Thu Apr 21, 2022 9:59 am

Re: Feather M0 LoRa TTN V3

by jerryn on Thu Apr 21, 2022 5:06 pm

Take a look at the LMIC library https://github.com/mcci-catena/arduino-lmic
There are examples for the feather m0 and instructions fo platformio. I have not used platformio myself but I have used this library with the Arduino IDE.

jerryn
 
Posts: 1719
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather M0 LoRa TTN V3

by jimmyg0801 on Thu Apr 21, 2022 6:35 pm

I'm looking for examples to join the "Things Stack Community Edition"
I have a Helltec Lora 32 OLED device working on TTN3, but CANNOT get the Feather M0 LoRa board code!

jimmyg0801
 
Posts: 6
Joined: Thu Apr 21, 2022 9:59 am

Re: Feather M0 LoRa TTN V3

by jerryn on Thu Apr 21, 2022 6:49 pm

I have used the feather m0 LoRa with TTN v3 using the library and examples I posted above. I don’t think I can help more than that.

jerryn
 
Posts: 1719
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather M0 LoRa TTN V3

by jerryn on Fri Apr 22, 2022 6:34 am

Here is the code I am using to send data from a temp/humidity sensor to TTN V3 from a feather m0 lora:

Code: Select all | TOGGLE FULL SIZE
/*******************************************************************************
 * The Things Network - Sensor Data Example
 *
 * Example of sending a valid LoRaWAN packet with DHT22 temperature and
 * humidity data to The Things Networ using a Feather M0 LoRa.
 *
 * Learn Guide: https://learn.adafruit.com/the-things-network-for-feather
 *
 * Copyright (c) 2015 Thomas Telkamp and Matthijs Kooijman
 * Copyright (c) 2018 Terry Moore, MCCI
 * Copyright (c) 2018 Brent Rubell, Adafruit Industries
 *
 * 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.
 *******************************************************************************/
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>

#include "Adafruit_Si7021.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] = { <REDACTED> };
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] = { <REDACTED> };
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 the TTN console can be copied as-is.
static const u1_t PROGMEM APPKEY[16] = { <REDACTED> };
void os_getDevKey (u1_t* buf) {  memcpy_P(buf, APPKEY, 16);}



// payload to send to TTN gateway
static uint8_t payload[5];
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 for Adafruit Feather M4 LoRa
const lmic_pinmap lmic_pins = {
    .nss = 8,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 4,
    .dio = {3, 12, LMIC_UNUSED_PIN},
    .rxtx_rx_active = 0,
    .rssi_cal = 8,              // LBT cal for the Adafruit Feather M0 LoRa, in dB
    .spi_freq = 8000000,
};

Adafruit_Si7021 sensor = Adafruit_Si7021();

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("artKey: ");
              for (int i=0; i<sizeof(artKey); ++i) {
                if (i != 0)
                  Serial.print("-");
                Serial.print(artKey[i], HEX);
              }
              Serial.println("");
              Serial.print("nwkKey: ");
              for (int i=0; i<sizeof(nwkKey); ++i) {
                      if (i != 0)
                              Serial.print("-");
                      Serial.print(nwkKey[i], HEX);
              }
              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;
            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;
        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 {
        // read the temperature from the Si7021
        float temperature = sensor.readTemperature();
        Serial.print("Temperature: "); Serial.print(temperature);
        Serial.println(" *C");
        // adjust for the f2sflt16 range (-1 to 1)
        temperature = temperature / 100;

        // read the humidity from the si1021
        float rHumidity = sensor.readHumidity();
        Serial.print("%RH ");
        Serial.println(rHumidity);
        // adjust for the f2sflt16 range (-1 to 1)
        rHumidity = rHumidity / 100;
       
        // float -> int
        // note: this uses the sflt16 datum (https://github.com/mcci-catena/arduino-lmic#sflt16)
        uint16_t payloadTemp = LMIC_f2sflt16(temperature);
        // int -> bytes
        byte tempLow = lowByte(payloadTemp);
        byte tempHigh = highByte(payloadTemp);
        // place the bytes into the payload
        payload[0] = tempLow;
        payload[1] = tempHigh;

        // float -> int
        uint16_t payloadHumid = LMIC_f2sflt16(rHumidity);
        // int -> bytes
        byte humidLow = lowByte(payloadHumid);
        byte humidHigh = highByte(payloadHumid);
        payload[2] = humidLow;
        payload[3] = humidHigh;

        // prepare upstream data transmission at the next possible time.
        // transmit on port 1 (the first parameter); you can use any value from 1 to 223 (others are reserved).
        // don't request an ack (the last parameter, if not zero, requests an ack from the network).
        // Remember, acks consume a lot of network resources; don't ask for an ack unless you really need it.
        LMIC_setTxData2(1, payload, sizeof(payload)-1, 0);
    }
    // Next TX is scheduled after TX_COMPLETE event.
}

void setup() {
    delay(5000);
    //while (! Serial);
    Serial.begin(9600);
    Serial.println(F("Starting"));
    sensor.begin();

    // LMIC init
    os_init();
    // Reset the MAC state. Session and pending data transfers will be discarded.
    LMIC_reset();
    // Disable link-check mode and ADR, because ADR tends to complicate testing.
    LMIC_setLinkCheckMode(0);
    // Set the data rate to Spreading Factor 7.  This is the fastest supported rate for 125 kHz channels, and it
    // minimizes air time and battery power. Set the transmission power to 14 dBi (25 mW).
    LMIC_setDrTxpow(DR_SF7,14);
    // in the US, with TTN, it saves join time if we start on subband 1 (channels 8-15). This will
    // get overridden after the join by parameters from the network. If working with other
    // networks or in other regions, this will need to be changed.
    LMIC_selectSubBand(1);

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

void loop() {
  // we call the LMIC's runloop processor. This will cause things to happen based on events and time. One
  // of the things that will happen is callbacks for transmission complete or received messages. We also
  // use this loop to queue periodic data transmissions.  You can put other things here in the `loop()` routine,
  // but beware that LoRaWAN timing is pretty tight, so if you do more than a few milliseconds of work, you
  // will want to call `os_runloop_once()` every so often, to keep the radio running.
  os_runloop_once();
}



with lmic_project_config.h
Code: Select all | TOGGLE FULL SIZE
// project-specific definitions
//#define CFG_eu868 1
#define CFG_us915 1
//#define CFG_au921 1
//#define CFG_as923 1
// #define LMIC_COUNTRY_CODE LMIC_COUNTRY_CODE_JP   /* for as923-JP */
//#define CFG_in866 1
#define CFG_sx1276_radio 1
#define LMIC_USE_INTERRUPTS

jerryn
 
Posts: 1719
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather M0 LoRa TTN V3

by jimmyg0801 on Fri Apr 22, 2022 3:35 pm

Thank you that gets me a little further. I was able to build and program the code. However, I can only send one data packet then the program hangs

Starting
Temperature: 20.00 *C
%RH 1234.00
313866: EV_JOINING
313978: EV_TXSTART
655168: EV_JOINED
netid: 19
devaddr: 260C967B
artKey: (A KEY)
nwkKey: (ANOTHER KEY)
656061: EV_TXSTART
995317: EV_TXCOMPLETE (includes waiting for RX windows)
1026018: EV_TXSTART
OP_TXRXPEND, not sending

Any suggestions?

jimmyg0801
 
Posts: 6
Joined: Thu Apr 21, 2022 9:59 am

Re: Feather M0 LoRa TTN V3

by jerryn on Sat Apr 23, 2022 6:17 am

hmm -- I have reproduced this issue and I have no idea what has broken. It has worked in the past, but clearly something has changed.
I'll see if I can figure out what and will post any progress.

My apologies for the non-working example...

Edited to add -- I also have similar code running on a feather_m4_express with rfm9x featherwing and it also is now apparently broken.
sigh ....

jerryn
 
Posts: 1719
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather M0 LoRa TTN V3

by jerryn on Sat Apr 23, 2022 6:58 am

well... the issue with my featherm4 express/featherwing was just a bad connection to one of the pins... It is now working normally, but I am still unable to get the feather m0 lora to work properly ...

jerryn
 
Posts: 1719
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather M0 LoRa TTN V3

by jimmyg0801 on Sat Apr 23, 2022 9:26 am

That's why it's driving me nuts. I'm a retired software engineer and I have worked on a lot of microprocessor based projects and there was always problems with vendor libraries and insufficient documentation. However these ESP32/ESP8286 devices seem to have more problems than what would be considered reasonable.

The reason I purchased the Adafruit product is because many online reviews said they were a very reputable company with outstanding support. Frankly, I don't see that.

I hope someone (perhaps you) can figure out what LoRaWan TTN3 example will work with this device.

Thanks for your support so far.

jimmyg0801
 
Posts: 6
Joined: Thu Apr 21, 2022 9:59 am

Re: Feather M0 LoRa TTN V3

by jerryn on Sat Apr 23, 2022 9:53 am

AH -- found the issue - ON the feather M0 LoRa , DIO1 is not connected by default. I had to install a jumper from the DIO1 Pin to the D12 pin for my code to work.

also there is one minor change to my code
Code: Select all | TOGGLE FULL SIZE
LMIC_setTxData2(1, payload, sizeof(payload)-1, 0);

should be
Code: Select all | TOGGLE FULL SIZE
LMIC_setTxData2(1, payload, sizeof(payload), 0);

It is now working normally for me.

Note: I do not represent Adafruit -- Just trying to help.

jerryn
 
Posts: 1719
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather M0 LoRa TTN V3

by jimmyg0801 on Sat Apr 23, 2022 1:14 pm

YES!!! LOL

I just found that out when trying another excellent project at: https://github.com/lnlp/LMIC-node

There is a README.md that states that the jumper between DI01 -> Pin 6 (GPIO6) is required. I added the jumper and got the program to work!

I will probably try the example you gave me later, but right now I'm happy with the great documentation of LMIC-Node.

THANK YOU SO MUCH FOR YOUR HELP :) I was really going to give up on this board.

jimmyg0801
 
Posts: 6
Joined: Thu Apr 21, 2022 9:59 am

Re: Feather M0 LoRa TTN V3

by jerryn on Sat Apr 23, 2022 4:14 pm

Thanks for the LMIC-NODE link. I’ll give it a try.
Good luck with your projects.

jerryn
 
Posts: 1719
Joined: Sat Sep 14, 2013 9:05 am

Re: Feather M0 LoRa TTN V3

by saddenaal564 on Wed May 11, 2022 8:36 am

I have a Helltec Lora 32 OLED device working on TTN3, but CANNOT get the Feather M0 LoRa board code!

saddenaal564
 
Posts: 1
Joined: Wed May 11, 2022 8:25 am

Re: Feather M0 LoRa TTN V3

by jimmyg0801 on Wed May 11, 2022 5:03 pm


jimmyg0801
 
Posts: 6
Joined: Thu Apr 21, 2022 9:59 am

Please be positive and constructive with your questions and comments.