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

Written by 2bndy5 in 2020

A simple example of streaming 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.

1/*
2 * See documentation at https://nRF24.github.io/RF24
3 * See License information at root directory of this library
4 * Author: Brendan Doherty 2bndy5
5 */
6
13#include <SPI.h>
14#include "printf.h"
15#include "RF24.h"
16
17#define CE_PIN 7
18#define CSN_PIN 8
19// instantiate an object for the nRF24L01 transceiver
20RF24 radio(CE_PIN, CSN_PIN);
21
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
27// to use different addresses on a pair of radios, we need a variable to
28// uniquely identify which address this radio will use to transmit
29bool radioNumber; // 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 node, false = RX node
33
34// For this example, we'll be sending 32 payloads each containing
35// 32 bytes of data that looks like ASCII art when printed to the serial
36// monitor. The TX node and RX node needs only a single 32 byte buffer.
37#define SIZE 32 // this is the maximum for this example. (minimum is 1)
38char buffer[SIZE + 1]; // for the RX node
39uint8_t counter = 0; // for counting the number of received payloads
40void makePayload(uint8_t); // prototype to construct a payload dynamically
41
42
43void setup() {
44
45 buffer[SIZE] = 0; // add a NULL terminating character (for easy printing)
46
47 Serial.begin(115200);
48 while (!Serial) {
49 // some boards need to wait to ensure access to serial over USB
50 }
51
52 // initialize the transceiver on the SPI bus
53 if (!radio.begin()) {
54 Serial.println(F("radio hardware is not responding!!"));
55 while (1) {} // hold in infinite loop
56 }
57
58 // print example's introductory prompt
59 Serial.println(F("RF24/examples/StreamingData"));
60
61 // To set the radioNumber via the Serial monitor on startup
62 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
63 while (!Serial.available()) {
64 // wait for user input
65 }
66 char input = Serial.parseInt();
67 radioNumber = input == 1;
68 Serial.print(F("radioNumber = "));
69 Serial.println((int)radioNumber);
70
71 // role variable is hardcoded to RX behavior, inform the user of this
72 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
73
74 // Set the PA Level low to try preventing power supply related problems
75 // because these examples are likely run with nodes in close proximity to
76 // each other.
77 radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
78
79 // save on transmission time by setting the radio to only transmit the
80 // number of bytes we need to transmit
81 radio.setPayloadSize(SIZE); // default value is the maximum 32 bytes
82
83 // set the TX address of the RX node for use on the TX pipe (pipe 0)
84 radio.stopListening(address[radioNumber]); // put radio in TX mode
85
86 // set the RX address of the TX node into a RX pipe
87 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
88
89 // additional setup specific to the node's RX role
90 if (!role) {
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(); // (smaller) function that prints raw register values
97 // radio.printPrettyDetails(); // (larger) function that prints human readable data
98
99} // setup()
100
101
102void loop() {
103
104 if (role) {
105 // This device is a TX node
106
107 radio.flush_tx();
108 uint8_t i = 0;
109 uint8_t failures = 0;
110 unsigned long start_timer = micros(); // start the timer
111 while (i < SIZE) {
112 makePayload(i); // make the payload
113 if (!radio.writeFast(&buffer, SIZE)) {
114 uint8_t flags = radio.getStatusFlags();
115 if (flags & RF24_TX_DF) {
116 failures++;
117 // now we need to reset the tx_df flag and the radio's CE pin
118 radio.ce(LOW);
119 radio.clearStatusFlags(RF24_TX_DF);
120 radio.ce(HIGH);
121 }
122 // else the TX FIFO is full; just continue loop.
123 } else {
124 i++;
125 }
126
127 if (failures >= 100) {
128 Serial.print(F("Too many failures detected. Aborting at payload "));
129 Serial.println(buffer[0]);
130 break;
131 }
132 }
133 unsigned long end_timer = micros(); // end the timer
134
135 Serial.print(F("Time to transmit = "));
136 Serial.print(end_timer - start_timer); // print the timer result
137 Serial.print(F(" us with "));
138 Serial.print(failures); // print failures detected
139 Serial.println(F(" failures detected"));
140
141 // to make this example readable in the serial monitor
142 delay(1000); // slow transmissions down by 1 second
143
144 } else {
145 // This device is a RX node
146
147 if (radio.available()) { // is there a payload?
148 radio.read(&buffer, SIZE); // fetch payload from FIFO
149 Serial.print(F("Received: "));
150 Serial.print(buffer); // print the payload's value
151 Serial.print(F(" - "));
152 Serial.println(counter++); // print the received counter
153 }
154 } // role
155
156 if (Serial.available()) {
157 // change the role via the serial monitor
158
159 char c = toupper(Serial.read());
160 if (c == 'T' && !role) {
161 // Become the TX node
162
163 role = true;
164 counter = 0; //reset the RX node's counter
165 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
166 radio.stopListening();
167
168 } else if (c == 'R' && role) {
169 // Become the RX node
170
171 role = false;
172 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
173 radio.startListening();
174 }
175 }
176
177} // loop
178
179
180void makePayload(uint8_t i) {
181 // Make a single payload based on position in stream.
182 // This example employs function to save memory on certain boards.
183
184 // let the first character be an identifying alphanumeric prefix
185 // this lets us see which payload didn't get received
186 buffer[0] = i + (i < 26 ? 65 : 71);
187 for (uint8_t j = 0; j < SIZE - 1; ++j) {
188 char chr = j >= (SIZE - 1) / 2 + abs((SIZE - 1) / 2 - i);
189 chr |= j < (SIZE - 1) / 2 - abs((SIZE - 1) / 2 - i);
190 buffer[j + 1] = chr + 48;
191 }
192}
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.
Definition RF24.h:160
@ RF24_PA_LOW
Definition RF24.h:50
#define delay(millisec)
#define HIGH
#define LOW
@ RF24_TX_DF
Represents an event where TX Data Failed to send.
Definition RF24.h:275