jgromes / RadioLib

Universal wireless communication library for embedded devices
https://jgromes.github.io/RadioLib/
MIT License
1.59k stars 398 forks source link

[SX128x] High packet loss on spreading factor 5 #1253

Closed jacobeva closed 1 month ago

jacobeva commented 1 month ago

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: ```c++ #include #include "Adafruit_TinyUSB.h" #include #include #include 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: ```c++ #include #include "Adafruit_TinyUSB.h" #include #include #include 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):

jacobeva commented 1 month ago

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)

jacobeva commented 1 month ago

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

StevenCellist commented 1 month ago

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

jgromes commented 1 month ago

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.

jacobeva commented 1 month ago

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.

jacobeva commented 1 month ago

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.