Optimized high speed nRF24L01+ driver class documentation v1.4.8
TMRh20 2020 - Optimized fork of the nRF24L01+ driver
Loading...
Searching...
No Matches
examples_linux/scanner.cpp

Example to detect interference on the various channels available. This is a good diagnostic tool to check whether you're picking a good channel for your application.

Inspired by cpixip. See http://arduino.cc/forum/index.php/topic,54795.0.html

Use ctrl+C to exit

1/*
2 Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 version 2 as published by the Free Software Foundation.
7
8
9 03/17/2013 : Charles-Henri Hallard (http://hallard.me)
10 Modified to use with Arduipi board http://hallard.me/arduipi
11 Changed to use modified bcm2835 and RF24 library
12 07/12/2022: Modified to be more promiscuous using reverse engineering tactics.
13 */
14
28/*
29 * How to read the output:
30 * - The header is a list of supported channels in decimal written vertically.
31 * - Each column corresponding to the vertical header is a hexadecimal count of
32 * detected signals (max is 15 or 'f').
33 *
34 * The following example
35 * 000
36 * 111
37 * 789
38 * ~~~ <- just a divider between the channel's vertical labels and signal counts
39 * 1-2
40 * can be interpreted as
41 * - 1 signal detected on channel 17
42 * - 0 signals (denoted as '-') detected on channel 18
43 * - 2 signals detected on channel 19
44 *
45 * Each line of signal counts represent 100 passes of the supported spectrum.
46 */
47#include <string> // string, getline()
48#include <iostream> // cout, endl, flush, cin
49#include <RF24/RF24.h>
50
51using namespace std;
52
53/****************** Linux ***********************/
54// Radio CE Pin, CSN Pin, SPI Speed
55// CE Pin uses GPIO number with BCM and SPIDEV drivers, other platforms use their own pin numbering
56// CS Pin addresses the SPI bus number at /dev/spidev<a>.<b>
57// ie: RF24 radio(<ce_pin>, <a>*10+<b>); spidev1.0 is 10, spidev1.1 is 11 etc..
58#define CSN_PIN 0
59#ifdef MRAA
60 #define CE_PIN 15 // GPIO22
61#elif defined(RF24_WIRINGPI)
62 #define CE_PIN 3 // GPIO22
63#else
64 #define CE_PIN 22
65#endif
66// Generic:
67RF24 radio(CE_PIN, CSN_PIN);
68/****************** Linux (BBB,x86,etc) ***********************/
69// See http://nRF24.github.io/RF24/pages.html for more information on usage
70// See https://github.com/eclipse/mraa/ for more information on MRAA
71// See https://www.kernel.org/doc/Documentation/spi/spidev for more information on SPIDEV
72
73// Channel info
74const uint8_t num_channels = 126; // 0-125 are supported
75uint8_t values[num_channels]; // the array to store summary of signal counts per channel
76
77// To detect noise, we'll use the worst addresses possible (a reverse engineering tactic).
78// These addresses are designed to confuse the radio into thinking
79// that the RF signal's preamble is part of the packet/payload.
80const uint8_t noiseAddress[][6] = {{0x55, 0x55}, {0xAA, 0xAA}, {0x0A, 0xAA}, {0xA0, 0xAA}, {0x00, 0xAA}, {0xAB, 0xAA}};
81
82const int num_reps = 100; // number of passes for each scan of the entire spectrum
83
84void printHeader(); // prototype function for printing the channels' header
85
86int main(int argc, char** argv)
87{
88 // print example's name
89 cout << argv[0] << endl;
90
91 // Setup the radio
92 if (!radio.begin()) {
93 cout << "Radio hardware not responding!" << endl;
94 return 1;
95 }
96
97 // print a line that should not be wrapped
98 cout << "\n!!! This example requires a width of at least 126 characters. "
99 << "If this text uses multiple lines, then the output will look bad."
100 << endl;
101
102 // set the data rate
103 cout << "Select your Data Rate. "
104 << "Enter '1' for 1 Mbps, '2' for 2 Mbps, '3' for 250 kbps. "
105 << "Defaults to 1Mbps."
106 << endl;
107 string dataRate = "";
108 getline(cin, dataRate);
109 if (dataRate.length() >= 1 && static_cast<char>(dataRate[0]) == '2') {
110 cout << "Using 2 Mbps." << endl;
111 radio.setDataRate(RF24_2MBPS);
112 }
113 else if (dataRate.length() >= 1 && static_cast<char>(dataRate[0]) == '3') {
114 cout << "Using 250 kbps." << endl;
115 radio.setDataRate(RF24_250KBPS);
116 }
117 else {
118 cout << "Using 1 Mbps." << endl;
119 radio.setDataRate(RF24_1MBPS);
120 }
121
122 // configure the radio
123 radio.setAutoAck(false); // Don't acknowledge arbitrary signals
124 radio.disableCRC(); // Accept any signal we find
125 radio.setAddressWidth(2); // A reverse engineering tactic (not typically recommended)
126 for (uint8_t i = 0; i < 6; ++i) {
127 radio.openReadingPipe(i, noiseAddress[i]);
128 }
129
130 // Get into standby mode
131 radio.startListening();
132 radio.stopListening();
133 radio.flush_rx();
134 // radio.printPrettyDetails();
135 // print the vertical header
136 printHeader();
137
138 // forever loop
139 while (1) {
140 // Clear measurement values
141 memset(values, 0, sizeof(values));
142
143 // Scan all channels num_reps times
144 int rep_counter = num_reps;
145 while (rep_counter--) {
146
147 for (int i = 0; i < num_channels; ++i) {
148
149 // Select this channel
150 radio.setChannel(i);
151
152 // Listen for a little
153 radio.startListening();
155 bool foundSignal = radio.testRPD();
156 radio.stopListening();
157
158 // Did we get a signal?
159 if (foundSignal || radio.testRPD() || radio.available()) {
160 ++values[i];
161 radio.flush_rx(); // discard packets of noise
162 }
163
164 // output the summary/snapshot for this channel
165 if (values[i]) {
166 // Print out channel measurements, clamped to a single hex digit
167 cout << hex << min(0xF, static_cast<int>(values[i])) << flush;
168 }
169 else {
170 cout << '-' << flush;
171 }
172 }
173 cout << '\r' << flush;
174 }
175 cout << endl;
176 }
177
178 return 0;
179}
180
181void printHeader()
182{
183 // print the hundreds digits
184 for (uint8_t i = 0; i < num_channels; ++i)
185 cout << static_cast<int>(i / 100);
186 cout << endl;
187
188 // print the tens digits
189 for (uint8_t i = 0; i < num_channels; ++i)
190 cout << static_cast<int>((i % 100) / 10);
191 cout << endl;
192
193 // print the singles digits
194 for (uint8_t i = 0; i < num_channels; ++i)
195 cout << static_cast<int>(i % 10);
196 cout << endl;
197
198 // print the header's divider
199 for (uint8_t i = 0; i < num_channels; ++i)
200 cout << '~';
201 cout << endl;
202}
203
204// vim:ai:cin:sts=2 sw=2 ft=cpp
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.
Definition RF24.h:116
@ RF24_2MBPS
Definition RF24.h:85
@ RF24_250KBPS
Definition RF24.h:87
@ RF24_1MBPS
Definition RF24.h:83
#define delayMicroseconds(usec)