Skip to content

Implement "reliable datagram" #24

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

Merged
merged 22 commits into from
Apr 14, 2020
Merged

Implement "reliable datagram" #24

merged 22 commits into from
Apr 14, 2020

Conversation

jerryneedell
Copy link
Contributor

@jerryneedell jerryneedell commented Mar 13, 2020

Implemented compatibility with the RadioHead library "Reliable DataGram" mode. see #20.
Received packets ar "ACKed" and Transmitted packets wait for ACK response.

It has been difficult to make this work reliably. Packets will still be missed occasionally but now they will be reported. There are attributes taht can be "tweaked" to help

rfm69.ack_delay -- set a delay before the ACK packet is sent - this is necessary when the receive unit an MCU communication to a Raspberry Pi . The MCU can send it's ACK packet before the Raspberry Pi has resumed "listening". The default setting is "None" but setting it to .1 seconds may be necessary. The Arduino RadioHead library does not allow for this "ack_delay" and it it may be difficult to get this to work, especially with a Raspberry Pi.

rfm69.retries -- set the number of ack retries

All of the existing examples will still execute without change.

There are "breaking changes" fo anyone that had been setting the RadioHead headers directly.
There are now attributes for setting the header parameters and the rx_filter parameter for the receive function has been removed.

There are examples for using this mode in rfm69_node1_ack.py and rfm69_node2_ack.py

other new examples
rfm69_header.py -- receive packets and display the header and packet contents
rfm69_node1.py -- uses adresses without ACK
rfm69_node2.py -- companion to rfm69_node1.py
rfm68_rpi_simpletest.py - no LED and set pins for RaspBerry Pi
rfm69_node1_bonnet.py -- similar to rfm69_node1.py but for use with RPi and bonnet -- uses buttons to sent packets

@jerryneedell jerryneedell requested a review from brentru March 13, 2020 11:52
@jerryneedell jerryneedell changed the title Implemnt "reliable datagram" Implement "reliable datagram" Mar 13, 2020
@brentru brentru requested review from a team and removed request for brentru March 13, 2020 20:47
@jerryneedell
Copy link
Contributor Author

This PR will require updating to accommodate #28. I recommend suspending testing or review until I resolve the conflicts.

@jerryneedell
Copy link
Contributor Author

updated to accommodate #28

@jerryneedell jerryneedell requested review from a team and removed request for a team March 23, 2020 19:03
Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Here are my thoughts. No major concerns. I didn't actually test it.

Copy link
Member

@tannewt tannewt left a comment

Choose a reason for hiding this comment

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

Two comment nits but looks good otherwise. Thanks!

@FoamyGuy
Copy link
Contributor

I am set up to test these now so far I've been able to successfully test rfm69_node1.py and rfm69_node2.py. I did have to change some of the pins used to these in order for it to work for me on Feather M0 RFM69HCW:

# Define pins connected to the chip.
CS = digitalio.DigitalInOut(board.RFM69_CS)
RESET = digitalio.DigitalInOut(board.RFM69_RST)

After that I was able to send/receive the counting messages between a pair of devices. I think these pins probably depend on what devices and setup you are using?

"""Reliable Datagram mode:
Send a packet with data and wait for an ACK response.
The packet header is automatically generated.
If enabled, the packet tranmsiion will be retried on failure
Copy link
Contributor

Choose a reason for hiding this comment

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

@jerryneedell Small typo in this comment transmission

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

import adafruit_rfm69

# set the time interval (seconds) for sending packets
transmit_interval = 5
Copy link
Contributor

Choose a reason for hiding this comment

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

@jerryneedell with rfm69_node1_ack.py and rfm69_node2_ack.py I thought I was noticing a trend of longer streaks where I was getting several (tens) of successes in a row or several of No Acks in row with the opposites sprinkled in occasional but a pretty solid trend of back and forth being more or less likely to succeed.

I started taking a peek at how it's working inside of adafruit_rfm69.py. I am brand new to this hardware and low level radio like this generally so I'm not sure how much to trust about my understanding and the conclusions I drew from them perhaps they may not be plausible.

I got to wondering if the way the various delays inside of the send/retry/receive processes were shaking out was causing my devices to go through periods of being "out of sync" where node2 was not done with all of its waiting and retrying before node 1 was moving on and sending the next packet. I thought maybe increasing this transmit_interval at the application layer might allow some extra time and possibly alleviate it some if this was actually the case.

I increased this timeout to 10 and let them run for a while. In my case it did seem to help out. I do still get a few No Acks in a row from time to time, but overall it seems like my success rate seems to have increased a good bit and I'm no longer noticing stronger trends of success and failure streaks back and forth.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It will definitely be better with fewer transmissions. I was trying to strike a balance for testing. I think you are correct that with 5 seconds between transmissions, it can get caught up in the retries. I'm happy to set this to 10 for the demo.

# destination address - default is broadcast
self.destination = _RH_BROADCAST_ADDRESS
"""The default destination address for packet transmissions. (0-255).
If 255 (0xff) then any receiing node should accept the packet.
Copy link
Contributor

Choose a reason for hiding this comment

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

One more small typo I think in this comment receiving

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done

@jerryneedell
Copy link
Contributor Author

I am set up to test these now so far I've been able to successfully test rfm69_node1.py and rfm69_node2.py. I did have to change some of the pins used to these in order for it to work for me on Feather M0 RFM69HCW:

# Define pins connected to the chip.
CS = digitalio.DigitalInOut(board.RFM69_CS)
RESET = digitalio.DigitalInOut(board.RFM69_RST)

After that I was able to send/receive the counting messages between a pair of devices. I think these pins probably depend on what devices and setup you are using?

yes -- this pins do have to be adjusted for the device being used

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.

Great work Jerry. Thank you for this. I tested all of the examples that I could with two Feather M0 RFM69HCW devices and it was all working as intended.

@jerryneedell
Copy link
Contributor Author

Great work Jerry. Thank you for this. I tested all of the examples that I could with two Feather M0 RFM69HCW devices and it was all working as intended.

Thank you for testing and for your comments.

@jerryneedell
Copy link
Contributor Author

@tannewt when you have a chance, let me know if you would like any additional changes and if you think this is OK to merge.

Copy link
Member

@tannewt tannewt 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 so much @jerryneedell! Thanks to @FoamyGuy for the test too.

@tannewt tannewt merged commit 1d4c764 into adafruit:master Apr 14, 2020
adafruit-adabot added a commit to adafruit/Adafruit_CircuitPython_Bundle that referenced this pull request Apr 15, 2020
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.

3 participants