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.

/examples/GettingStarted/GettingStarted.ino
 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.

/examples/AcknowledgementPayloads/AcknowledgementPayloads.ino
 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.

/examples/ManualAcknowledgements/ManualAcknowledgements.ino
 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.

/examples/MulticeiverDemo/MulticeiverDemo.ino
 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.

/examples/StreamingData/StreamingData.ino
 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.

/examples/InterruptConfigure/InterruptConfigure.ino
 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.

/examples/scanner/scanner.ino
 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}