-
Notifications
You must be signed in to change notification settings - Fork 26
Implement "Reliable Datagram" #20
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
@jerryneedell I'd love reliable packet delivery for the RFM9x/69 modules (adafruit/Adafruit_CircuitPython_RFM9x#34). I feel this would be a mode which should be enabled by default. |
@jerryneedell reliable datagram in the driver would be awesome. At the moment, I work around this by sending every packet twice and having the server ignore the duplicate if it sees it. I drop about 1 packet in 5000 with this, but it's not elegant. If I can help with testing, I'll be available mid-January with a Raspi and a couple of ItsyBitsy M4s. |
I use the middle way, RH Datagram stack on SAMD21 board on sender side and raspi as a receiver.. It's not the full reliable version included the ACK requirement, but you can set sender functions ex. to wait until the packets is properly sended. My tests: it's a good idea to give the receiver time to handle the packets. In my case, after "RHDatagram.waitPacketSent()" I set a delay of 500ms. Now it works perfect. No bad packets, no ignores. |
Thank you for this example of how you are using it. I have been working on implementing the Reliable Datagram into the CircuitPython Library and I have also found it useful to allow a small delay before sending the ACK especially when the receiver is a Raspberry Pi. -- I have made it configurable. I am still working out some issues but hope to heave a version ready for others to test soon. |
Thanks for sharing that, it's an interesting solution. I use CircuitPython on SAMD21 and SAMD51 boards for sending and Python on the Raspberry Pi 3B as the server. On my Raspi, which receives from multiple stations, I've implemented threading in the Python app that receives data and writes it out to the database. The main thread sleeps until the RFM69 interrupt occurs. Then the interrupt callback function reads the radio data, writes it to a queue and goes back to sleep. A daemon thread sleeps until something is added to the queue, reads the data, processes it, writes it to the database and goes back to sleep. On average, the program cannot handle more than one packet per the time interval it takes to process the data and write it to the database. However, the Raspi can handle a quick burst of packets arriving from multiple stations without dropping any because the queue is a buffer. The callback function can continue to respond to new packets while queued packets are being processed by the other thread. In the future, I will be sending commands from the Raspi to the remote stations, and this is where I'll need the reliable datagrams. |
This is just to update the status of "reliable datagram". I'm still working on this -- trying to find ways to make it respond better. |
maybe it helps - take a look on receive function (if fifo_length < 4 ...). Sometimes I got "bad packets" and the fifo_length was 0. Then the function stop working. |
Thank you for that warning. I think that issue will be resolved by some of the changes I have made, especially https://github.com/jerryneedell/Adafruit_CircuitPython_RFM69/blob/jerryn_ack/adafruit_rfm69.py#L848 |
you are right, that's better. if the fifo length is between 0 and 4 it seems to be the datagram header, but no payload data - a useless data frame. |
See the example for RH Datagram : https://www.airspayce.com/mikem/arduino/RadioHead/rf69_client_8pde-example.html. I tested that and it works well. Sending a packet, you can get ACK with values (maybe commands) without the full reliable version. |
after some new test cycles I saw a surprising fact. My sensor send packets with around 47 byte length. Sometime I got 0 or 10 bytes length. But these are not "bad packets" as I thought. These are packets from other 433 MHz systems in the neighborhood, like remote controls for garage doors. I use the "from" value in the receive function to identify the sender, but that taken place in the program after DIO is triggered and the packet is received. |
Sorry for the delay. It will likely be another 2 weeks before I can get back to working on this. |
I tinkered with this a bit. I have two Feather M0 (SAMD21) RFM69 boards, with Circuitpython. I was just using the Adafruit supplied demo scripts. Neither board could keep up with a full-speed exchange between them. There were a lot of message losses. I tried several ways of tweaking the scripts, but could still not get a good exchange stream between them. I stopped tinkering with these at this point because these would not have any chance of keeping up with RadioHead running on an Arduino. I would try implementing the simplest and less involved protocols in the RadioHead library firs and see where that goes. I just do not think the M0 boards with Circuitpython are fast enough for this kind of thing. The M4 and faster boards should do much better but would require using an RFM69 module. |
Yes, that's my experience too. I use the Feather M0 (SAMD21) RFM69 board as client and Raspberry Pi Zero as server. Both units not really high speed devices. I have some different tasks/function running in parallel on the server side to receive and handle the data. Maybe it sounds curious, but using threading helps a bit on the single core raspberry. |
The "bad packet" issue seems to be a "signal flank" problem. I set bouncetime = 200 for the GPIO event detection, now I have stable packets. |
Thank you for the update. That is good to know. I'll try it here as well. |
question: could we simple take "pybind11" to bind the Reliabllity functions of the c++ RadioHead library into the python code? |
I have my doubts about the "simple" part ;-) |
Hm, if im right, CPython is a subset of python functions/modules written in C. |
Good luck - It'll be interesting to hear how it works. This may be a good approach for the Raspberry Pi. |
I'm a bit confused, sorry. Maybe a dump question.If we use small low-power mcu (ESP-, SAMD-, AVR-based, whatever), we have C/C++ libraries like RadioHead to work with. What is the idea, to convert these existing libraries into python-like language for these mcu? |
That is what I have been working on -- creating python code (for use with CircuitPython on the supported MCUs) that implements the same functionality as in the RadioHead library. |
implemented by #24 |
The Radiohead library has a "Reliable Datagram" mode that uses acknowledgement and retries to insure packet delivery.
Is there interest in implementing that here. I'll be happy to take it on, but wanted to see if there was any concern or interest.
The text was updated successfully, but these errors were encountered: