Optimized high speed nRF24L01+ driver class documentation v1.4.9
TMRh20 2020 - Optimized fork of the nRF24L01+ driver
Loading...
Searching...
No Matches
examples/scanner/scanner.ino

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

1/*
2 * Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
3 * Updated 2020 TMRh20
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * version 2 as published by the Free Software Foundation.
8 */
9
29/*
30 * How to read the output:
31 * - The header is a list of supported channels in decimal written vertically.
32 * - Each column corresponding to the vertical header is a hexadecimal count of
33 * detected signals (max is 15 or 'f').
34 *
35 * The following example
36 * 000
37 * 111
38 * 789
39 * ~~~ <- just a divider between the channel's vertical labels and signal counts
40 * 1-2
41 * can be interpreted as
42 * - 1 signal detected on channel 17
43 * - 0 signals (denoted as '-') detected on channel 18
44 * - 2 signals detected on channel 19
45 *
46 * Each line of signal counts represent 100 passes of the supported spectrum.
47 */
48
49#include "RF24.h"
50#include "printf.h"
51
52//
53// Hardware configuration
54//
55
56#define CE_PIN 7
57#define CSN_PIN 8
58// instantiate an object for the nRF24L01 transceiver
59RF24 radio(CE_PIN, CSN_PIN);
60
61//
62// Channel info
63//
64
65const uint8_t num_channels = 126; // 0-125 are supported
66uint8_t values[num_channels]; // the array to store summary of signal counts per channel
67
68// To detect noise, we'll use the worst addresses possible (a reverse engineering tactic).
69// These addresses are designed to confuse the radio into thinking
70// that the RF signal's preamble is part of the packet/payload.
71const uint8_t noiseAddress[][2] = { { 0x55, 0x55 }, { 0xAA, 0xAA }, { 0xA0, 0xAA }, { 0xAB, 0xAA }, { 0xAC, 0xAA }, { 0xAD, 0xAA } };
72
73const int num_reps = 100; // number of passes for each scan of the entire spectrum
74bool constCarrierMode = 0; // this flag controls example behavior (scan mode is default)
75
76void printHeader(); // prototype function for printing the channels' header
77
78
79void setup(void) {
80
81 // Print preamble
82 Serial.begin(115200);
83 while (!Serial) {
84 // some boards need this to wait for Serial connection
85 }
86 Serial.println(F("RF24/examples/scanner/"));
87
88 // Setup and configure rf radio
89 if (!radio.begin()) {
90 Serial.println(F("radio hardware not responding!"));
91 while (true) {
92 // hold in an infinite loop
93 }
94 }
95 radio.stopConstCarrier(); // in case MCU was reset while radio was emitting carrier wave
96 radio.setAutoAck(false); // Don't acknowledge arbitrary signals
97 radio.disableCRC(); // Accept any signal we find
98 radio.setAddressWidth(2); // A reverse engineering tactic (not typically recommended)
99 for (uint8_t i = 0; i < 6; ++i) {
100 radio.openReadingPipe(i, noiseAddress[i]);
101 }
102
103 // set the data rate
104 Serial.print(F("Select your Data Rate. "));
105 Serial.print(F("Enter '1' for 1 Mbps, '2' for 2 Mbps, '3' for 250 kbps. "));
106 Serial.println(F("Defaults to 1Mbps."));
107 while (!Serial.available()) {
108 // wait for user input
109 }
110 uint8_t dataRate = Serial.parseInt();
111 if (dataRate == 50) {
112 Serial.println(F("Using 2 Mbps."));
113 radio.setDataRate(RF24_2MBPS);
114 } else if (dataRate == 51) {
115 Serial.println(F("Using 250 kbps."));
116 radio.setDataRate(RF24_250KBPS);
117 } else {
118 Serial.println(F("Using 1 Mbps."));
119 radio.setDataRate(RF24_1MBPS);
120 }
121 Serial.println(F("***Enter a channel number to emit a constant carrier wave."));
122 Serial.println(F("***Enter a negative number to switch back to scanner mode."));
123
124 // Get into standby mode
125 radio.startListening();
126 radio.stopListening();
127 radio.flush_rx();
128
129 // printf_begin();
130 // radio.printPrettyDetails();
131 // delay(1000);
132
133 // Print out vertical header
134 printHeader();
135}
136
137void loop(void) {
138 /****************************************/
139 // Send a number over Serial to begin Constant Carrier Wave output
140 // Configure the power amplitude level below
141 if (Serial.available()) {
142 int8_t c = Serial.parseInt();
143 if (c >= 0) {
144 c = min(125, max(0, c)); // clamp channel to supported range
145 constCarrierMode = 1;
146 radio.stopListening();
147 delay(2);
148 Serial.print("\nStarting Carrier Wave Output on channel ");
149 Serial.println(c);
150 // for non-plus models, startConstCarrier() changes address on pipe 0 and sets address width to 5
151 radio.startConstCarrier(RF24_PA_LOW, c);
152 } else {
153 constCarrierMode = 0;
154 radio.stopConstCarrier();
155 radio.setAddressWidth(2); // reset address width
156 radio.openReadingPipe(0, noiseAddress[0]); // ensure address is looking for noise
157 Serial.println("\nStopping Carrier Wave Output");
158 printHeader();
159 }
160
161 // discard any CR and LF sent
162 while (Serial.peek() != -1) {
163 if (Serial.peek() == '\r' || Serial.peek() == '\n') {
164 Serial.read();
165 } else { // got a charater that isn't a line feed
166 break; // handle it on next loop() iteration
167 }
168 }
169 }
170
171 /****************************************/
172
173 if (constCarrierMode == 0) {
174 // Clear measurement values
175 memset(values, 0, sizeof(values));
176
177 // Scan all channels num_reps times
178 int rep_counter = num_reps;
179 while (rep_counter--) {
180 int i = num_channels;
181 while (i--) {
182 // Select this channel
183 radio.setChannel(i);
184
185 // Listen for a little
186 radio.startListening();
188 bool foundSignal = radio.testRPD();
189 radio.stopListening();
190
191 // Did we get a signal?
192 if (foundSignal || radio.testRPD() || radio.available()) {
193 ++values[i];
194 radio.flush_rx(); // discard packets of noise
195 }
196 }
197 }
198
199 // Print out channel measurements, clamped to a single hex digit
200 for (int i = 0; i < num_channels; ++i) {
201 if (values[i])
202 Serial.print(min(0xf, values[i]), HEX);
203 else
204 Serial.print(F("-"));
205 }
206 Serial.println();
207
208 } // if constCarrierMode == 0
209 else {
210 // show some output to prove that the program isn't bricked
211 Serial.print(F("."));
212 delay(1000); // delay a second to keep output readable
213 }
214} // end loop()
215
216void printHeader() {
217 // Print the hundreds digits
218 for (uint8_t i = 0; i < num_channels; ++i)
219 Serial.print(i / 100);
220 Serial.println();
221
222 // Print the tens digits
223 for (uint8_t i = 0; i < num_channels; ++i)
224 Serial.print((i % 100) / 10);
225 Serial.println();
226
227 // Print the singles digits
228 for (uint8_t i = 0; i < num_channels; ++i)
229 Serial.print(i % 10);
230 Serial.println();
231
232 // Print the header's divider
233 for (uint8_t i = 0; i < num_channels; ++i)
234 Serial.print(F("~"));
235 Serial.println();
236}
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
@ RF24_PA_LOW
Definition RF24.h:50
#define delay(milisec)
#define delayMicroseconds(usec)