jgromes/RadioLib

[SX128x] High packet loss on spreading factor 5

Closed this issue · 6 comments

Describe the bug
High packet loss on SF5 when using an SX1280 modem. SF6 provides a higher data rate.

Debug mode output

When sketches configured with SF6:

Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 93 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 93 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps
Bitrate: 91 kbps

When sketches configured with SF5:

Bitrate: 22 kbps
Bitrate: 30 kbps
Bitrate: 20 kbps
Bitrate: 28 kbps
Bitrate: 28 kbps
Bitrate: 18 kbps
Bitrate: 26 kbps
Bitrate: 34 kbps
Bitrate: 32 kbps
Bitrate: 22 kbps
Bitrate: 18 kbps
Bitrate: 12 kbps
Bitrate: 20 kbps
Bitrate: 28 kbps
Bitrate: 16 kbps
Bitrate: 32 kbps
Bitrate: 24 kbps

To Reproduce

Sketch that is causing the module fail

Transmit:

#include <Arduino.h>
#include "Adafruit_TinyUSB.h"
#include <SPI.h>
#include <variant.h>
#include <RadioLib.h>

    SX1280 radio = new Module(24, 15, 16, 25);

volatile bool packet_rx = false;
int packets = 0;

void setflag() {
    packet_rx = true;
}

void setup() {
    Serial.begin(115200);
    while(!Serial);
    uint8_t sf = 5;
      int state = radio.begin(2408.0, 1625.0, sf, 5, 0x14, 1, 150);
      radio.setRfSwitchPins(19, 20);
      radio.explicitHeader();
radio.setCRC(2);
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true) { delay(10); }
  }
}

void loop() {
    uint8_t data[255] = {0};
    for (int i = 0; i < 255; i++) {
        data[i] = i;
    }
    int16_t status;
    while (true) {
    status = radio.transmit(data, 255);
    if (status == RADIOLIB_ERR_NONE) Serial.println("transmitting...");
    }
}

Receive:

#include <Arduino.h>
#include "Adafruit_TinyUSB.h"
#include <SPI.h>
#include <variant.h>
#include <RadioLib.h>

    SX1280 radio = new Module(24, 15, 16, 25);

volatile bool packet_rx = false;
volatile bool tx = false;
int packets = 0;

void setflag() {
        packet_rx = true;
}

void setup() {
    Serial.begin(115200);
    while(!Serial);
    uint8_t sf = 5;
      int state = radio.begin(2408.0, 1625.0, sf, 5, 0x14, 1, 150);
      radio.setRfSwitchPins(19, 20);
      radio.explicitHeader();
radio.setCRC(2);
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success! rx ready"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true) { delay(10); }
  }
    radio.setPacketReceivedAction(setflag);
    radio.startReceive();
}

unsigned long last_stat = millis();

void loop() {
    if (packet_rx) {
        packet_rx = false;
        uint8_t length = radio.getPacketLength();
        uint8_t data[255];
        radio.readData(data, 255);
        for (int i = 0; i < length; i++) {
            if (data[i] != i) {
                Serial.println("Packet corrupted!!");
            }
        }
        radio.startReceive();
        packets++;
    }

    if (millis() - last_stat >= 1000) {
        Serial.print("Bitrate: ");
        Serial.print(((packets * 255) * 8) / 1000);
        Serial.println(" kbps");
        last_stat = millis();
        packets = 0;
    }
}

Expected behavior
Data rate should be closer to around 140kbps+, or at least higher than the data rate of SF6 anyway!

Additional info (please complete):

Note, performance seems to be slightly higher with the CRC check disabled on the receiver, see below:

Bitrate: 28 kbps
Bitrate: 34 kbps
Bitrate: 32 kbps
Bitrate: 30 kbps
Bitrate: 32 kbps
Bitrate: 30 kbps
Bitrate: 42 kbps
Bitrate: 30 kbps
Bitrate: 18 kbps
Bitrate: 40 kbps
Bitrate: 40 kbps
Bitrate: 38 kbps
Bitrate: 36 kbps
Bitrate: 30 kbps
Bitrate: 28 kbps
Bitrate: 44 kbps
Bitrate: 24 kbps
Bitrate: 42 kbps
Bitrate: 38 kbps
Bitrate: 38 kbps
Bitrate: 34 kbps
Bitrate: 28 kbps
Bitrate: 28 kbps

(Or this is just me seeing things that aren't there)

Increasing the SPI frequency in the SPI settings variable also has no affect.

This looks like some massive breach of laws to me - as in, worthy of spending time behind iron bars.

I fully agree with @StevenCellist that what you have made there is a poor man's jammer. Definitely not legal.

My guess is that your receive code is unable to keep up with the transmitter, since apart from getting the packets from the radio it also has to check the contents and print into the Serial, which is very slow. Also the non-standard sync word probably doesn't help either.

I fully agree with @StevenCellist that what you have made there is a poor man's jammer. Definitely not legal.

That was not the intention. This sketch was only run for a brief period of time regardless. I shall be careful with its use nonetheless.

I will experiment further, thanks.

Interestingly enough, after resetting the sync word to the default value (RADIOLIB_SX128X_SYNC_WORD_PRIVATE), that seems to have fixed it. I think that sync word was a copy - paste from another bit of code of mine, hence I did not notice my mistake. Thank you.