Search code examples
pythoncarduinolora

rfm9x.receive() - Python LoRa receive method drops the first 4 characters


I'm planning to set up a local LoRa network with a receiver (running Python on Raspberry Pi Zero) and several transmitters (running C code on Arduino).

To start on this I was testing some sketches from Adafruit and several other online tutorials and could get a transmitter and receiver to communicate using the RFM95 module.

But the issue is when the Python code reads the LoRa packet it drops the first 4 characters from the packet transmitted by the source.

What could be done to fix this? I suspect this could be a byte/string conversion issue, but I couldn't get it to work yet.

Transmitter code (C on Arduino):

....
void loop() {
  Serial.print("Sending - Packet:");
  Serial.println(msgCount);
  LoRa.beginPacket();
  LoRa.print("Packet:");
  LoRa.print(msgCount);
  LoRa.endPacket();
  msgCount++;
  delay(5000);
}
.......

Receiver code (Python on PiZero):

.......
while True:
    packet = None
    packet = rfm9x.receive()
    if packet is None:
        print('Waiting for PKT')
    else:
        prev_packet = packet
        packet_text = str(prev_packet, "utf-8")
        print(packet_text)
        time.sleep(1)
    time.sleep(0.1)
........

Expected output at the receiver:

Packet:1
Packet:2
Packet:3
.......
Packet:10
Packet:11
........

Actual output at the receiver:

et:1
et:2
et:3
.......
et:10
et:11
.......

I tried the below functions/methods without any success:

packet_text = prev_packet.decode("ascii", 'ignore')
packet_text = prev_packet.decode("utf-8", 'ignore')

Any help is appreciated! Thanks!


Solution

  • It seems you missed the documentation of RFM9x.receive():

    receive(*, keep_listening: bool = True, with_header: bool = False, with_ack: bool = False, timeout: float | None = None) → bytearray | None

    Wait to receive a packet from the receiver. If a packet is found the payload bytes are returned, otherwise None is returned (which indicates the timeout elapsed with no reception). If keep_listening is True (the default) the chip will immediately enter listening mode after reception of a packet, otherwise it will fall back to idle mode and ignore any future reception. All packets must have a 4-byte header for compatibility with the RadioHead library. The header consists of 4 bytes (To,From,ID,Flags). The default setting will strip the header before returning the packet to the caller. If with_header is True then the 4 byte header will be returned with the packet. The payload then begins at packet[4]. If with_ack is True, send an ACK after receipt (Reliable Datagram mode)

    What could be done to fix this?

    One could send a header or use with_header = True.