jgromes / RadioLib

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

Extra bits after the message using RFM69HCW module on feather 32u4 #1126

Closed samgosamgo closed 4 months ago

samgosamgo commented 4 months ago

Hello, I am attempting to send a message with the following structure: preamble, sync word, and message

It seems that there are some unnecessary bits in the packet. There is 1 bit before and after the preamble, and 18 bits after the preamble.

The expected output is (in hex) 0xAAAAD29207074b22 (in binary) 1010101010101010110100101001001000000111000001110100101100100010

The output I am currently getting is (in binary) 1 1010101010101010 1 110100101001001000000111000001110100101100100010 010100101010100001 (here I have separated in space the unnecessary and necessary bits)

The following is my code.

#include <RadioLib.h>
#include <SPI.h>

#define LED 13
#define RFM69_CS 8
#define RFM69_INT 7
#define RFM69_RST 4

RF69 radio = new Module(RFM69_CS, RFM69_INT, RFM69_RST);

void setup() {
  // put your setup code here, to run once:
  SPI.begin();
  Serial.begin(9600);
  while (!Serial) {
    delay(1);
  }
  pinMode(LED, OUTPUT);
  pinMode(RFM69_RST, OUTPUT);
  digitalWrite(RFM69_RST, LOW);
  Serial.println("Feather RFM69 RX Test! with RadioLib");

  // Blink LED to indicate start of setup
  digitalWrite(LED, HIGH);
  delay(100);
  digitalWrite(LED, LOW);
  delay(100);

  Serial.println("Resetting RFM69...");
  digitalWrite(RFM69_RST, HIGH);
  delay(100);  // Increased delay
  digitalWrite(RFM69_RST, LOW);
  delay(100);  // Increased delay

  Serial.print(F("[RFM69] Initializing ... "));
  int state = radio.begin();
  if (state == RADIOLIB_ERR_NONE) {
    Serial.println(F("success!"));
  } else {
    Serial.print(F("failed, code "));
    Serial.println(state);
    while (true);
  }
  Serial.println("RFM69 initialization succeeded");

  radio.packetMode();
  radio.setFrequency(434.0);
  radio.setBitRate(24.0);
  radio.setFrequencyDeviation(25.0);
  delay(100);

  uint8_t sync[] = {0xd2, 0x92};
  radio.setSyncWord(sync, sizeof(sync));
  radio.setPreambleLength(16);
  delay(100);

  radio.setOutputPower(20, true);
  radio.fixedPacketLengthMode(0);
  radio.setCrcFiltering(false);
  radio.disableAES();
  radio.disableAddressFiltering();
  radio.enableSyncWordFiltering(0);
  Serial.println("RFM69 configured");

}

void loop() {
  // put your main code here, to run repeatedly:
  uint8_t message[] = {0x07, 0x07, 0x4B, 0x22};
  int state = radio.transmit(message, sizeof(message));
  radio.finishTransmit();

  if (state == RADIOLIB_ERR_NONE) {
    Serial.println("Message sent successfully!");
  } else {
    Serial.print("Message send failed, code ");
    Serial.println(state);
  }

  delay(1000);
}

I am using feather 32u4 with RFM69HCW module, and using RTL-SDR driver to receive the signal. Is there a way to get rid of the unnecessary bits?

jgromes commented 4 months ago

The first bit before preamble is likely a ramp-up of the power amplifier - this is very common and can be ignored. That's why the preamble and sync word is there, to let you distinguish a packet from a noise.

Next, the bits at the end - how do you decide where to stop receiving your packet? Typically this would be done by including a length field in the packet itself (which you disabled) or using only packets of fixed lengths, in which case there is no need for you to process beyond that length.

Finally, there's the issues in your code:

  1. you are not checking the return status, so you have no way to know whether any of that configuration failed.
  2. radio.fixedPacketLengthMode(0); - A packet of fixed length 0 seems like it shouldn't work at all. What were you trying to achieve by this?
  3. radio.finishTransmit(); - why are you calling this? It's being done internally by transmit, none of the examples reference finishTransmit, so I don't understand why you felt the need to add it.
samgosamgo commented 4 months ago

First, thank you for a speedy reply.

  1. I added the configuration checks in this format for any configuration lines, and there seems to be no errors on any configuration set ups.

    state = radio.setCrcFiltering(false);
    if (state != RADIOLIB_ERR_NONE) {
    Serial.print(F("Set CRC filtering failed, code "));
    Serial.println(state);
    while (true);
    }
  2. I was trying to set the format to unlimited length packet format, which according to the RFM69HCW module datasheet, Unlimited length packet format is selected when bit PacketFormat is set to 0 and PayloadLength is set to 0.

  3. This was a mistake on my end, and it seems to have no effect on the output.

I have also tried

radio.fixedPacketLengthMode(4); // size of message is 4 bytes

which doesn't drop the extra bits at the end.

jgromes commented 4 months ago
  1. I suspected as much, but it is a good practice.
  2. Unlimited packet mode has other implications; just setting two register values to 0 will not magically enlarge the internal FIFO to an infinite size - for example, you need to be actively refilling the FIFO as it empties out during transmission. RadioLib implements this in its Stream mode, see the Stream examples. I don't know what will happen if you set payload lendgth to zero without actually actively refilling the FIFO, it might well lead to issues.

which doesn't drop the extra bits at the end.

Why do you think there are extra bits? Or rather, how should the SDR distinguish the bits from the noise?

samgosamgo commented 4 months ago

I'm still not sure why there are extra bits at the end. Regardless, it seems like there is no problem retrieving the message with the feather 32u4 with RFM69HCW module. Thank you for your assistance.

jgromes commented 4 months ago

And I remain unconvinced these extra bits are being transmitted by the radio. I think you are just taking some noise after the packet end and interpreting it as "bits". Since the only thing I know about how you are receiving the data is "using RTL-SDR driver to receive the signal.", I don't whether that could be the case.