Uplinks repeating - MCCI LMIC library on a Heltec module

Hello everyone, I am new to LoRaWAN and I am testing the Heltec Wireless Stick modules as end devices, for this I used the recommended library which was LMIC and it works correctly, but when connecting to TTN through ABP the transmissions have a kind of retransmission of events, as you can see in the image

image

As you can see the information is sent but the events are very annoying since they appear in TTN as packets without any information.

image

I have reviewed some forums and they suggest that I separate the end devices from the gateway at a certain distance and some other alternatives that do not give me a solution, I hope you can help me and thanks in advance

Here´s my code :slight_smile:

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

// include the DHT22 Sensor Library
#include "DHT.h"

// DHT digital pin and sensor type
#define DHTPIN 10
#define DHTTYPE DHT22

// configurar el pin utilizado para la medicion de voltaje del divisor resistivo del NTC
#define CONFIG_THERMISTOR_ADC_PIN A0
// configurar el valor de la resistencia que va en serie con el termistor NTC en ohms
#define CONFIG_THERMISTOR_RESISTOR 9550l

#ifdef COMPILE_REGRESSION_TEST

// LoRaWAN NwkSKey, network session key
static const PROGMEM u1_t NWKSKEY[16] = { 0x15, 0x32, 0xEE, 0x5E, 0x50, 0x3D, 0xD4, 0xB3, 0xC1, 0xF1, 0x74, 0x7E, 0x95, 0x6E, 0x1C, 0x93 };

// LoRaWAN AppSKey, application session key
static const u1_t PROGMEM APPSKEY[16] = { 0x9A, 0x54, 0x9D, 0x9F, 0x55, 0x54, 0xFA, 0xB4, 0x87, 0x23, 0x74, 0xA1, 0xBC, 0x88, 0xFE, 0x77 };

#ifndef COMPILE_REGRESSION_TEST
static const u4_t DEVADDR = 0x260CAC49 ;
#else
static const u4_t DEVADDR = 0;
#endif

void os_getArtEui (u1_t* buf) { }
void os_getDevEui (u1_t* buf) { }
void os_getDevKey (u1_t* buf) { }


static uint8_t payload[5];
static osjob_t sendjob;

const unsigned TX_INTERVAL = 60;

const lmic_pinmap lmic_pins = {
    .nss = 18,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 14,
    .dio = {26, 35, 34},
    .rxtx_rx_active = 0,
    .rssi_cal = 8,              // LBT cal for the Adafruit Feather M0 LoRa, in dB
    .spi_freq = 8000000,
};

// init. DHT
DHT dht(DHTPIN, DHTTYPE);

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;
        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;
        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;
    }
}
//-------------------------------------------------------------------------------------------
int32_t thermistor_get_resistance(uint16_t adcval)
{
  // calculamos la resistencia del NTC a partir del valor del ADC
  return (CONFIG_THERMISTOR_RESISTOR * ((4095.0 / adcval) - 1));
}
//-------------------------------------------------------------------------------------------
float thermistor_get_temperature(int32_t resistance)
{
  float temp;
  temp = log(resistance);
  temp = 1 / (-0.00852320883160124 + (0.00145388599096923 * temp) + (-0.0000030650257379238766 * temp * temp * temp));
  return temp - 273.15;
}
//-------------------------------------------------------------------------------------------
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 {
        float temperatura;
        uint32_t resistencia;
        resistencia = thermistor_get_resistance(analogRead(CONFIG_THERMISTOR_ADC_PIN));
        temperatura = thermistor_get_temperature(resistencia);
        
        Serial.print("Temperature: "); Serial.print(temperatura);
        Serial.println(" *C");

          int16_t celciusInt = temperatura * 100; // convert to signed 16 bits integer: 0x0929
          uint8_t buffer[2]; // reserve 2 bytes in memory
         
          buffer[0] = celciusInt >> 8;
          buffer[1] = celciusInt;
          
          // Send on port 1, without asking for confirmation:
          LMIC_setTxData2(1, buffer, sizeof(buffer), 0); // 0x0929 for 23.45
    }
    // Next TX is scheduled after TX_COMPLETE event.
}

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

    // LMIC init
    os_init();
    // Reset the MAC state. Session and pending data transfers will be discarded.
    LMIC_reset();
    
    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);

    // We'll disable all 72 channels used by TTN
    // LMIC_selectSubBand(2);
    for (int c = 0; c < 72; c++){
      LMIC_disableChannel(c);
    }
    // We'll only enable Channel 16 (905.5Mhz) since we're transmitting on a single-channel
    LMIC_enableChannel(12);

    // 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() {
  os_runloop_once();
}

EDIT:

To clarify something, I have modified ABP by OTAA with the same problem, I thought I could just get around the problem but the uplinks persist.

16:05:34.320 -> Packet queued
16:05:39.540 -> 4740306: EV_TXCOMPLETE (includes waiting for RX windows)
16:05:40.008 -> 4770942: EV_TXSTART
16:05:45.242 -> 5098017: EV_TXCOMPLETE (includes waiting for RX windows)
16:05:45.756 -> 5128654: EV_TXSTART
16:05:50.939 -> 5454447: EV_TXCOMPLETE (includes waiting for RX windows)
16:05:51.456 -> 5485083: EV_TXSTART
16:05:56.678 -> 5810878: EV_TXCOMPLETE (includes waiting for RX windows)
16:05:57.148 -> 5841514: EV_TXSTART
16:06:03.374 -> 6230326: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:03.378 -> 9980347: EV_TXSTART
16:07:03.378 -> Packet queued
16:07:08.641 -> 10308703: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:09.096 -> 10339340: EV_TXSTART
16:07:14.350 -> 10665134: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:14.813 -> 10695770: EV_TXSTART
16:07:20.032 -> 11021565: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:20.500 -> 11052201: EV_TXSTART
16:07:25.710 -> 11377995: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:26.222 -> 11408631: EV_TXSTART
16:07:31.459 -> 11734426: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:31.919 -> 11765062: EV_TXSTART
16:07:37.118 -> 12090857: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:37.622 -> 12121493: EV_TXSTART
16:07:42.828 -> 12447288: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:43.343 -> 12477924: EV_TXSTART
16:07:48.545 -> 12803719: EV_TXCOMPLETE (includes waiting for RX windows)
16:07:49.045 -> 12834355: EV_TXSTART
16:07:55.261 -> 13223164: EV_TXCOMPLETE (includes waiting for RX windows)
16:08:55.246 -> 16973184: EV_TXSTART
16:08:55.294 -> Packet queued
1 Like

One thing I see is that the RSSI-values are extremely high. What is the distance between node and gateway?

1 Like

Hi wolfp, approximately 10 meters, but I have tried them even with 6 floors of difference and the error persists, something else is that sometimes the error does not occur and the transmission works very well

Please format your posts for readability. Use </> above the textbox for this.

2 Likes

Welcome,

Star by trying to get your RSSI down, -50 even -70 at least. Brick wall and 10m or more, should normally suffice.

Then let see what happens

TX intervals need to be with in FUP, please.

Why are you using ABP rather than OTAA?

Which version of LMIC are you using and where did you get it from?

What region are you in?

Why is the uplink interval set to 60s in breach of Fair Use Policy for TTN?

As above, if it’s text, please copy & paste, not screen shots. The console is tricky so that’s an exception but the serial log can be text.

1 Like

Hello @Johan_Scheepers, thank you very much for your help. I carried out the test with a much greater distance and between floors but the error persisted, there are minimal occasions in which the transmission works well even with the gateway close to the node.

It is a problem if the module & gateway is too close and this needs to be resolved as part of the solution, but the repeating problem is firmware related.

1 Like

Can you please answers Nick questions as well?

1 Like

Hello @descartes,

Why are you using ABP rather than OTAA?
At the moment I am doing tests with these devices, with OTAA I was not successful and I used ABP which worked fine but this error appeared and I would like to solve it.

Which version of LMIC are you using and where did you get it from?
I am using MCCI LoRaWAN Arduino LMIC library from version 4.1.0 available in Arduino Library Manager

What region are you in?
I am from Ecuador, but I am using the US915 region for the equipment I have

Why is the uplink interval set to 60s in breach of Fair Use Policy for TTN?
Sorry, I did not consider that this rule was in force but I have tried with larger intervals and the error persists, I would be happy to read your options and I appreciate your questions

1 Like

ABP is not working fine - perhaps better to solve the OTAA issue?

OTAA solves many issues with configuration which is what is going on here with your ABP implementation. The stack is rejecting a MAC command from the NS that is likely to be related to the dwell time for the region, something that can’t be rejected. This is an educated guess as I’d need to see far more details to figure out who can decode / debug it all.

What was the problem with OTAA? Most likely not hearing the Join Accept due to the proximity of the device to the gateway.

There also seems to be a certain amount of cruft in the code - like the COMPILE_REGRESSION_TEST that is not in the MCCI LMIC ABP example around the DEVADDR and you’ve got a DHT sensor that’s not being used. All this stuff is complicated enough, best to remove anything not being used so you can be sure that it’s not interfering.

1 Like

An additional hint: imho you do an uplink every 6 seconds. This is rather often, perhaps you should increase TX_INTERVAL.

2 Likes

@wolfp, the device appears to be in a runaway loop of rejecting ADR requests - but the code does show that it is set to 60 seconds, the out of the box MCCI LMIC setting - so @infocades, you will need to increase the TX_INTERVAL to keep within the Fair Use Policy.

3 Likes

Hello everyone, I have followed your advice regarding the presence of uplinks, I modified the code by removing everything unnecessary and increasing the transmission time to 120 seconds, with successful results, something I wanted to add is that once the node starts to send packages you have to restart the session and the state of the mac in TTN, it’s something strange and I still want to find out why I have to restart it 2 times for everything to go well, anyway thank you all very much, this time it works very well

This will not be within the Fair Use Policy for any number of bytes. Please do the research / learning / reading to set it to an appropriate interval for your payload size.

You may, most of us don’t - you should be asking why and what you need to do to resolve this.

2 Likes

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.