Arduino examples¶
GettingStarted.ino¶
A simple example of sending data from 1 nRF24L01 transceiver to another. This example was written to be used on 2 devices acting as “nodes”. Use the Serial Monitor to change each node’s behavior.
13#include <SPI.h>
14#include "printf.h"
15#include "RF24Revamped.h"
16
17// instantiate an object for the nRF24L01 transceiver
18RF24Revamped radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
19
20// Let these addresses be used for the pair
21uint8_t address[][6] = {"1Node", "2Node"};
22// It is very helpful to think of an address as a path instead of as
23// an identifying device destination
24
25// to use different addresses on a pair of radios, we need a variable to
26// uniquely identify which address this radio will use to transmit
27bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
28
29// Used to control whether this node is sending or receiving
30bool role = false; // true = TX role, false = RX role
31
32// For this example, we'll be using a payload containing
33// a single float number that will be incremented
34// on every successful transmission
35float payload = 0.0;
36
37void setup() {
38
39 Serial.begin(115200);
40 while (!Serial) {
41 // some boards need to wait to ensure access to serial over USB
42 }
43
44 // initialize the transceiver on the SPI bus
45 if (!radio.begin()) {
46 Serial.println(F("radio hardware is not responding!!"));
47 while (1) {} // hold in infinite loop
48 }
49
50 // print example's introductory prompt
51 Serial.println(F("RF24/examples/GettingStarted"));
52
53 // To set the radioNumber via the Serial monitor on startup
54 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
55 while (!Serial.available()) {
56 // wait for user input
57 }
58 char input = Serial.parseInt();
59 radioNumber = input == 1;
60 Serial.print(F("radioNumber = "));
61 Serial.println((int)radioNumber);
62
63 // role variable is hardcoded to RX behavior, inform the user of this
64 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
65
66 // Set the PA Level low to try preventing power supply related problems
67 // because these examples are likely run with nodes in close proximity to
68 // each other.
69 radio.setPaLevel(RF24_PA_LOW); // RF24_PA_MAX is default.
70
71 // save on transmission time by setting the radio to only transmit the
72 // number of bytes we need to transmit a float
73 radio.setPayloadLength(sizeof(payload)); // float datatype occupies 4 bytes
74
75 // set the TX address of the RX node into the TX pipe
76 radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
77
78 // set the RX address of the TX node into a RX pipe
79 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
80
81 // additional setup specific to the node's role
82 if (role) {
83 radio.stopListening(); // put radio in TX mode
84 } else {
85 radio.startListening(); // put radio in RX mode
86 }
87
88 // For debugging info
89 // printf_begin(); // needed only once for printing details
90 // radio.printDetails();
91
92} // setup
93
94void loop() {
95
96 if (role) {
97 // This device is a TX node
98
99 unsigned long start_timer = micros(); // start the timer
100 bool report = radio.send(&payload, sizeof(float)); // transmit & save the report
101 unsigned long end_timer = micros(); // end the timer
102
103 if (report) {
104 Serial.print(F("Transmission successful! ")); // payload was delivered
105 Serial.print(F("Time to transmit = "));
106 Serial.print(end_timer - start_timer); // print the timer result
107 Serial.print(F(" us. Sent: "));
108 Serial.println(payload); // print payload sent
109 payload += 0.01; // increment float payload
110 } else {
111 Serial.println(F("Transmission failed or timed out")); // payload was not delivered
112 }
113
114 // to make this example readable in the serial monitor
115 delay(1000); // slow transmissions down by 1 second
116
117 } else {
118 // This device is a RX node
119
120 if (radio.available()) { // is there a payload?
121 uint8_t pipe = radio.pipe(); // grab the pipe number that received it
122 uint8_t bytes = radio.any(); // get the size of the payload
123 radio.read(&payload, bytes); // fetch payload from FIFO
124 Serial.print(F("Received "));
125 Serial.print(bytes); // print the size of the payload
126 Serial.print(F(" bytes on pipe "));
127 Serial.print(pipe); // print the pipe number
128 Serial.print(F(": "));
129 Serial.println(payload); // print the payload's value
130 }
131 } // role
132
133 if (Serial.available()) {
134 // change the role via the serial monitor
135
136 char c = toupper(Serial.read());
137 if (c == 'T' && !role) {
138 // Become the TX node
139
140 role = true;
141 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
142 radio.stopListening();
143
144 } else if (c == 'R' && role) {
145 // Become the RX node
146
147 role = false;
148 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
149 radio.startListening();
150 }
151 }
152
153} // loop
AcknowledgementPayloads.ino¶
A simple example of sending data from 1 nRF24L01 transceiver to another with Acknowledgement (ACK) payloads attached to ACK packets. This example was written to be used on 2 devices acting as “nodes”. Use the Serial Monitor to change each node’s behavior.
14#include <SPI.h>
15#include "printf.h"
16#include "RF24Revamped.h"
17
18// instantiate an object for the nRF24L01 transceiver
19RF24Revamped radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
20
21// an identifying device destination
22// Let these addresses be used for the pair
23uint8_t address[][6] = {"1Node", "2Node"};
24// It is very helpful to think of an address as a path instead of as
25// an identifying device destination
26// to use different addresses on a pair of radios, we need a variable to
27
28// uniquely identify which address this radio will use to transmit
29bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
30
31// Used to control whether this node is sending or receiving
32bool role = false; // true = TX role, false = RX role
33
34// For this example, we'll be using a payload containing
35// a string & an integer number that will be incremented
36// on every successful transmission.
37// Make a data structure to store the entire payload of different datatypes
38struct PayloadStruct {
39 char message[7]; // only using 6 characters for TX & ACK payloads
40 uint8_t counter;
41};
42PayloadStruct payload;
43
44void setup() {
45
46 Serial.begin(115200);
47 while (!Serial) {
48 // some boards need to wait to ensure access to serial over USB
49 }
50
51 // initialize the transceiver on the SPI bus
52 if (!radio.begin()) {
53 Serial.println(F("radio hardware is not responding!!"));
54 while (1) {} // hold in infinite loop
55 }
56
57 // print example's introductory prompt
58 Serial.println(F("RF24/examples/AcknowledgementPayloads"));
59
60 // To set the radioNumber via the Serial monitor on startup
61 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
62 while (!Serial.available()) {
63 // wait for user input
64 }
65 char input = Serial.parseInt();
66 radioNumber = input == 1;
67 Serial.print(F("radioNumber = "));
68 Serial.println((int)radioNumber);
69
70 // role variable is hardcoded to RX behavior, inform the user of this
71 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
72
73 // Set the PA Level low to try preventing power supply related problems
74 // because these examples are likely run with nodes in close proximity to
75 // each other.
76 radio.setPaLevel(RF24_PA_LOW); // RF24_PA_MAX is default.
77
78 // to use ACK payloads, we need to enable dynamic payload lengths (for all nodes)
79 radio.setDynamicPayloads(true); // ACK payloads are dynamically sized
80
81 // Acknowledgement packets have no payloads by default. We need to enable
82 // this feature for all nodes (TX & RX) to use ACK payloads.
83 radio.enableAckPayload();
84
85 // set the TX address of the RX node into the TX pipe
86 radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
87
88 // set the RX address of the TX node into a RX pipe
89 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
90
91 // additional setup specific to the node's role
92 if (role) {
93 // setup the TX payload
94
95 memcpy(payload.message, "Hello ", 6); // set the payload message
96 radio.stopListening(); // put radio in TX mode
97 } else {
98 // setup the ACK payload & load the first response into the FIFO
99
100 memcpy(payload.message, "World ", 6); // set the payload message
101 // load the payload for the first received transmission on pipe 0
102 radio.writeAck(1, &payload, sizeof(payload));
103
104 radio.startListening(); // put radio in RX mode
105 }
106
107 // For debugging info
108 // printf_begin(); // needed only once for printing details
109 // radio.printDetails();
110
111}
112
113void loop() {
114
115 if (role) {
116 // This device is a TX node
117
118 unsigned long start_timer = micros(); // start the timer
119 bool report = radio.send(&payload, sizeof(payload)); // transmit & save the report
120 unsigned long end_timer = micros(); // end the timer
121
122 if (report) {
123 Serial.print(F("Transmission successful! ")); // payload was delivered
124 Serial.print(F("Time to transmit = "));
125 Serial.print(end_timer - start_timer); // print the timer result
126 Serial.print(F(" us. Sent: "));
127 Serial.print(payload.message); // print the outgoing message
128 Serial.print(payload.counter); // print the outgoing counter
129 if (radio.available()) { // is there an ACK payload?
130 uint8_t pipe = radio.pipe(); // get the pipe number that received it
131 PayloadStruct received;
132 radio.read(&received, sizeof(received)); // get incoming ACK payload
133 Serial.print(F(" Recieved "));
134 Serial.print(radio.any()); // print incoming payload size
135 Serial.print(F(" bytes on pipe "));
136 Serial.print(pipe); // print pipe number that received the ACK
137 Serial.print(F(": "));
138 Serial.print(received.message); // print incoming message
139 Serial.println(received.counter); // print incoming counter
140
141 // save incoming counter & increment for next outgoing
142 payload.counter = received.counter + 1;
143
144 } else {
145 // empty ACK packet received
146 Serial.println(F(" Recieved: an empty ACK packet"));
147 }
148
149
150 } else {
151 Serial.println(F("Transmission failed or timed out")); // payload was not delivered
152 }
153
154 // to make this example readable in the serial monitor
155 delay(1000); // slow transmissions down by 1 second
156
157 } else {
158 // This device is a RX node
159
160 if (radio.available()) { // is there a payload?
161 uint8_t pipe = radio.pipe(); // grab the pipe number that received it
162 uint8_t bytes = radio.any(); // get the size of the payload
163 PayloadStruct received;
164 radio.read(&received, sizeof(received)); // get incoming payload
165 Serial.print(F("Received "));
166 Serial.print(bytes); // print the size of the payload
167 Serial.print(F(" bytes on pipe "));
168 Serial.print(pipe); // print the pipe number
169 Serial.print(F(": "));
170 Serial.print(received.message); // print incoming message
171 Serial.print(received.counter); // print incoming counter
172 Serial.print(F(" Sent: "));
173 Serial.print(payload.message); // print outgoing message
174 Serial.println(payload.counter); // print outgoing counter
175
176 // save incoming counter & increment for next outgoing
177 payload.counter = received.counter + 1;
178 // load the payload for the first received transmission on pipe 0
179 radio.writeAck(1, &payload, sizeof(payload));
180 }
181 } // role
182
183 if (Serial.available()) {
184 // change the role via the serial monitor
185
186 char c = toupper(Serial.read());
187 if (c == 'T' && !role) {
188 // Become the TX node
189
190 role = true;
191 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
192
193 memcpy(payload.message, "Hello ", 6); // change payload message
194 radio.stopListening(); // this also discards any unused ACK payloads
195
196 } else if (c == 'R' && role) {
197 // Become the RX node
198
199 role = false;
200 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
201 memcpy(payload.message, "World ", 6); // change payload message
202
203 // load the payload for the first received transmission on pipe 0
204 radio.writeAck(1, &payload, sizeof(payload));
205 radio.startListening();
206 }
207 }
208} // loop
ManualAcknowledgements.ino¶
This is a simple example of using the RF24 class on a Raspberry Pi to transmit and respond with acknowledgment (ACK) transmissions. Notice that the auto-ack feature is enabled, but this example doesn’t use automatic ACK payloads because automatic ACK payloads’ data will always be outdated by 1 transmission. Instead, this example uses a call and response paradigm. This example was written to be used on 2 devices acting as “nodes”. Use the Serial Monitor to change each node’s behavior.
19#include <SPI.h>
20#include "printf.h"
21#include "RF24Revamped.h"
22
23// instantiate an object for the nRF24L01 transceiver
24RF24Revamped radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
25
26// Let these addresses be used for the pair
27uint8_t address[][6] = {"1Node", "2Node"};
28// It is very helpful to think of an address as a path instead of as
29// an identifying device destination
30
31// to use different addresses on a pair of radios, we need a variable to
32// uniquely identify which address this radio will use to transmit
33bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
34
35// Used to control whether this node is sending or receiving
36bool role = false; // true = TX node, false = RX node
37
38// For this example, we'll be using a payload containing
39// a string & an integer number that will be incremented
40// on every successful transmission.
41// Make a data structure to store the entire payload of different datatypes
42struct PayloadStruct {
43 char message[7]; // only using 6 characters for TX & RX payloads
44 uint8_t counter;
45};
46PayloadStruct payload;
47
48void setup() {
49
50 // append a NULL terminating character for printing as a c-string
51 payload.message[6] = 0;
52
53 Serial.begin(115200);
54 while (!Serial) {
55 // some boards need to wait to ensure access to serial over USB
56 }
57
58 // initialize the transceiver on the SPI bus
59 if (!radio.begin()) {
60 Serial.println(F("radio hardware is not responding!!"));
61 while (1) {} // hold in infinite loop
62 }
63
64 // print example's introductory prompt
65 Serial.println(F("RF24/examples/ManualAcknowledgements"));
66
67 // To set the radioNumber via the Serial monitor on startup
68 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
69 while (!Serial.available()) {
70 // wait for user input
71 }
72 char input = Serial.parseInt();
73 radioNumber = input == 1;
74 Serial.print(F("radioNumber = "));
75 Serial.println((int)radioNumber);
76
77 // role variable is hardcoded to RX behavior, inform the user of this
78 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
79
80 // Set the PA Level low to try preventing power supply related problems
81 // because these examples are likely run with nodes in close proximity to
82 // each other.
83 radio.setPaLevel(RF24_PA_LOW); // RF24_PA_MAX is default.
84
85 // save on transmission time by setting the radio to only transmit the
86 // number of bytes we need to transmit a float
87 radio.setPayloadLength(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes
88
89 // set the TX address of the RX node into the TX pipe
90 radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
91
92 // set the RX address of the TX node into a RX pipe
93 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
94
95 if (role) {
96 // setup the TX node
97
98 memcpy(payload.message, "Hello ", 6); // set the outgoing message
99 radio.stopListening(); // put radio in TX mode
100 } else {
101 // setup the RX node
102
103 memcpy(payload.message, "World ", 6); // set the outgoing message
104 radio.startListening(); // put radio in RX mode
105 }
106
107 // For debugging info
108 // printf_begin(); // needed only once for printing details
109 // radio.printDetails();
110
111} // setup()
112
113void loop() {
114
115 if (role) {
116 // This device is a TX node
117
118 unsigned long start_timer = micros(); // start the timer
119 bool report = radio.send(&payload, sizeof(payload)); // transmit & save the report
120
121 if (report) {
122 // transmission successful; wait for response and print results
123
124 radio.startListening(); // put in RX mode
125 unsigned long start_timeout = millis(); // timer to detect timeout
126 while (!radio.available()) { // wait for response
127 if (millis() - start_timeout > 200) // only wait 200 ms
128 break;
129 }
130 unsigned long end_timer = micros(); // end the timer
131 radio.stopListening(); // put back in TX mode
132
133 // print summary of transactions
134 Serial.print(F("Transmission successful!")); // payload was delivered
135 if (radio.available()) { // is there a payload received
136 uint8_t pipe = radio.pipe(); // grab the pipe number that received it
137 Serial.print(F(" Round-trip delay: "));
138 Serial.print(end_timer - start_timer); // print the timer result
139 Serial.print(F(" us. Sent: "));
140 Serial.print(payload.message); // print the outgoing payload's message
141 Serial.print(payload.counter); // print outgoing payload's counter
142 PayloadStruct received;
143 radio.read(&received, sizeof(received)); // get payload from RX FIFO
144 Serial.print(F(" Received "));
145 Serial.print(radio.any()); // print the size of the payload
146 Serial.print(F(" bytes on pipe "));
147 Serial.print(pipe); // print the pipe number
148 Serial.print(F(": "));
149 Serial.print(received.message); // print the incoming payload's message
150 Serial.println(received.counter); // print the incoming payload's counter
151 payload.counter = received.counter; // save incoming counter for next outgoing counter
152
153 } else {
154 // no response received
155 Serial.println(F(" Recieved no response."));
156 }
157
158 } else {
159 // payload was not delivered
160 Serial.println(F("Transmission failed or timed out"));
161 } // report
162
163 // to make this example readable in the serial monitor
164 delay(1000); // slow transmissions down by 1 second
165
166 } else {
167 // This device is a RX node
168
169 if (radio.available()) { // is there a payload?
170 uint8_t pipe = radio.pipe(); // grab the pipe number that received it
171 PayloadStruct received;
172 radio.read(&received, sizeof(received)); // get incoming payload
173 payload.counter = received.counter + 1; // increment incoming counter for next outgoing response
174
175 // transmit response & save result to `report`
176 radio.stopListening(); // put in TX mode
177 unsigned long start_response = millis();
178 bool report = radio.send(&payload, sizeof(payload)); // send response
179 while (!report && millis() - start_response < 200) {
180 report = radio.resend(); // retry for 200 ms
181 }
182 radio.startListening(); // put back in RX mode
183
184 // print summary of transactions
185 Serial.print(F("Received "));
186 Serial.print(radio.any()); // print the size of the payload
187 Serial.print(F(" bytes on pipe "));
188 Serial.print(pipe); // print the pipe number
189 Serial.print(F(": "));
190 Serial.print(received.message); // print incoming message
191 Serial.print(received.counter); // print incoming counter
192
193 if (report) {
194 Serial.print(F(" Sent: "));
195 Serial.print(payload.message); // print outgoing message
196 Serial.println(payload.counter); // print outgoing counter
197 } else {
198 Serial.println(" Response failed."); // failed to send response
199 }
200 }
201 } // role
202
203 if (Serial.available()) {
204 // change the role via the serial monitor
205
206 char c = toupper(Serial.read());
207 if (c == 'T' && !role) {
208 // Become the TX node
209
210 role = true;
211 memcpy(payload.message, "Hello ", 6); // set the outgoing message
212 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
213 radio.stopListening(); // put in TX mode
214
215 } else if (c == 'R' && role) {
216 // Become the RX node
217
218 role = false;
219 memcpy(payload.message, "World ", 6); // set the response message
220 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
221 radio.startListening(); // put in RX mode
222 }
223 }
224} // loop
MulticeiverDemo.ino¶
A simple example of sending data from as many as 6 nRF24L01 transceivers to 1 receiving transceiver. This technique is trademarked by Nordic Semiconductors as “MultiCeiver”. Use the Serial Monitor to change each node’s behavior.
16#include <SPI.h>
17#include "printf.h"
18#include "RF24Revamped.h"
19
20// instantiate an object for the nRF24L01 transceiver
21RF24Revamped radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
22
23// For this example, we'll be using 6 addresses; 1 for each TX node
24// It is very helpful to think of an address as a path instead of as
25// an identifying device destination
26// Notice that the last byte is the only byte that changes in the last 5
27// addresses. This is a limitation of the nRF24L01 transceiver for pipes 2-5
28// because they use the same first 4 bytes from pipe 1.
29uint64_t address[6] = {0x7878787878LL,
30 0xB3B4B5B6F1LL,
31 0xB3B4B5B6CDLL,
32 0xB3B4B5B6A3LL,
33 0xB3B4B5B60FLL,
34 0xB3B4B5B605LL
35 };
36
37// Because this example allow up to 6 nodes (specified by numbers 0-5) to
38// transmit and only 1 node to receive, we will use a negative value in our
39// role variable to signify this node is a receiver.
40// role variable is used to control whether this node is sending or receiving
41char role = 'R'; // 0-5 = TX node; any negative number = RX node
42
43// For this example, we'll be using a payload containing
44// a node ID number and a single integer number that will be incremented
45// on every successful transmission.
46// Make a data structure to use as a payload.
47struct PayloadStruct
48{
49 unsigned long nodeID;
50 unsigned long payloadID;
51};
52PayloadStruct payload;
53
54// This example uses all 6 pipes to receive while TX nodes only use 2 pipes
55// To make this easier we'll use a function to manage the addresses, and the
56// payload's nodeID
57void setRole(); // declare a prototype; definition is found after the loop()
58
59void setup() {
60
61 Serial.begin(115200);
62 while (!Serial) {
63 // some boards need to wait to ensure access to serial over USB
64 }
65
66 // initialize the transceiver on the SPI bus
67 if (!radio.begin()) {
68 Serial.println(F("radio hardware is not responding!!"));
69 while (1) {} // hold in infinite loop
70 }
71
72 // print example's introductory prompt
73 Serial.println(F("RF24/examples/MulticeiverDemo"));
74 Serial.println(F("*** Enter a number between 0 and 5 (inclusive) to change"));
75 Serial.println(F(" the identifying node number that transmits."));
76
77 // Set the PA Level low to try preventing power supply related problems
78 // because these examples are likely run with nodes in close proximity of
79 // each other.
80 radio.setPaLevel(RF24_PA_LOW); // RF24_PA_MAX is default.
81
82 // save on transmission time by setting the radio to only transmit the
83 // number of bytes we need to transmit a float
84 radio.setPayloadLength(sizeof(payload)); // 2x int datatype occupy 8 bytes
85
86 // Set the pipe addresses accordingly. This function additionally also
87 // calls startListening() or stopListening() and sets the payload's nodeID
88 setRole();
89
90 // For debugging info
91 // printf_begin(); // needed only once for printing details
92 // radio.printDetails();
93
94} // setup()
95
96void loop() {
97
98 if (role <= 53) {
99 // This device is a TX node
100
101 unsigned long start_timer = micros(); // start the timer
102 bool report = radio.send(&payload, sizeof(payload)); // transmit & save the report
103 unsigned long end_timer = micros(); // end the timer
104
105 if (report) {
106 // payload was delivered
107
108 Serial.print(F("Transmission of payloadID "));
109 Serial.print(payload.payloadID); // print payloadID
110 Serial.print(F(" as node "));
111 Serial.print(payload.nodeID); // print nodeID
112 Serial.print(F(" successful!"));
113 Serial.print(F(" Time to transmit: "));
114 Serial.print(end_timer - start_timer); // print the timer result
115 Serial.println(F(" us"));
116 } else {
117 Serial.println(F("Transmission failed or timed out")); // payload was not delivered
118 }
119 payload.payloadID++; // increment payload number
120
121 // to make this example readable in the serial monitor
122 delay(1000); // slow transmissions down by 1 second
123
124 } else if (role == 'R') {
125 // This device is the RX node
126
127 if (radio.available()) { // is there a payload?
128 uint8_t pipe = radio.pipe(); // grab the pipe number that received it
129 uint8_t bytes = radio.any(); // get the size of the payload
130 radio.read(&payload, bytes); // fetch payload from FIFO
131 Serial.print(F("Received "));
132 Serial.print(bytes); // print the size of the payload
133 Serial.print(F(" bytes on pipe "));
134 Serial.print(pipe); // print the pipe number
135 Serial.print(F(" from node "));
136 Serial.print(payload.nodeID); // print the payload's origin
137 Serial.print(F(". PayloadID: "));
138 Serial.println(payload.payloadID); // print the payload's number
139 }
140 } // role
141
142 if (Serial.available()) {
143 // change the role via the serial monitor
144
145 char c = Serial.read();
146 if (toupper(c) == 'R' && role <= 53) {
147 // Become the RX node
148
149 role = 'R';
150 Serial.println(F("*** CHANGING ROLE TO RECEIVER ***"));
151 Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to act as"));
152 Serial.println(F(" a unique node number that transmits to the RX node."));
153 setRole(); // change address on all pipes to TX nodes
154
155 } else if (c >= 48 && c <= 53 && c != role) {
156 // Become a TX node with identifier 'c'
157
158 role = c - 48;
159 Serial.print(F("*** CHANGING ROLE TO NODE "));
160 Serial.print(c);
161 Serial.println(F(" ***"));
162 Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to change"));
163 Serial.println(F(" the identifying node number that transmits."));
164 Serial.println(F("--- PRESS 'R' to act as the RX node."));
165 setRole(); // change address on pipe 0 to the RX node
166 }
167 }
168
169} // loop
170
171void setRole() {
172 if (role == 'R') {
173 // For the RX node
174
175 // Set the addresses for all pipes to TX nodes
176 for (uint8_t i = 0; i < 6; ++i)
177 radio.openReadingPipe(i, address[i]);
178
179 radio.startListening(); // put radio in RX mode
180
181 } else {
182 // For the TX node
183
184 // set the payload's nodeID & reset the payload's identifying number
185 payload.nodeID = role;
186 payload.payloadID = 0;
187
188 // Set the address on pipe 0 to the RX node.
189 radio.stopListening(); // put radio in TX mode
190 radio.openWritingPipe(address[role]);
191
192 // According to the datasheet, the auto-retry features's delay value should
193 // be "skewed" to allow the RX node to receive 1 transmission at a time.
194 // So, use varying delay between retry attempts and 15 (at most) retry attempts
195 radio.setAutoRetry(((role * 3) % 12) + 3, 15); // maximum value is 15 for both args
196 }
197} // setRole
StreamingData.ino¶
This is a simple example of using the RF24 class on a Raspberry Pi for streaming multiple payloads. This example was written to be used on 2 devices acting as “nodes”. Use the Serial Monitor to change each node’s behavior.
13#include <SPI.h>
14#include "printf.h"
15#include "RF24Revamped.h"
16
17// instantiate an object for the nRF24L01 transceiver
18RF24Revamped radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
19
20// Let these addresses be used for the pair
21uint8_t address[][6] = {"1Node", "2Node"};
22// It is very helpful to think of an address as a path instead of as
23// an identifying device destination
24
25// to use different addresses on a pair of radios, we need a variable to
26// uniquely identify which address this radio will use to transmit
27bool radioNumber; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
28
29// Used to control whether this node is sending or receiving
30bool role = false; // true = TX node, false = RX node
31
32// For this example, we'll be sending 32 payloads each containing
33// 32 bytes of data that looks like ASCII art when printed to the serial
34// monitor. The TX node and RX node needs only a single 32 byte buffer.
35#define SIZE 32 // this is the maximum for this example. (minimum is 1)
36char buffer[SIZE + 1]; // for the RX node
37uint8_t counter = 0; // for counting the number of received payloads
38void makePayload(uint8_t); // prototype to construct a payload dynamically
39
40
41void setup() {
42
43 buffer[SIZE] = 0; // add a NULL terminating character (for easy printing)
44
45 Serial.begin(115200);
46 while (!Serial) {
47 // some boards need to wait to ensure access to serial over USB
48 }
49
50 // initialize the transceiver on the SPI bus
51 if (!radio.begin()) {
52 Serial.println(F("radio hardware is not responding!!"));
53 while (1) {} // hold in infinite loop
54 }
55
56 // print example's introductory prompt
57 Serial.println(F("RF24/examples/StreamingData"));
58
59 // To set the radioNumber via the Serial monitor on startup
60 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
61 while (!Serial.available()) {
62 // wait for user input
63 }
64 char input = Serial.parseInt();
65 radioNumber = input == 1;
66 Serial.print(F("radioNumber = "));
67 Serial.println((int)radioNumber);
68
69 // role variable is hardcoded to RX behavior, inform the user of this
70 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
71
72 // Set the PA Level low to try preventing power supply related problems
73 // because these examples are likely run with nodes in close proximity to
74 // each other.
75 radio.setPaLevel(RF24_PA_LOW); // RF24_PA_MAX is default.
76
77 // save on transmission time by setting the radio to only transmit the
78 // number of bytes we need to transmit
79 radio.setPayloadLength(SIZE); // default value is the maximum 32 bytes
80
81 // set the TX address of the RX node into the TX pipe
82 radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
83
84 // set the RX address of the TX node into a RX pipe
85 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
86
87 // additional setup specific to the node's role
88 if (role) {
89 radio.stopListening(); // put radio in TX mode
90 } else {
91 radio.startListening(); // put radio in RX mode
92 }
93
94 // For debugging info
95 // printf_begin(); // needed only once for printing details
96 // radio.printDetails();
97
98} // setup()
99
100
101void loop() {
102
103 if (role) {
104 // This device is a TX node
105
106 radio.flushTx();
107 uint8_t i = 0;
108 makePayload(i); // make the payload
109 uint8_t failures = 0;
110 unsigned long start_timer = micros(); // start the timer
111 while (i < SIZE && failures < 100) {
112 while (!radio.write(&buffer, SIZE, false, true) && i < SIZE) {
113 i++;
114 makePayload(i); // make the payload
115 }
116 radio.ce(true);
117 while (!radio.isFifo(true, true)) {
118 if (radio.irqDf()) {
119 failures++;
120 radio.ce(false);
121 radio.clearStatusFlags();
122 radio.ce(true);
123 if (failures >= 100) {
124 Serial.print(F("Too many failures detected. Aborting at payload "));
125 Serial.println(buffer[0]);
126 break;
127 }
128 }
129 }
130 }
131 radio.ce(false);
132 unsigned long end_timer = micros(); // end the timer
133
134 Serial.print(F("Time to transmit = "));
135 Serial.print(end_timer - start_timer); // print the timer result
136 Serial.print(F(" us with "));
137 Serial.print(failures); // print failures detected
138 Serial.println(F(" failures detected"));
139
140 // to make this example readable in the serial monitor
141 delay(1000); // slow transmissions down by 1 second
142
143 } else {
144 // This device is a RX node
145
146 if (radio.available()) { // is there a payload?
147 radio.read(&buffer, SIZE); // fetch payload from FIFO
148 Serial.print(F("Received: "));
149 Serial.print(buffer); // print the payload's value
150 Serial.print(F(" - "));
151 Serial.println(counter++); // print the received counter
152 }
153 } // role
154
155 if (Serial.available()) {
156 // change the role via the serial monitor
157
158 char c = toupper(Serial.read());
159 if (c == 'T' && !role) {
160 // Become the TX node
161
162 role = true;
163 counter = 0; //reset the RX node's counter
164 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
165 radio.stopListening();
166
167 } else if (c == 'R' && role) {
168 // Become the RX node
169
170 role = false;
171 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
172 radio.startListening();
173 }
174 }
175
176} // loop
177
178
179void makePayload(uint8_t i) {
180 // Make a single payload based on position in stream.
181 // This example employs function to save memory on certain boards.
182
183 // let the first character be an identifying alphanumeric prefix
184 // this lets us see which payload didn't get received
185 buffer[0] = i + (i < 26 ? 65 : 71);
186 for (uint8_t j = 0; j < SIZE - 1; ++j) {
187 char chr = j >= (SIZE - 1) / 2 + abs((SIZE - 1) / 2 - i);
188 chr |= j < (SIZE - 1) / 2 - abs((SIZE - 1) / 2 - i);
189 buffer[j + 1] = chr + 48;
190 }
191}
InterruptConfigure.ino¶
This is a simple example of using the RF24 class on a Raspberry Pi to detecting (and verifying) the IRQ (interrupt) pin on the nRF24L01. This example was written to be used on 2 devices acting as “nodes”. Use the Serial Monitor to change each node’s behavior.
16#include <SPI.h>
17#include "printf.h"
18#include "RF24Revamped.h"
19
20// We will be using the nRF24L01's IRQ pin for this example
21#define IRQ_PIN 2 // this needs to be a digital input capable pin
22volatile bool wait_for_event = false; // used to wait for an IRQ event to trigger
23
24// instantiate an object for the nRF24L01 transceiver
25RF24Revamped radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
26
27// Let these addresses be used for the pair
28uint8_t address[][6] = {"1Node", "2Node"};
29// It is very helpful to think of an address as a path instead of as
30// an identifying device destination
31
32// to use different addresses on a pair of radios, we need a variable to
33// uniquely identify which address this radio will use to transmit
34bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
35
36// Used to control whether this node is sending or receiving
37bool role = false; // true = TX node, false = RX node
38
39// For this example, we'll be using a payload containing
40// a string that changes on every transmission. (successful or not)
41// Make a couple arrays of payloads & an iterator to traverse them
42const uint8_t tx_pl_size = 5;
43const uint8_t ack_pl_size = 4;
44uint8_t pl_iterator = 0;
45// The " + 1" compensates for the c-string's NULL terminating 0
46char tx_payloads[][tx_pl_size + 1] = {"Ping ", "Pong ", "Radio", "1FAIL"};
47char ack_payloads[][ack_pl_size + 1] = {"Yak ", "Back", " ACK"};
48
49void interruptHandler(); // prototype to handle IRQ events
50void printRxFifo(); // prototype to print RX FIFO with 1 buffer
51
52
53void setup() {
54 Serial.begin(115200);
55 while (!Serial) {
56 // some boards need to wait to ensure access to serial over USB
57 }
58
59 // initialize the transceiver on the SPI bus
60 if (!radio.begin()) {
61 Serial.println(F("radio hardware is not responding!!"));
62 while (1) {} // hold in infinite loop
63 }
64
65 // print example's introductory prompt
66 Serial.println(F("RF24/examples/InterruptConfigure"));
67
68 // To set the radioNumber via the Serial monitor on startup
69 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
70 while (!Serial.available()) {
71 // wait for user input
72 }
73 char input = Serial.parseInt();
74 radioNumber = input == 1;
75 Serial.print(F("radioNumber = "));
76 Serial.println((int)radioNumber);
77
78 // role variable is hardcoded to RX behavior, inform the user of this
79 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
80
81 // setup the IRQ_PIN
82 pinMode(IRQ_PIN, INPUT);
83 attachInterrupt(digitalPinToInterrupt(IRQ_PIN), interruptHandler, FALLING);
84 // IMPORTANT: do not call radio.available() before calling
85 // radio.clearStatusFlags() when the interruptHandler() is triggered by the
86 // IRQ pin FALLING event. According to the datasheet, the pipe information
87 // is unreliable during the IRQ pin FALLING transition.
88
89 // Set the PA Level low to try preventing power supply related problems
90 // because these examples are likely run with nodes in close proximity to
91 // each other.
92 radio.setPaLevel(RF24_PA_LOW); // RF24_PA_MAX is default.
93
94 // For this example we use acknowledgment (ACK) payloads to trigger the
95 // IRQ pin when data is received on the TX node.
96 // to use ACK payloads, we need to enable dynamic payload lengths
97 radio.setDynamicPayloads(true); // ACK payloads are dynamically sized
98
99 // Acknowledgement packets have no payloads by default. We need to enable
100 // this feature for all nodes (TX & RX) to use ACK payloads.
101 radio.enableAckPayload();
102 // Fot this example, we use the same address to send data back and forth
103
104 // set the TX address of the RX node into the TX pipe
105 radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
106
107 // set the RX address of the TX node into a RX pipe
108 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
109
110 // additional setup specific to the node's role
111 if (role) {
112 // setup for TX mode
113 radio.stopListening(); // put radio in TX mode
114
115 } else {
116 // setup for RX mode
117
118 // let IRQ pin only trigger on "data ready" event in RX mode
119 radio.interruptConfig(true, false, false); // args = dataReady, dataSent, dataFail
120
121 // Fill the TX FIFO with 3 ACK payloads for the first 3 received
122 // transmissions on pipe 1
123 radio.writeAck(1, &ack_payloads[0], ack_pl_size);
124 radio.writeAck(1, &ack_payloads[1], ack_pl_size);
125 radio.writeAck(1, &ack_payloads[2], ack_pl_size);
126
127 radio.startListening(); // put radio in RX mode
128 }
129
130 // For debugging info
131 // printf_begin(); // needed only once for printing details
132 // radio.printDetails();
133
134}
135
136void loop() {
137 if (role && !wait_for_event) {
138
139 // delay(1); // wait for IRQ pin to fully RISE
140
141 // This device is a TX node. This if block is only triggered when
142 // NOT waiting for an IRQ event to happen
143
144 if (pl_iterator == 0) {
145 // Test the "data ready" event with the IRQ pin
146
147 Serial.println(F("\nConfiguring IRQ pin to ignore the 'data sent' event"));
148 radio.interruptConfig(true, false, true); // args = dataReady, dataSent, dataFail
149 Serial.println(F(" Pinging RX node for 'data ready' event..."));
150
151 } else if (pl_iterator == 1) {
152 // Test the "data sent" event with the IRQ pin
153
154 Serial.println(F("\nConfiguring IRQ pin to ignore the 'data ready' event"));
155 radio.interruptConfig(false, true, true); // args = dataReady, dataSent, dataFail
156 Serial.println(F(" Pinging RX node for 'data sent' event..."));
157
158 } else if (pl_iterator == 2) {
159 // Use this iteration to fill the RX node's FIFO which sets us up for the next test.
160
161 // send() uses virtual interrupt flags that work despite the masking of the IRQ pin
162 radio.interruptConfig(false, false, false);; // disable IRQ masking for this step
163
164 Serial.println(F("\nSending 1 payload to fill RX node's FIFO. IRQ pin is neglected."));
165 // send() will call flushTx() before calling write()
166 if (radio.send(&tx_payloads[pl_iterator], tx_pl_size)) {
167 if (radio.isFifo(false, true)) {
168 Serial.println(F("RX node's FIFO is full; it is not listening any more"));
169 } else {
170 Serial.println("Transmission successful, but the RX node might still be listening.");
171 }
172 } else {
173 Serial.println(F("Transmission failed or timed out. Continuing anyway."));
174 radio.flushTx(); // discard payload(s) that failed to transmit
175 }
176
177 } else if (pl_iterator == 3) {
178 // test the "data fail" event with the IRQ pin
179
180 Serial.println(F("\nConfiguring IRQ pin to reflect all events"));
181 radio.interruptConfig(); // all args default to true
182 Serial.println(F(" Pinging inactive RX node for 'data fail' event..."));
183 }
184
185 if (pl_iterator < 4 && pl_iterator != 2) {
186
187 // IRQ pin is LOW when activated. Otherwise it is always HIGH
188 // Wait until IRQ pin is activated.
189 wait_for_event = true;
190
191 // use the non-blocking call to write a payload and begin transmission
192 // the "false" argument means we are expecting an ACK packet response
193 radio.write(tx_payloads[pl_iterator++], tx_pl_size, false);
194
195 // In this example, the "data fail" event is always configured to
196 // trigger the IRQ pin active. Because the auto-ACK feature is on by
197 // default, we don't need a timeout check to prevent an infinite loop.
198
199 } else if (pl_iterator == 4) {
200 // all IRQ tests are done; flushTx() and print the ACK payloads for fun
201
202 // CE pin is still HIGH which consumes more power. Example is now idling so...
203 radio.stopListening(); // ensure CE pin is LOW
204 // stopListening() also calls flushTx() when ACK payloads are enabled
205
206 printRxFifo();
207 pl_iterator++;
208
209
210 // inform user what to do next
211 Serial.println(F("\n*** PRESS 'T' to restart the transmissions"));
212 Serial.println(F("*** PRESS 'R' to change to Receive role\n"));
213
214
215 } else if (pl_iterator == 2) {
216 pl_iterator++; // proceed from step 3 to last step (stop at step 4 for readability)
217 }
218
219 } else if (!role) {
220 // This device is a RX node
221
222 if (radio.isFifo(false, false)) {
223 // wait until RX FIFO is full then stop listening
224
225 delay(100); // let ACK payload finish transmitting
226 radio.stopListening(); // also discards unused ACK payloads
227 printRxFifo(); // flush the RX FIFO
228
229 // Fill the TX FIFO with 3 ACK payloads for the first 3 received
230 // transmissions on pipe 1.
231 radio.writeAck(1, &ack_payloads[0], ack_pl_size);
232 radio.writeAck(1, &ack_payloads[1], ack_pl_size);
233 radio.writeAck(1, &ack_payloads[2], ack_pl_size);
234
235 delay(100); // let TX node finish its role
236 radio.startListening(); // We're ready to start over. Begin listening.
237 }
238
239 } // role
240
241 if (Serial.available()) {
242 // change the role via the serial monitor
243
244 char c = toupper(Serial.read());
245 if (c == 'T') {
246 // Become the TX node
247 if (!role)
248 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
249 else
250 Serial.println(F("*** RESTARTING IRQ PIN TEST ***"));
251
252 role = true;
253 wait_for_event = false;
254 pl_iterator = 0; // reset the iterator
255 radio.flushTx(); // discard any payloads in the TX FIFO
256
257 // startListening() clears the IRQ masks also. This is required for
258 // continued TX operations when a transmission fails.
259 radio.stopListening(); // this also discards any unused ACK payloads
260
261 } else if (c == 'R' && role) {
262 // Become the RX node
263 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
264
265 role = false;
266
267 radio.interruptConfig(); // the IRQ pin should only trigger on "data ready" event
268
269 // Fill the TX FIFO with 3 ACK payloads for the first 3 received
270 // transmissions on pipe 1
271 radio.flushTx(); // make sure there is room for 3 new ACK payloads
272 radio.writeAck(1, &ack_payloads[0], ack_pl_size);
273 radio.writeAck(1, &ack_payloads[1], ack_pl_size);
274 radio.writeAck(1, &ack_payloads[2], ack_pl_size);
275 radio.startListening();
276 }
277 } // Serial.available()
278} // loop
279
280
281/**
282 * when the IRQ pin goes active LOW, call this fuction print out why
283 */
284void interruptHandler() {
285 // print IRQ status and all masking flags' states
286
287 Serial.println(F("\tIRQ pin is actively LOW")); // show that this function was called
288 delayMicroseconds(250);
289 radio.clearStatusFlags(); // get values for IRQ masks
290 // clearStatusFlags() clears the IRQ masks also. This is required for
291 // continued TX operations when a transmission fails.
292 // clearing the IRQ masks resets the IRQ pin to its inactive state (HIGH)
293
294 Serial.print(F("\tdata_sent: "));
295 Serial.print(radio.irqDs()); // print "data sent" mask state
296 Serial.print(F(", data_fail: "));
297 Serial.print(radio.irqDf()); // print "data fail" mask state
298 Serial.print(F(", data_ready: "));
299 Serial.println(radio.irqDr()); // print "data ready" mask state
300
301 if (radio.irqDf()) // if TX payload failed
302 radio.flushTx(); // clear all payloads from the TX FIFO
303
304 // print if test passed or failed. Unintentional fails mean the RX node was not listening.
305 // pl_iterator has already been incremented by now
306 if (pl_iterator <= 1) {
307 Serial.print(F(" 'Data Ready' event test "));
308 Serial.println(radio.irqDr() ? F("passed") : F("failed"));
309 } else if (pl_iterator == 2) {
310 Serial.print(F(" 'Data Sent' event test "));
311 Serial.println(radio.irqDs() ? F("passed") : F("failed"));
312 } else if (pl_iterator == 4) {
313 Serial.print(F(" 'Data Fail' event test "));
314 Serial.println(radio.irqDf() ? F("passed") : F("failed"));
315 }
316 wait_for_event = false; // ready to continue with loop() operations
317} // interruptHandler
318
319
320/**
321 * Print the entire RX FIFO with one buffer. This will also flush the RX FIFO.
322 * Remember that the payload sizes are declared as tx_pl_size and ack_pl_size.
323 */
324void printRxFifo() {
325 if (radio.available()) { // if there is data in the RX FIFO
326 // to flush the data from the RX FIFO, we'll fetch it all using 1 buffer
327
328 uint8_t pl_size = !role ? tx_pl_size : ack_pl_size;
329 char rx_fifo[pl_size * 3 + 1]; // RX FIFO is full & we know ACK payloads' size
330 if (radio.isFifo(false, true)) {
331 rx_fifo[pl_size * 3] = 0; // add a NULL terminating char to use as a c-string
332 radio.read(&rx_fifo, pl_size * 3); // this clears the RX FIFO (for this example)
333 } else {
334 uint8_t i = 0;
335 while (radio.available()) {
336 radio.read(&rx_fifo + (i * pl_size), pl_size);
337 i++;
338 }
339 rx_fifo[i * pl_size] = 0; // add a NULL terminating char to use as a c-string
340 }
341 Serial.print(F("Complete RX FIFO: "));
342 Serial.println(rx_fifo); // print the entire RX FIFO with 1 buffer
343 }
344}
scanner.ino¶
This example is best used as a diagnostic tool to determine what RF channels have less interference in your vicinity. Use the Serial Monitor to change each node’s behavior.
25#include <SPI.h>
26#include "printf.h"
27#include "RF24Revamped.h"
28
29// instantiate an object for the nRF24L01 transceiver
30RF24Revamped radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
31
32// Channel info
33const uint8_t num_channels = 126;
34uint8_t values[num_channels];
35
36void setup(void)
37{
38 Serial.begin(115200);
39 while (!Serial) {
40 // some boards need to wait to ensure access to serial over USB
41 }
42
43 // initialize the transceiver on the SPI bus
44 if (!radio.begin()) {
45 Serial.println(F("radio hardware is not responding!!"));
46 while (1) {} // hold in infinite loop
47 }
48
49 Serial.println(F("RF24Revamped/examples/scanner/"));
50
51 radio.setAutoAck(false);
52
53 // Get into standby mode
54 radio.startListening();
55 radio.stopListening();
56
57 printf_begin(); // needed for printDetails()
58 radio.printDetails();
59
60 // Print out header, high then low digit
61 int i = 0;
62 while ( i < num_channels )
63 {
64 Serial.print(i >> 4, HEX);
65 ++i;
66 }
67 Serial.println();
68 i = 0;
69 while ( i < num_channels )
70 {
71 Serial.print(i & 0xf, HEX);
72 ++i;
73 }
74 Serial.println();
75}
76
77const int num_reps = 100;
78bool constCarrierMode = 0;
79
80void loop(void)
81{
82 /****************************************/
83 // Send g over Serial to begin CCW output
84 // Configure the channel and power level below
85 if (Serial.available()) {
86 char c = Serial.read();
87 if (c == 'g') {
88 constCarrierMode = 1;
89 radio.stopListening();
90 delay(2);
91 Serial.println("Starting Carrier Out");
92 radio.setChannel(40);
93 radio.setPaLevel(RF24_PA_LOW);
94 radio.startCarrierWave();
95 } else if (c == 'e') {
96 constCarrierMode = 0;
97 radio.stopCarrierWave();
98 Serial.println("Stopping Carrier Out");
99 }
100 }
101 /****************************************/
102
103 if (constCarrierMode == 0) {
104 // Clear measurement values
105 memset(values, 0, sizeof(values));
106
107 // Scan all channels num_reps times
108 int rep_counter = num_reps;
109 while (rep_counter--)
110 {
111 int i = num_channels;
112 while (i--)
113 {
114 // Select this channel
115 radio.setChannel(i);
116
117 // Listen for a little
118 radio.startListening();
119 delayMicroseconds(128);
120 radio.stopListening();
121
122 // Did we get a carrier?
123 if (radio.testRpd()) {
124 ++values[i];
125 }
126 }
127 }
128
129
130 // Print out channel measurements, clamped to a single hex digit
131 int i = 0;
132 while ( i < num_channels )
133 {
134 if (values[i])
135 Serial.print(min(0xf, values[i]), HEX);
136 else
137 Serial.print(F("-"));
138
139 ++i;
140 }
141 Serial.println();
142
143 }//If constCarrierMode == 0
144}