Inconsistent payload with LoRa and TTN

Seeking help from anyone knowledgeable in things LoRa. I am a novice.

I have two "environmental monitor" boxes which consist of Arduino R4 Minimas with a bunch of sensors in the Grove ecosystem. I have the Arduino get info from the sensors and send that data to a LoRaWAN gateway where it is decoded. One of these boxes appears to be functioning fine and sending the correct information to the gateway, the other is consistently having a problem...

Relative to my office, the gateway is through a couple walls and maybe 30ft away from my desk. One of the boxes is set up a similar distance away from the gateway, through one wall, and appears to be functioning fine, as in it sends payloads to the gateway that reflect the data read from the sensors. The other box is having issues.

If I set the other box up in my office, it sends the expected payloads. As soon as I move this device close to the gateway, for instance on the same factory shopfloor as the gateway, the payloads get messed up. Here is an example of a correct payload:

"uplink_message": {
      "session_key_id": "AZRBzw7rIaY+4yHsrYNgsg==",
      "f_port": 8,
      "f_cnt": 1723,
      "frm_payload": "G7MD8wUoAwgIaS9i1RY=",
      "decoded_payload": {
        "co2Estimation": 776,
        "dustConcentration": 121.3,
        "humidity": 10.11,
        "oxygenConcentration": 21.53,
        "temperature": 70.91,
        "voc": 1320
      }

And here is what the incorrect payloads look like:

"uplink_message": {
      "session_key_id": "AZRL1ottMloQQJFLvfw0Mw==",
      "f_port": 8,
      "f_cnt": 41,
      "frm_payload": "AbzQUCBwIC2AhBOQiw==",
      "decoded_payload": {
        "co2Estimation": 8237,
        "dustConcentration": 50.08,
        "humidity": 533.28,
        "oxygenConcentration": 329,
        "temperature": 4.44,
        "voc": 8304
      }

Again, when I set up the box closer to the gateway, it sends something like the second example but then seems to resolve itself when positioned further away, through walls, like in my office. They have similar data rates as well as SNR and RSSI. They use the same exact payload formatter, and same method of sending the payloads. I'm sure if I moved the other box it would give similar results.

If anyone has an idea of what might cause this I would love to be educated, it's driving me nuts!

You have to see the raw data in order to determine if there is some kind of pattern. When I say raw I mean BITS as a one bit missing can make the following data look bizarre.
LORA has a lot of tuning settings that are often a trade off. Icreasing payload may reduce range or reliability etc. Normally we harangue noobs to read the pinned post re How to get the best from the forum, but in this case a wiring diagram will not be of much help.
Do yourself a paper and do a search on LORA tradeoffs re data integrity, maybe even ask an AI or two.

1 Like

Is the payload bracketed with CRC32 fields that you check to determine valid data?

And the SNR and RSSI values reported are ?

And what spreading factor is in use ?

can you give more detail of the hardware, e.g. LoRa modules connected to the Arduino R4 and the LoRaWAN gateway
what LoRaWAN libraries are you using?
are there other LoRa devices in the area?

Frequency plan for both is US 902-928 MHz, FSB 2

An example:

Device 1 (wrong payload data):

Data rate - SF7BW125 (OTAA)
SNR - 14
RSSI - -59

Device 2 (working as expected):

Data rate - SF7BW125 (OTAA)
SNR - 13.5
RSSI - -77

So if you move Device 1 further away from the Gateway is the payload then OK ?

And if you move Device 2 closer to the Gateway is the payload then corrupted ?

The LoRa module is a Grove Wio E5

I'm actually not using any libraries at the moment, which is probably a bad thing, I am using a version of the sample code provided at this website, but did end up changing some things with it to get my devices to connect to the gateway which of course could be part of the problem and I will provide the code at the bottom of this. If there are any good libraries that you would recommend that are beginner friendly, I would happily use them.

There are several other LoRa devices in the area, mostly lights and buttons like the "kuando Busylight IoT Omega LoRaWAN" and "Milesight WS101 Smart Button" which I have never used and know nothing about. The gateway was there so I just decided to try to use it for a school project.

Here are the related functions as they are in my program, I am not the original author of this:

//Functions for LoRa module
static int at_send_check_response(char *p_ack, int timeout_ms, char*p_cmd, ...)
{
    int ch;
    int num = 0;
    int index = 0;
    int startMillis = 0;
    va_list args;
    char cmd_buffer[256];  // Adjust the buffer size as needed
    memset(recv_buf, 0, sizeof(recv_buf));
    va_start(args, p_cmd);
    vsprintf(cmd_buffer, p_cmd, args);  // Format the command string
    mySerial.print(cmd_buffer);
    Serial.print(cmd_buffer);
    va_end(args);
    delay(50);
    startMillis = millis();


    if (p_ack == NULL)
    {
        Serial.println("p_ack none");
        return 0;
    }

    do
    {
        while (mySerial.available() > 0)
        {
            ch = mySerial.read();
            recv_buf[index++] = ch;
            Serial.print((char)ch);
            delay(2);
        }

        if (strstr(recv_buf, p_ack) != NULL)
        {
            return 1;
        }

    } while (millis() - startMillis < timeout_ms);
    return 0;
}

static void recv_prase(char *p_msg)
{
    if (p_msg == NULL)
    {
        return;
    }
char*p_start = NULL;
    int data = 0;
    int rssi = 0;
    int snr = 0;

    p_start = strstr(p_msg, "RX");
    if (p_start && (1 == sscanf(p_start, "RX: \"%d\"\r\n", &data)))
    {
        Serial.println(data);
        Serial.print("led :");
        led = !!data;
        Serial.print(led);
        if (led)
        {
            digitalWrite(LED_BUILTIN, LOW);
        }
        else
        {
            digitalWrite(LED_BUILTIN, HIGH);
        }
    }

    p_start = strstr(p_msg, "RSSI");
    if (p_start && (1 == sscanf(p_start, "RSSI %d,", &rssi)))
    {
        Serial.print("rssi:");
        Serial.print(rssi);
    }
    p_start = strstr(p_msg, "SNR");
    if (p_start && (1 == sscanf(p_start, "SNR %d", &snr)))
    {
        Serial.print("snr :");
        Serial.print(snr);
    }
}

This is the basic loop, it's a timed action function that is called periodically as set in the setup() portion. I just based it on how the sample code worked, but there is probably something wrong with it.

class LoRaComms : public VariableTimedAction {
  private:
    unsigned long run() {
      if (is_exist) {
        int ret = 0;
        if (is_join) {
          ret = at_send_check_response("+JOIN: Network joined", 12000, "AT+JOIN\r\n");
          if (ret) {
              is_join = false;
          }
          else {
              at_send_check_response("+ID: AppEui", 1000, "AT+ID\r\n");
              Serial.print("JOIN failed!\r\n\r\n");
              delay(5000);
          }
        }
        else {
          u16 value = 0;
          u8 data[6] = {0};
          char cmd[128];
          /*
          if (ratio != lastRatio && ratio > 0) {
            lastRatio = ratio;
            submitRatio = lastRatio * 100;
          }
          */
          if (oxygenData != lastOxygenData) {
            lastOxygenData = oxygenData;
            submitOxygen = lastOxygenData * 100;
          }
          if (lastTemp != temp) {
            lastTemp = temp;
            submitTemp = lastTemp * 100;
          }
          if (lastHum != hum) {
            lastHum = hum;
            submitHum = lastHum * 100;
          }
          if (lastDust != dust_concentration && dust_concentration > 1) {
            lastDust = dust_concentration;
            submitDust = lastDust * 100;
          }
          if (lastVoc != tvoc_ppb) {
            lastVoc = tvoc_ppb;
            submitVoc = lastVoc;
          }
          if (lastCo2 != co2_eq_ppm) {
            lastCo2 = co2_eq_ppm;
            submitCo2 = lastCo2;
          }
          sprintf(cmd, "AT+CMSGHEX=\"%04X%04X%04X%04X%04X%04X\"\r\n", int(submitTemp), int(submitHum), int(submitVoc), int(submitCo2), int(submitOxygen), int(submitDust)); //int(submitRatio) remember to add a %04X if adding this back in
          ret = at_send_check_response("Done", 5000, cmd);
          if (ret)
          {
              recv_prase(recv_buf);
          }
          else
          {
              Serial.print("Send failed!\r\n\r\n");
          }
        }
      }
      else {
        delay(1000);
      }
      return 0;
    }
};

The following is in setup():

I did change the +DR to US915 and made it set to +DR1 to get it to connect, but I'm sure there are other setup issues a knowledgeable person could point out.

//LoRa Module
    if (at_send_check_response("+AT: OK", 200, "AT\r\n")) {
      is_exist = true;

      
      if (at_send_check_response("+ID:", 1000, "AT+ID\r\n")) {
        
          Serial.print("Received ID data: ");
          Serial.println(recv_buf);
      } else {

          Serial.println("Failed to get ID data.");
      }

      at_send_check_response("+MODE: LWOTAA", 1000, "AT+MODE=LWOTAA\r\n");
      at_send_check_response("+DR: US915", 1000, "AT+DR=US915\r\n");
      at_send_check_response("+DR: DR1", 1000, "AT+DR=DR1\r\n"); //TO INCREASE PACKET SIZE TO 53 BYTES
      at_send_check_response("+CH: NUM", 1000, "AT+CH=NUM,8-15\r\n");
      at_send_check_response("+KEY: APPKEY", 1000, "AT+KEY=APPKEY,\"2B7E151628AED2A6ABF7158809CF4F3D\"\r\n");
      at_send_check_response("+CLASS: C", 1000, "AT+CLASS=A\r\n");
      at_send_check_response("+PORT: 8", 1000, "AT+PORT=8\r\n");

      delay(200);
      is_join = true;
    }
    else {
        is_exist = false;
        Serial.print("No E5 module found.\r\n");
    }

    lora.start(100000);

Yes when Device 1 is closest to the gateway, the payload received is wrong, when a bit further away but still in the same room it sometimes sends a correct payload sometimes a wrong one, and when it is farthest away (through multiple walls in my office) it sends the correct payload consistently.

I haven't tried to break Device 2 yet, I set it up in the room where it currently is and it has been working well ever since I put it there, but the hardware and code are identical so I would expect it works the same. I can test this next week, but as it is right now it is providing good data.

There is a problem when nodes are close to a Gateway, in that packets that are very strong can be received, but corrupt, on the wrong channel\gateway.

However, if the nodes are using packet CRC checking, then the Gateway should be rejecting corrupt packets.

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