adafruit / adafruit/Adafruit_CircuitPython_RFM9x

rfm9x corrupted header

Open
#74 5 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
76
Forks
53
PR merge metrics
No merged PRs in 30d

Description

when using rfm9x to transfer sensor data to another rfm9x to forward to AIO, I have observed something strange.

EDIT 4/14/2022

Throughout working this issue myself, I have found some interesting things.

1. The corruption is limited to the flag position of the header. There is never another place in the package that is corrupted.
2. The transmit is done using CRC enabled, and 'with header' so ACK should be working. I never receive a 'no ack' unless the receiver program is not running or the radios are too far apart.
3. Could it be that the CRC and ACK are limited to the payload and not the entire packet?
4. The program worked better when I did not use asyncio. I needed a way to keep the data acquisition going because I needed nearly continuous monitoring of the wind speed. I worked this into the program using asyncio, but failures began to get worse.
5. Not only is the flag byte the only one that gets corrupted, it is always (I think) corrupted the same way. For example, if rfm9x.flags is set to 5, and the flag byte gets corrupted, this is what it looks like in hex.
Received raw packet: ['0x2', '0x3', '0x5e', '0x45', '0x31', '0x2e', '0x34', '0x33']

Note that the fourth byte has the value of 0x45, which is the insertion of the number 4 before the flag value of 5. Every corrupt flag is the same, the flag value is preceded by a 4.


several examples: corrupted byte \/
Received raw packet: ['0x2', '0x3', '0x64', '0x42', '0x39', '0x39', '0x36', '0x2e', '0x32']
Received raw packet: ['0x2', '0x3', '0x56', '0x42', '0x39', '0x39', '0x36', '0x2e', '0x33']
Received raw packet: ['0x2', '0x3', '0x3e', '0x45', '0x32', '0x2e', '0x31', '0x34']
Received raw packet: ['0x2', '0x3', '0x19', '0x43', '0x35', '0x30', '0x2e', '0x31', '0x33']
Received raw packet: ['0x2', '0x3', '0x11', '0x43', '0x34', '0x39', '0x2e', '0x36', '0x34']
Received raw packet: ['0x2', '0x3', '0xf7', '0x43', '0x34', '0x38', '0x2e', '0x33', '0x31']
Received raw packet: ['0x2', '0x3', '0xf3', '0x44', '0x34', '0x2e', '0x34', '0x31']
Received raw packet: ['0x2', '0x3', '0xf1', '0x43', '0x34', '0x38', '0x2e', '0x39', '0x32']

The above examples were the output of the following code
`elif flag != 1 or 2 or 3 or 4 or 5 or 6:
print("Received raw packet:", [hex(x) for x in packet[:]])`

I am attempting to use rfm9x.flags as a way to distinguish up to 6 different streams of sensor data. Since these packets were corrupted in the flag byte, they get printed out at the end.

here are sections of code that are t

while True:
temperature = (bme280.temperature)
temperature=str(temperature)
rfm9x.flags=1
print(rfm9x.flags, temperature)
if not rfm9x.send_with_ack(temperature.encode("utf-8")):
#ack_failed_counter += 1
print(" No Ack T: ", ack_failed_counter)
time.sleep(1)
await asyncio.sleep(interval)

async def get_pressure(interval):
while True:
pressure = (bme280.pressure)
pressure = str(pressure)
rfm9x.flags=2
print(rfm9x.flags, pressure)
#time.sleep(.1)
if not rfm9x.send_with_ack(pressure.encode("utf-8")):
#ack_failed_counter += 1
print(" No Ack T: ", ack_failed_counter)
time.sleep(1)
await asyncio.sleep(interval)

the serial monitor then prints:
1 24.8129
2 997.658

When the receiver gets these packets however, using the following pertinent section of code:
while True:
# Look for a new packet: only accept if addresses to my_node
packet = rfm9x.receive(with_ack=True, with_header=True)
# If no packet was received during the timeout then None is returned.
if packet is not None:
flag=packet[3]
print(flag)
print("received (raw bytes):{0}".format(packet))
if flag==1:
print(flag)
temperature = str(packet[4:], "utf-8")
temperature = (float(temperature)*1.8 + 32)
temperature=round(temperature, 2)
print("temperature = ", temperature, "F")
#print("Received RSSI: {0}".format(rfm9x.last_rssi))
if adafruit.is_active:
aio.send(temperature_feed.key, str(temperature))
else:
print("wifi not ready")
if flag==2:
print(flag)
pressure = str(packet[4:], "utf-8")
print("pressure = ", pressure, "mB")
#print("Received RSSI: {0}".format(rfm9x.last_rssi))
if adafruit.is_active:
aio.send(pressure_feed.key, str(pressure))
else:
print("wifi not ready")

The serial monitor then prints the following:
1
received (raw bytes):bytearray(b'\x02\x01\x02\x0124.8129')
1
temperature = 76.66 F
66
received (raw bytes):bytearray(b'\x02\x01\x03B997.658')

the first packet received is correct in that the four byte header contains the appropriate information, 02= this node, 01 = sending node, x02 is an 'identifier' and the fourth is x01, meaning the flag was set and received as 1.

The second packet was sent with rfm9x.flags = 2 (shown above in the serial output)
but the received flag was printed as '66' and thus missed by the "if rfm9x.flags ==2 test and pases through without sending the data on to AIO. Note that the payload 997.658 is correct.

This is one example. The CRC is enabled, and the 'with header' is enabled. there is no 'no ack' sent back to the sending node. This I assume means that the header was received, correctly? But parsed or decoded incorrectly.

I really need to be able to use the rfm9x.flags in the header to filter and sort the 6 different data streams I am using (only showed 1,2)

I do not know if this is due to using asyncio and really typing up the processor (RPI PICO), or if it may be a hardware issue.

One final thing. The error is not always on the same flagged packets, meaning sometime flag=2 is passed and parsed correctly. However, the failure is not random, the payload with flags = 2 is corrupted much more frequently.

Any help would be appreciated.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start at the send_with_ack and receive(with_ack=True, with_header=True) entry points shown in the report, then inspect how the header flag is transmitted and parsed. Reproduce the differing flag values with and without asyncio and compare CRC/ACK behavior. Done means explaining the recurring flag-byte corruption and preserving all six flag values; no source file or test is named.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
embedded-iot, networking
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.