nRF24 / RF24

OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
https://nrf24.github.io/RF24
GNU General Public License v2.0
2.23k stars 1.02k forks source link

Scanner program not working on RPi 3B+ #713

Closed OldSurferDude closed 3 years ago

OldSurferDude commented 3 years ago

Having issues with ACK not working correctly? Please see common issues.

Describe the bug A clear and concise description of what the bug is.

The scanner example compiles and runs on the RPi fine, but the output is 0 with random rare 1. The scanner program for the arduino runs as expected.

Please include:

  1. Code to reproduce: current library using example in rf24libs/RF24/examples_linux/extra
  2. Expected behaviour: like that of the Arduino code
  3. What device(es) are you using? Please specify make and model. Arduino Nano, RPi 3B+

Additional context Add any other context about the problem here. The process to test is

  1. download libraries 2.in a terminal, move to folder
  2. make
  3. sudo ./scanner

I use scanner to ensure my wiring is correct. When I got a bad result:

I ran GettingStarted on two Nano's with success In a similar fashion to how I tried to run scanner, I ran GettingStarted on the RPi3b+ and one Nano with success.

From this I conclude that there is a problem with scanner.

Scanner is not important other than to confirm that the wiring is correct. An unsophisticated diagnostic program that does this function would be OK, read and write a register?

This is low priority

2bndy5 commented 3 years ago

Scanner is not important other than to confirm that the wiring is correct. An unsophisticated diagnostic program that does this function would be OK, read and write a register?

Actually all examples confirm the wiring is established by using

if (!radio.begin()) {
  Serial.println("radio hardware not responding!");
  while (1) {} // hold in infinite loop
}

Excluding syntax formatting changes 1 year ago, the scanner.cpp file hasn't been updated since this commit (4 years ago). Also, the scanner.ino Arduino example is from the original library by ManiacBug, and it has only been updated a for posterity since (hence it is located in a folder called "old_backups"). I do see a commit that alters the Arduino scanner.ino example to use the newer constant carrier wave functions, but I don't see similar alteration to the linux scanner.cpp example.

The scanner program relies on basic RF hardware test functions testRPD() (which uses a synonymous register offset as testCarrier()), and the newer startConstCarrier() and stopConstCarrier() that was added last year. These test functions are meant to hint at signal quality and certify the radio hardware's emission/reception (ambiguous to what data is carried in the ambient signals).

The scanner example compiles and runs on the RPi fine, but the output is 0 with random rare 1. The scanner program for the arduino runs as expected.

Not really sure what you mean here. Could you post the output from running scanner on Arduino and RPi? Please also include the distance between the nodes running the scanner program (with some relation to proximity of WiFi/Bluetooth devices).

Avamander commented 3 years ago

@2bndy5 I'm not saying you should do it, but maybe a newer Scanner sketch would still be a nice addition amongst the examples? E.g. with optional TFT support like on this video: https://www.youtube.com/watch?v=kapd3wM9hsg

2bndy5 commented 3 years ago

@Avamander If I were to write a new scanner example,

  1. I would require that startConstCarrier() take no arguments because the RF data rate and channel can/should be set independently of startConstCarrier().
  2. Furthermore, Any example that involves other peripheral hardware that isn't a nRF24 module (like a TFT display) should be saved to the "examples/recipes/" folder because such an example requires external libraries/hardware that isn't directly supported by RF24 lib.
    • Unfortunately, I don't own a TFT display to test on ☹️ , rather I would probably just use the Arduino IDE's Serial plotter option (which would output slower than an I2C based TFT display).
    • The github action that runs CI with the Arduino CLI compiler could be told to install an external library as well.
  3. testRpd() (& testCarrier()) only detect signals "louder" than -64 dBm. The video you linked to is doing some averaging and manipulation on falling peaks. This is what makes your request interesting (to me). Furthermore, this data is only reset when entering RX mode (specifically during FALLING transitions of the CE pin when the CONFIG register's PRIM_RX bit is asserted), so add the confusion of manually manipulating the CE pin (considering that ce() is a private function).

Nonetheless, I shy away from no challenge...

OldSurferDude commented 3 years ago

Thanks for looking into this.

here is the out put

RPi3B+

RF24/examples/scanner/ Connecting ... connected.
================ SPI Configuration ================
CSN Pin     = /dev/spidev0.0
CE Pin      = Custom GPIO22
SPI Speedz  = 10 Mhz
================ NRF Configuration ================
STATUS      = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1    = 0xccccccccc3 0xcccccccc3c
RX_ADDR_P2-5    = 0x33 0xce 0x3e 0xe3
TX_ADDR     = 0xcccccc3ecc
RX_PW_P0-6  = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA       = 0x00
EN_RXADDR   = 0x01
RF_CH       = 0x4c
RF_SETUP    = 0x07
CONFIG      = 0x0e
DYNPD/FEATURE   = 0x00 0x00
Data Rate   = 1 MBPS
Model       = nRF24L01+
CRC Length  = 16 bits
PA Power    = PA_MAX
ARC     = 5
000000000000000011111111111111112222222222222222333333333333333344444444444444445555555555555555666666666666666677777777777777
0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcd
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
111111111111111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Arduino Nano

RF24/examples/scanner/
SPI Speedz  = 10 Mhz
STATUS      = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1    = 0xe7e7e7e7e7 0xc2c2c2c2c2
RX_ADDR_P2-5    = 0xc3 0xc4 0xc5 0xc6
TX_ADDR     = 0xe7e7e7e7e7
RX_PW_P0-6  = 0x20 0x20 0x20 0x20 0x20 0x20
EN_AA       = 0x00
EN_RXADDR   = 0x01
RF_CH       = 0x4c
RF_SETUP    = 0x07
CONFIG      = 0x0e
DYNPD/FEATURE   = 0x00 0x00
Data Rate   = 1 MBPS
Model       = nRF24L01+
CRC Length  = 16 bits
PA Power    = PA_MAX
ARC     = 0
000000000000000011111111111111112222222222222222333333333333333344444444444444445555555555555555666666666666666677777777777777
0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCDEF0123456789ABCD
000000000046BCBAC9AACC89300000000000000000000000000000000000000211000000000000000000000000000000000000000000000000000000000000
000000000136ABBAC9CA9B99410000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
000000000886CBDACBADBDB6650000000000000002310000000000000000000101000000000000000000000000000000000000000000000000000000000000
0000000007AAEFFFFEFFEEF9840000000000000000100000000000000000000332000000000000000000000000000000000000000000000000000000000000
000000000389FFFFFFFFFFFCB51000000000000004310000000000000000000000000000000000000000000000000000000000000000000000000000000000
0001110079FFFFFFFFFFFFFFE65000000000000002220000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000DBFFFFFFFFFFFFFFF85000000000000000000000000000000000000543000000000000000000000000000000000000000000000000000000000000
0000000077FEFFFFFFFFFFFFFB9000000000000000000000000000000000000431000000000000000000000000000000000000000000000000000000000000
0000000066BDFFFFFFFFFFFFF98000000000000005520000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000065ADFEFFFFDFFFFFE64000000000000005640000000000000000000000000000000000000000000000000000000000000000000000000000000000
0000000025BBFFFFFFFFFFFED65000000000000006420000001000000000000000000000000000000000000000000000000000000000000000000000000000
2bndy5 commented 3 years ago

@OldSurferDude Are both the RPi and Arduino in the same relative location? The output is strange, but I don't know where to even begin because the code for both examples (Linux and Arduino) is identical (aside from the optional Carrier wave output on the Arduino example). My first guess is the port of delayMicroseconds() to linux, but I doubt that is the culprit.

@Avamander I've been giving it more thought... Instead of a TFT display, we could use a python program (using the cross-platform freindly pyserial lib for input from the MCU) to output a more visually appealing and/or understandable chart/graph data to a window (probably using pygame or the builtin tkinter libs for drawing). Of course this idea would be even harder for people (like me) ssh-ing to RPi and running examples from the terminal.

2bndy5 commented 3 years ago

I think I found the problem

The examples only check the RPD bit (bit 0 of register 9) after exiting RX mode. I got the scanner example working on my RPi4 by checking the RPD bit (with testCarrier()) before calling stopListening(). There seems to be a discrepancy about when this RPD bit is latched, but I don't know why the Arduino example works when checking the RPD bit after calling stopListening()...

According to the plus variant datasheet in section 6.4

Received Power Detector (RPD), located in register 09, bit 0, triggers at received power levels above -64 dBm that are present in the RF channel you receive on. If the received power is less than -64 dBm, RDP = 0. The RPD can be read out at any time while nRF24L01+ is in receive mode. This offers a snapshot of the current received power level in the channel. The RPD status is latched when a valid packet is received which then indicates signal strength from your own transmitter. If no packets are received the RPD is latched at the end of a receive period as a result of host MCU setting CE low or RX time out controlled by Enhanced ShockBurst™. The status of RPD is correct when RX mode is enabled and after a wait time of Tstby2a +Tdelay_AGC= 130us + 40us. The RX gain varies over temperature which means that the RPD threshold also varies over temperature. The RPD threshold value is reduced by - 5dB at T = -40°C and increased by + 5dB at 85°C.

and noted in the description of register 9:

This register is called CD (Carrier Detect) in the nRF24L01. The name is different in nRF24L01+ due to the different input power level threshold for this bit.

According to the non-plus variant datasheet in section 6.1.4

In RX mode a carrier detect signal is avaliable. The carrier detect is a signal that is set high when a RF signal is detected inside the receiving frequency channel. The signal must be FSK modulated for a secure detection. Other signals can also be detected. The Carrier Detect (CD) is set high when an RF signal is detected in RX mode, otherwise CD is low. The internal CD signal is filtered before presented to CD register. The RF signal must be present for at least 128µs before the CD is set high. How to use the CD is described in Appendix E on page 74.

and in Appendix E:

If the PLOS_CNT in the PTX device indicates a high rate of packet losses, the device can be configured to a PRX device for a short time (Tstbt2a + CD-filter delay = 130µs+128µs = 258µs) to check CD. If CD was high (jam situation), the frequency channel should be changed. If CD was low (out of range or jammed by broadband signals like WLAN), it may continue on the same frequency channel, but you must perform other adjustments (a dummy write to the RF_CH clears the PLOS_CNT).

Conclusion

I think the RPD/CD bit behaves differently based on what variant of the nRF24 module is being used. I need a non-plus variant to verify that the CD bit can be checked before exiting RX mode. If this cannot be detirmined, then proper modification of the scanner examples should probably employ the isPVariant() function which no longer does anything but return a private bool member that's set in begin() (a change I made in #691 for quicker function performance).

OldSurferDude commented 3 years ago

@2bndy5 You gave me hope so I tried putting stoplistining() after if (radio.testCarrier()) ++values[i]; with no joy. I changed the delay from 128 to 256 and tested stoplistining() after and before, still no joy.

:(

2bndy5 commented 3 years ago

Damn. Really thought that was it. The same technique worked in my CircuitPython library. Back to square one then...

2bndy5 commented 3 years ago

@OldSurferDude I also noticed that the Linux scanner.cpp example was using a c'tor declaration that only worked with the BCM driver. Could you try

cd RF24
git fetch
git checkout test-scanner
./configure --driver=SPIDEV
make
sudo make install
cd examples_linux/extra
make
./scanner

I changed the output of 0 to - to relieve my eyes.

OldSurferDude commented 3 years ago

@2bndy5 I'm not very experienced with the in's-and-out's of github. When I executed the command: git checkout test-scanner I got the error message: _error: Your local changes to the following files would be overwritten by checkout: exampleslinux/extra/scanner.cpp Please commit your changes or stash them before you switch branches. Aborting

Suggestions? osd

2bndy5 commented 3 years ago

that's ok. what your error is say is you have made changes that have not been stashed/commited to the RF24 repo (this repo). But you won't be able to commit them directly to the master branch (not even I can do that).

option 1 (a little more involved)

git stash save "my changes"

then you can switch branches with

git checkout test-scanner

After switching back to master (or whatever branch you stashed your changes on), you can restore your changes using

git stash pop

option 2 (the easy way out)

git clone the RF24 repo into a new folder

cd ~
git clone https://github.com/nRF24/RF24.git new-RF24
cd new-RF24
git checkout test-scanner

and continue to re-install using the SPIDEV driver with my fixes to the scanner.cpp

./configure --driver=SPIDEV
make
sudo make install
cd examples_linux/extra
make
./scanner

The fact that you were able to run the scanner.cpp on the master branch tells me that your library install of RF24 was configured to use the BCM driver. (you can see the driver options in by running

./configure --help
OldSurferDude commented 3 years ago

@2bndy5

I like the dashes instead of 0's.

Alas, no joy.

Still, the _RF24MeshExample on the Nano with _RF24Mesh_ExampleMaster on the RPi3B+ is working like a champ! (albeit, with some packets being lost, but that's another issue with collisions)

If you're curious, my project is a solar powered temperature/humidity/soil moisture station + monitor hours of usable sun. Projects like this seem to crop up spontaneously when one is retired. ;)

2bndy5 commented 3 years ago

Projects like this seem to crop up spontaneously when one is retired. ;)

😃 I'm such a sucker for puns.

I tried pitching a project like that to my college robotics club, but those millennials were too interested in buzzwords like "AI Robot". They also turned down a robotic bartender (!?); I can't relate to kids anymore.

2bndy5 commented 3 years ago

@TMRh20 can you confirm this is still a problem with your RPi3 (when you get the time of course)? I modified the scanner example for Linux in the test-scanner branch (seemed to be written for the BCM238x driver only).

I'm really just looking for a second opinion because I hit a dead end on my first attempt to resolve this, and I don't own a RPi3(B+).

TMRh20 commented 3 years ago

Scanner works fine on my RPI 3 B.

On Mar 19, 2021, at 5:23 AM, Brendan @.***> wrote:

 @TMRh20 can you confirm this is still a problem with your RPi3 (when you get the time of course)? I modified the scanner example for Linux in the test-scanner branch (seemed to be written for the BCM238x driver only).

I'm really just looking for a second opinion because I hit a dead end on my first attempt to resolve this, and I don't own a RPi3(B+).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

TMRh20 commented 3 years ago

Thinking more about this it could be that the device just isn’t picking up anything. The output of the nano is pretty sparse.

On Mar 19, 2021, at 5:23 AM, Brendan @.***> wrote:

 @TMRh20 can you confirm this is still a problem with your RPi3 (when you get the time of course)? I modified the scanner example for Linux in the test-scanner branch (seemed to be written for the BCM238x driver only).

I'm really just looking for a second opinion because I hit a dead end on my first attempt to resolve this, and I don't own a RPi3(B+).

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

2bndy5 commented 3 years ago

Thanks. I was suspecting that it was something specific to @OldSurferDude setup.

OldSurferDude commented 3 years ago

Unfortunate for the discussion here, but fortunate for me, my project is working very well and I don't dare "fix" it. I did a lot of thrashing that probably left artifacts, both beneficial and malignant.

Part of my project will detail everything that I did to create it. To do that documentation, I'll have to start with a NOOB Pi3B+ and confirm that scanner works on it, I have every confidence that it will.

Then I will have to confirm all of my code works, too, which is a project in and of itself. ;)