-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Weird and unstable behavior of python wrapper #101
Comments
Thanks for posting this here. As I mentioned I'm getting similar results, but I've looked at it and am not sure as to the cause. |
yep, I've registered the issue and planning to check that... as soon as I find some time, so be patient please. |
ok, I was successful with reproducing the issue. For me, 1st loop with radio.write succeeds, ack is received, but subsequent loops fail with MAX_RT set (verified by debugging printouts) and write method returns 0. I did not see this behavior in the same code in C, however python wrapper just returns what it gets from RF24's write. I have checked that write takes right params from the wrapper and also wrapper takes the return value correctly. It's either a dynamic memory bug or a timing bug somewhere and such are hard to catch :-( |
not sure if this has something to do with the Python issue, but this is what I got, playing with @kormitigrov 's scenario; this C code
produces segfault in 2nd loop run after receiving 1st packet from Arduino successfully. Backtrace:
still checking, but that seems to be really weird :-( |
Yes, I've also noticed that behavior, when the first ping packet is delivered with ack returned, but subsequent fail. But I haven't tried C code on RPi2. The code I used was for Arduino, it might compile differently for RPi2. For instance, unsigned long mean 4 bytes for Arduino. |
Taking your c++ code, i don't get segfault. If i comment out your second printDetails, I get the first ping delivered with ack and answer received, but then: RF24 HARDWARE ERROR |
Fix over reading a buffer by 1 byte #101
Technically, the last commit comment should say issue with printdetails.. blah blah. since the python issue still seems to be happening. In any case, this was interesting. I found the problem because p_variant was returning a value of 255 after the radio.read() function was called. Taking a closer look at read_payload, it turns out a buffer was being over-read by a single byte, and I guess the memory address was that of p_variant? The printDetails issue on RPi should be fixed in the updates branch, but the python issues are something else it seems. I've replicated the python issue using BCM and SPIDEV on RPi, and no amount of timing seems to do anything useful. I've gotten down to one scenario where a delay after radio.available returning true, and before radio.read, where it prevents a successful write, which makes no sense at all. I notice the wrapper uses the -pthread option when compiling, (not very familiar with python) but if it is dong some stuff with threading, it could have something to do with why the timing is all over the place, but thats just a shot-in-the-dark if you will. From all appearances, the radio is just refusing to respond correctly??? |
Related, should have been caught sooner?: #46 |
additional observations:
now just to identify where it is overwritten... what about write_payload, doesn't this suffer from the same issue as read_payload? |
I think I got it: if listening pipe 0 is not used, then pipe0_reading_address is left uninitialized. In some circumstances (for example in Python wrapper) it's not initialized to zeros and in startListening it's restored to a random value. Initializing pipe0_reading_address in constructor to zeros should solve it, at least for me it seems to solve it. |
So, eh, should I checkout another version to try it out myself? |
Fix is not commited yet. To verify, add this line
re-compile RF24 lib, install, try your scenarios and report back. |
I've changed both constructors i've found in RF24.cpp, right? Well, it seems to solve it, indeed! My python scripts mentioned earlier work beautifully, and including random pieces of code does not seem to break it so far! I've tried both the pinger- and the ponger- sides of the python script - no problem so far. However, your c code you mentioned recently does not seem to work. I've changed back the initialization to my setup (radio = RF24(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ)), and after compiling and running it, i get: printDetails output complete up to PA Power the executable silently end there, with no error reported back to the command line. |
for fixing the C code you need commit mentioned earlier by @TMRh20. Or remove printDetails :-) However I'm not sure whether my C code works fine, it was intended just for debugging. |
You're right! Made that --size modification, it works here as well. Any chance of seeing this committed to master soon? :) |
That's a question to @TMRh20. My opinion is that both fixes should go immediately to master as the bugs may anytime break functionality unexpectably. |
Per #101 (comment) initialize pipe0_reading_address[0] to address "Weird and unstable behavior of python wrapper" identified by @kormitigrov Resolution/Root Cause identified by mz-fuzzy
Updated and merged into master. Really nice troubleshooting in identifying this. Thank you both for the detailed trouble descriptions with code examples, as well as testing etc. etc. Initial results seem to confirm a full resolution. Although I haven't done extensive testing yet, I pushed both fixes to Updates and master branches because they address such show-stopping problems. The merge also includes code for the SPI transaction API introduced in Arduino IDE 1.61 or so. |
Question for @mz-fuzzy - You might have noticed the recent integration with SPIDEV and MRAA for general Linux support. Included with that is the ability to specify pin numbers using a simpler constructor: With the python wrapper, in order to use it once compiled with RF24+SPIDEV I had to comment out all of the BCM2835 stuff, but it worked fine. (compile with So my question is, is there a way to keep the BCM code in while allowing use with SPIDEV and/or MRAA? Else, what are your thoughts on removing the BCM specific code and sticking to the generic Linux constructor for the python wrapper? Else is there a better way to address this? |
What comes to my mind first is to arrange it the same way as in RF24 lib: to use a compilation parameter, and depending on that include BCM2835 or not. Removing it completely is also fine, I guess it's also a way for RF24's future, right? If there is a working generic implementation, why to keep RPi specific approach? |
I've come across a weird feature of python wrapper for the library several times already. It seams to be dependent of non-radio code in completely different parts of the script. I'm unable to find out if it is only my problem or if it persists for anybody else.
Using your code I've made another pair of ping-pong scripts for Arduino Nano and Raspberry Pi 2 exchanging current time with contant-size payload. Both the Arduino and Raspberry can be pingers and pongers and talk to each other, the scripts are compatible protocol-wise (exchanging 4 bytes of arduino's unsigned long).
The scripts I'm attaching work fine for me, for Raspberry being the pinger and Arduino Nano being the ponger. They both send data, receive acks successfully, then reply back with data, and again receive acks well.
But enabling the print 'aaa' line in Raspberry script in my case breaks the normal flow of acks for the scripts, even though the script was never meant to enter that part if it is pinger! I don't see any 'aaa' on the screen, but acks to the writes in pinger-part no longer arraive. If I comment that line again, everything works 100%.
How can this be?
In another part of the code I've at some point found I had to access radio.payloadSize in order for the following 'read' to actually read anything. In the end I had to add that access into loop condition, and even then its only stable 100% if you do not touch the code. Change anything - it might right away become 100% unstable.
I could imagine there might be an explanation for access radio.payloadSize, but that previous breaking print 'aaa' evades me completely.
attachment: pingpong_recv.py
attachment: sketch_rf24pingpong.ino
The text was updated successfully, but these errors were encountered: