Skip to content
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

Fix configuration for Spreading Factor = 6 #10

Merged
merged 7 commits into from
Feb 20, 2025

Conversation

jerryneedell
Copy link
Collaborator

@jerryneedell jerryneedell commented Jan 28, 2025

FIxes #8
Implemented changed to rfm9x.py to correctly configure SF=6 and facilitate other SF settings

  • select implicit header if SF = 6, explicit header for SF 7->12
  • add property to set payload_length for SF = 6
  • enable low_datarate_optimize if the signal duration is > 16ms per data sheet

low_datarate optimize is updated whenever the Spreading Factor or Signal Bandwidth are changed.

Added two examples for experimenting with setting the Spreading Factor:
rfm_lora_sf_base.py
rfm_lora_sf_node.py

For simplicity, The RadioHead Header is disabled for those examples.
It can be enabled if desired except that SF=6 is not currently compatible with "reliable datagram mode" (ACK). SF = 6 requires that the sender and receiver both know the length of each packet.

I'll continue working on this but it may be worth making these changes available now.. There are many use-cases that do not require SF=6 AND reliable datagram mode.

Tested on Raspberry Pi5 and Raspberry Pi Zero W with RFM9x Bonnets.

@jerryneedell
Copy link
Collaborator Author

This PR has been pending for a few weeks. Are there any concerns with it?

Copy link
Contributor

@FoamyGuy FoamyGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jerryneedell are the two new examples expected to work on microcontrollers too or just RPi?

If they are intended to run on MCU, can you describe their intended behavior briefly?

I can run them on two different feathers with radio featherwings connected and they don't crash, but the one running the base code seems to get "stuck" in a fast loop of receiving the same data over and over.

Even if I stop the node device with ctrl-C after it the base keeps printing it's received output

Received (raw payload): bytearray(b'message from node 0')

Sometimes the repeated message is the startup message, and other times it is the counter message, but I've never seen the counter higher than 0 yet.

print([hex(x) for x in packet])
print(f"RSSI: {rfm.last_rssi}")
# send reading after any packet received
if time.monotonic() - time_now > transmit_interval:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could time_now be called last_transmit_time like it is in the other script?

subtracting time_now from time.monotonic() for comparison threw me for a loop slightly since both kind of describe "now".

@jerryneedell
Copy link
Collaborator Author

Thanks for testing. I'll try them on both MCU and pi again and see if I can replicate.

@jerryneedell
Copy link
Collaborator Author

jerryneedell commented Feb 19, 2025

@jerryneedell are the two new examples expected to work on microcontrollers too or just RPi?

If they are intended to run on MCU, can you describe their intended behavior briefly?

I can run them on two different feathers with radio featherwings connected and they don't crash, but the one running the base code seems to get "stuck" in a fast loop of receiving the same data over and over.

Even if I stop the node device with ctrl-C after it the base keeps printing it's received output

Received (raw payload): bytearray(b'message from node 0')

Sometimes the repeated message is the startup message, and other times it is the counter message, but I've never seen the counter higher than 0 yet.

hmm -- I have the "base" running on metro_m4 with an rfm9x featherwing attached and it does to loop as you rescript.
Are you running the code as written -- except for the pin names? Any changes?

1j19
Done | 9.2.4soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py | 9.2.4spreading factor set to : 7
low_datarate_optimize set to:  0
signal_bandwidth set to : 125000
low_datarate_optimize set to:  0
xmit_timeout set to:  2.0
receive_timeout set to:  0.5
Waiting for packets...
Received (raw payload): bytearray(b'startup message from node')
['0x73', '0x74', '0x61', '0x72', '0x74', '0x75', '0x70', '0x20', '0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65']
RSSI: -57.0
Received (raw payload): bytearray(b'message from node 0')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x30']
RSSI: -57.0
Received (raw payload): bytearray(b'message from node 1')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x31']
RSSI: -57.0
Received (raw payload): bytearray(b'message from node 2')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x32']
RSSI: -57.0

@jerryneedell
Copy link
Collaborator Author

jerryneedell commented Feb 19, 2025

I am having a problem though. The node is not receiving back the packets as expected. Looking into it.

The node should send a packet every 10 seconds and the base should echo that packet back after 5 seconds.

I'm not seeing the echoed packet.

OK -- I found that issue. I'll fix it and explain -- The sample code is very simplistic -- maybe too simple....

In any case, I cannot reproduce your problem --
What MCU are you using?

@jerryneedell
Copy link
Collaborator Author

I made a few minor changes
the base listens for packets from the node and union receipt of a packet it will echo the packet back after a .5 second delay.
the node transmits a packet every 10 seconds and listens for any incoming packets.
It is easy for the node to miss incoming packets since there is a small time window between each call to rfm.receive()
This is not meant to be a robust test.

mainly the node should send and the base should receive.

I've been running the base on am MCU and the node on a PI. I'll dig out another MCU to run the node as well.
I still have not reproduced your issue.

@FoamyGuy
Copy link
Contributor

I tried with a few different combinations of a PyGamer + Featherwing as one device and a Feather RP2040 / Feather S3 + featherwing as the other device. I'm not certain which was base and which was node in all cases, but I tried a few different combinations of devices with the different scripts.

They were unmodified except for the pins changed.

I'll pull the latest version and try some other permutations of devices today or tomorrow.

@jerryneedell
Copy link
Collaborator Author

jerryneedell commented Feb 19, 2025

I made one more tweak to the "base" program and added a note about setting the transmit delay. You want to avoid multiples of the node receive_timeout (typically .5 seconds) or you can get into a situation where the node is between receive calls when the packets arrive and it misses them

I now have both the node and base on MCUs = node on a feather_rp2040_rfm9x and the base on the metro M4.

@jerryneedell
Copy link
Collaborator Author

from base

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py | 9.2.4spreading factor set to : 7
low_datarate_optimize set to:  0
signal_bandwidth set to : 125000
low_datarate_optimize set to:  0
xmit_timeout set to:  2.0
receive_timeout set to:  0.5
Waiting for packets...
Received (raw payload): bytearray(b'message from node 0')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x30']
RSSI: -48.0
Received (raw payload): bytearray(b'message from node 1')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x31']
RSSI: -48.0
Received (raw payload): bytearray(b'message from node 2')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x32']
RSSI: -48.0
Received (raw payload): bytearray(b'message from node 3')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x33']
RSSI: -48.0
Received (raw payload): bytearray(b'message from node 4')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x34']

from node:


REPL | 9.2.4y to enter the REPL. Use CTRL-D to reload.
Adafruit CircuitPython 9.2.4 on 2025-01-28; Adafruit Feather RP2040 RFM with rp2040
Done | 9.2.4soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
code.py | 9.2.4spreading factor set to : 7
low_datarate_optimize set to:  0
signal_bandwidth set to : 125000
low_datarate_optimize set to:  0
xmit_timeout set to:  2.0
receive_timeout set to:  0.5
Waiting for packets...
Received (raw payload): bytearray(b'startup message from base')
['0x73', '0x74', '0x61', '0x72', '0x74', '0x75', '0x70', '0x20', '0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x62', '0x61', '0x73', '0x65']
RSSI: -57.0
Received (raw payload): bytearray(b'message from node 0')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x30']
RSSI: -56.0
Received (raw payload): bytearray(b'message from node 1')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x31']
RSSI: -57.0
Received (raw payload): bytearray(b'message from node 2')
['0x6d', '0x65', '0x73', '0x73', '0x61', '0x67', '0x65', '0x20', '0x66', '0x72', '0x6f', '0x6d', '0x20', '0x6e', '0x6f', '0x64', '0x65', '0x20', '0x32']
RSSI: -57.0

@jerryneedell
Copy link
Collaborator Author

I really need to work on a guide for this library...

Copy link
Contributor

@FoamyGuy FoamyGuy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me. Thank you @jerryneedell

I was able to test successfully with a Feather M4 + Featherwing as base and RP2040 + Featherwing as node.

It seems that the issue I described before about getting stuck repeatedly receiving the same message over and over in a very fast loop is tied to the PyGamer. I went back and tested PyGamer as node and Feather M4 as base, and I see that stuck repeating issue on the pygamer. My only hunch about it was maybe the display sharing the SPI bus caused weirdness, but I tried displayio.release_displays() and then re-running the base and node scripts, and I still see the same behavior with repeated receive messages. Maybe the display could still be impacting it somehow, or there is some other difference in this hardware that is causing it.

@FoamyGuy FoamyGuy merged commit 8f0b80e into adafruit:main Feb 20, 2025
1 check passed
@jerryneedell
Copy link
Collaborator Author

Looks good to me. Thank you @jerryneedell

I was able to test successfully with a Feather M4 + Featherwing as base and RP2040 + Featherwing as node.

It seems that the issue I described before about getting stuck repeatedly receiving the same message over and over in a very fast loop is tied to the PyGamer. I went back and tested PyGamer as node and Feather M4 as base, and I see that stuck repeating issue on the pygamer. My only hunch about it was maybe the display sharing the SPI bus caused weirdness, but I tried displayio.release_displays() and then re-running the base and node scripts, and I still see the same behavior with repeated receive messages. Maybe the display could still be impacting it somehow, or there is some other difference in this hardware that is causing it.

Strange -- I'll dig out my pygamer and see if I can reproduce it.... Thanks for approving.

@jerryneedell jerryneedell deleted the jerryn_spreadf branch February 20, 2025 15:15
adafruit-adabot added a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Feb 21, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

problems with non-default spreading factor for rfm9x.
3 participants