RF24
RF24 copied to clipboard
Should the scanner example be more promiscuous?
I have been playing around with the scanner examples lately, and its hard to tell if this makes a difference, but technically, shouldn't the radio be using a configuration like the following?
radio.setAddressWidth(2);
uint8_t addresses[5][2] = {{0x00,0x00},{0x01,0x00},{0x02,0x00},{0x03,0x00},{0x04,0x00}};
radio.openReadingPipe(1,addresses[0]);
radio.openReadingPipe(2,addresses[1]);
radio.openReadingPipe(3,addresses[2]);
radio.openReadingPipe(4,addresses[3]);
radio.openReadingPipe(5,addresses[4]);
Essentially, I think we should configure it to use only 2 bytes for the address and then configure some broad radio addresses like 00 that will pick up anything. I'm not really sure if it makes a big difference, but theoretically it should pick up more signals with the radio configured this way, no?
Agreed. I hadn't considered using all the pipes simultaneously; that should definitely provide a better snapshot.
One hurtle I noticed was making sure the RX FIFO was flushed after the RPD is asserted. If not, the RPD will remain true despite whether or not there was a new signal detected for the latest RX session.
I think the addresses should be something that resembles the preamble. This is why I only thought to use 2 pipes in the pyRF24 scanner example.
One hurtle I noticed was making sure the RX FIFO was flushed after the RPD is asserted. If not, the RPD will remain true despite whether or not there was a new signal detected for the latest RX session.
Did not realize that.
I think the addresses should be something that resembles the preamble
I was thinking more along the lines of random noise, but I really wasn't sure what to use for the addresses. I think that's a pretty good idea.
I got the address idea from the reverse engineering readings posted in #798. You should be able capture the most noise by
- disable the CRC
- disable auto-ACK
- set address width to 2
- use alternating sequence of bits in the pipe addresses
Last time I ran the pyRF24 scanner example to read the ambient noise (for only 3 seconds), it was very efficient (lots of repeated "data" was output).
I've been playing with the Linux C++ scanner example, and I think part of the problem is with using printf()
.
I've switched to using cout << values[i] ? min(values[i], 0xf) : '-' << flush
(in hex) as the while loop traverses the channels, and I'm getting a much more active output...
min(0xf, (values[i] & 0xf))
I don't think this & 0xf
is doing us any favors because it could be returning a 0
.
I also had to hike the delay to 130 us and read the RPD flag before and after calling stopListening()
. I still have no idea why the flag is seemingly sometimes de-asserted on Linux after calling stopListening()
, but the following tactic seems to work better:
radio.startListening()
delayMicroseconds(130);
bool founSignal = radio.testRPD(); // somehow more accurate on Linux
radio.stopListening();
if (foundSignal || radio.testRPD()) {
++values[i];
radio.flush_rx(); // discard packets of noise
}
Nice! It does seem to pick up more signals, more consistently with your modified code. Wish I had more time to play around with this, but it looks like you have it under control.
I ported the python scanner from using rich to curses, and I'm proud to report a much more resposive output.
I've been playing around with the addresses (in the pyrf24 scanner), and I got improved responses from using
radio.open_rx_pipe(0, b"\x55\x55")
radio.open_rx_pipe(1, b"\xAA\xAA")
radio.open_rx_pipe(2, b"\xA0\xAA")
radio.open_rx_pipe(3, b"\x0A\xAA")
radio.open_rx_pipe(4, b"\xA5\xAA")
radio.open_rx_pipe(5, b"\x5A\xAA")
Its just a guessing game because we're really trying to predict the most common first 2 bytes in the ambient noise (based on the limits of the radio's address config), but I figured I'd share.
I started looking at revising the CirPy lib's scanner example, and now I'm getting crazy responsiveness when using available()
in the mix. I thought it was a miscalculation in the code, but I checked with my RF Explorer set to -85 dBm and it isn't that far off. I think part of the promiscuity is due to CirPy's slow execution of time.sleep(0.00013)
, but the results are the same when I don't idle on a channel in RX; it might also be slow enough to allow the radio to orient the RX FIFO with the received noise, thus a more accurate report from available()
... Basic algorithm is
- set config
- no auto-retry/ack
- no CRC
- no Dynamic Payloads (static payloads of 32 bytes)
- set address length to 2 bytes using (may be more subjective than objective):
-
{0, 0xAA}
-
{0, 0x55}
-
{0xAA, 0xAA}
-
{0x55, 0x55}
- optionally add 2 more
-
- set the channel
- flush the RX FIFO (despite the state of it) - should allow enough time for the radio to recenter on the frequency
- enter RX mode
- idle ~130 us
- capture RPD
- exit RX mode
- capture RPD or'd with
available()
- output the signal count
I tried using the same addresses and algorithm in the C++ revised scanner examples here (on the promiscuous-scanner branch), but the results were only slightly better when I added a 1ms delay between stopListening()
and available()
. Results were exactly the same as my CirPy experiment when I idled 1 ms in RX mode (using SPIDEV driver). Snapshot of output (each line represents 16 passes on the spectrum):
000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000011111111111111111111111111
000000000011111111112222222222333333333344444444445555555555666666666677777777778888888888999999999900000000001111111111222222
012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e919957388655568473852b813577654b537a5575728466344f5254689b78b787a6948882a36379563575769646748433466f8a43962555485361579b96557
b8-67856537455484356359483668345a25686835a57794866f555646a987896895656b43645676486876738754363646645d9875445514455736657b47575
e857849543672427452322a367547717a33781577a583768a4e856668455788bcb6787623747767589353357449796635144f6543967381476855452857548
f8277774974563559443668546457575877477453745687578f37784688988779663454887693554644525565537a4339446d9992785663664654763457466
While thtis is more accurate, it may be too promiscuous. We could start offering calculation options (like averaging detected signals with the number of spectrum passes) for better user comprehension.
Hehe, yeah that is pretty busy looking. I was just thinking about these scanner examples and finishing them up. I'm not sure what to do, on this one. Are you in a really noisy environment or is this 'normal' is kind of what I'm wondering. I wonder what would happen if you made a small faraday cage for the radio lol. Would it go quiet? In any case, that is very hard to make sense of, so anything we can do to simplify it I'm up for. We don't want to get too complicated though.
According to my RF explorer, most of the noise doesn't go over -70 dBm, but it shows the same amount of noise. I'll try it tomorrow night (when everyone is asleep) and see if there's less noise.
There are various ways to clean it up for readability. My first idea was to take 5 samples for a channel as it traverses the spectrum and add the averaged result to the array of signal counts.
Another way is to take a number (say 16) of samples and overwrite the array of signal counts, but this might look more sporadic to the user.
I just had a power out. So, I tried the RF explorer set to -90 dBm, and there was significantly less noise. I'm pretty sure the only noise I was picking up (which varied around -90/-95 dBm) was my wifi router (which is on an IPS - battery enabled power strip). I couldn't verify with the scanner example because while examining the RF explorer readout, the power came back on. Instantly, all that noise (lower than -70 dBm) came back.
Imagine the snooping I could do if using the nRF52840 with the ESB protocol...