-
Notifications
You must be signed in to change notification settings - Fork 48
rfm9x corrupted header #74
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
here is the transmit code SPDX-License-Identifier: MIT#modified by Roger Ayotte 11/12/2021 Example to send a packet periodically between addressed nodes with ACKimport time adcV= analogio.AnalogIn(board.VOLTAGE_MONITOR) adcW=analogio.AnalogIn(board.GP26) Create library object using our Bus I2C portfrom adafruit_bme280 import basic as adafruit_bme280 i2c = board.I2C() # uses board.SCL and board.SDAi2c = busio.I2C(scl=board.GP17, sda=board.GP16) i2c1=busio.I2C(scl= board.GP15, sda = board.GP14) set the time interval (seconds) for sending packetsdelay_interval = 600 Define radio parameters.RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your module! Can be a value like 915.0, 433.0, etc.Define pins connected to the chip.set GPIO pins as necessary -- this example is for Raspberry PiCS = digitalio.DigitalInOut(board.GP5) Initialize SPI bus.for Adafruit boards#spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) for PICOspi = busio.SPI(clock=board.GP2, MOSI=board.GP3, MISO=board.GP4) Initialze RFM radiorfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ, baudrate = 1000000) Optionally set an encryption key (16 byte AES key). MUST match bothon the transmitter and receiver (or be set to None to disable/the default).#rfm69.encryption_key = ( b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"#) set delay before sending ACKrfm9x.ack_delay = 0.2 set node addressesrfm9x.node = 3 initialize countercounter = 0 send startup message from my_noderfm9x.flags = 0 initialize flag and timerasync def get_temperature2(interval): async def get_humidity(interval): async def get_pressure(interval): async def get_voltage(interval): async def get_wind(interval): async def main(): asyncio.run(main())> |
here is the receiver code: <# SPDX-FileCopyrightText: 2020 Jerry Needell for Adafruit Industries SPDX-License-Identifier: MITmodified by Roger Ayotte 11/12/2021Example to receive addressed packed with ACK and send a responseimport time Define radio parameters.RADIO_FREQ_MHZ = 915.0 # Frequency of the radio in Mhz. Must match your module! Can be a value like 915.0, 433.0, etc.Define pins connected to the chip.set GPIO pins as necessary - this example is for Raspberry PiCS = digitalio.DigitalInOut(board.CE1) Initialize SPI bus.spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO) Initialze RFM radiorfm9x = adafruit_rfm9x.RFM9x(spi, CS, RESET, RADIO_FREQ_MHZ, baudrate = 500000, crc = True) Optionally set an encryption key (16 byte AES key). MUST match bothon the transmitter and receiver (or be set to None to disable/the default).#rfm69.encryption_key = ( b"\x01\x02\x03\x04\x05\x06\x07\x08\x01\x02\x03\x04\x05\x06\x07\x08"#) set delay before transmitting ACK (seconds)rfm9x.ack_delay = 0.1 set node addressesrfm9x.node = 2 initialize countercounter = 0 from Adafruit_IO import Client, Feed, Data, RequestError Set to your Adafruit IO key.Remember, your key is a secret,so make sure not to publish it when you publish this code!ADAFRUIT_IO_KEY = 'aio_Fzve6425emwZSbMDz9nTeAvjI1dj' Set to your Adafruit IO username.(go to https://accounts.adafruit.com to find your username).ADAFRUIT_IO_USERNAME = 'Rcayot' Create an instance of the REST client.aio = Client(ADAFRUIT_IO_USERNAME, ADAFRUIT_IO_KEY) Set up Adafruit IO Feeds.first test if internet is reachableif adafruit.is_active: Wait to receive packets.print("Waiting for packets...")
|
some output from receiver: |
and a section of output from transmitter, flag and sensor data: 6 0.14 |
I made some changes to the receiver program. Basically, since the errors were not evenly distributed (zero for flag = 1, 6 for flag = 6, and a handful for the other values of flag. I decided that it may be due to timing. since flag = 1, is never corrupted. Anyway, I reduced the number of 'print' statements in the receiver, and so far it has somewhat fewer corrupted header flags. I am not sure why there was no CRC or no ACK error, meaning that perhaps the error checking is on the payload only? Seems like if the receiver was not receiving whatever the transmitter sent, it would flag an error. Roger |
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.
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
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.
The text was updated successfully, but these errors were encountered: