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

Written by 2bndy5 in 2020

A simple example of sending data from 1 nRF24L01 transceiver to another with manually transmitted (non-automatic) Acknowledgement (ACK) payloads. This example still uses ACK packets, but they have no payloads. Instead the acknowledging response is sent with write(). This tactic allows for more updated acknowledgement payload data, where actual ACK payloads' data are outdated by 1 transmission because they have to loaded before receiving a transmission.

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
19#include <SPI.h>
20#include "printf.h"
21#include "RF24.h"
22
23#define CE_PIN 7
24#define CSN_PIN 8
25// instantiate an object for the nRF24L01 transceiver
26RF24 radio(CE_PIN, CSN_PIN);
27
28// Let these addresses be used for the pair
29uint8_t address[][6] = { "1Node", "2Node" };
30// It is very helpful to think of an address as a path instead of as
31// an identifying device destination
32
33// to use different addresses on a pair of radios, we need a variable to
34// uniquely identify which address this radio will use to transmit
35bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
36
37// Used to control whether this node is sending or receiving
38bool role = false; // true = TX node, false = RX node
39
40// For this example, we'll be using a payload containing
41// a string & an integer number that will be incremented
42// on every successful transmission.
43// Make a data structure to store the entire payload of different datatypes
44struct PayloadStruct {
45 char message[7]; // only using 6 characters for TX & RX payloads
46 uint8_t counter;
47};
48PayloadStruct payload;
49
50void setup() {
51
52 // append a NULL terminating character for printing as a c-string
53 payload.message[6] = 0;
54
55 Serial.begin(115200);
56 while (!Serial) {
57 // some boards need to wait to ensure access to serial over USB
58 }
59
60 // initialize the transceiver on the SPI bus
61 if (!radio.begin()) {
62 Serial.println(F("radio hardware is not responding!!"));
63 while (1) {} // hold in infinite loop
64 }
65
66 // print example's introductory prompt
67 Serial.println(F("RF24/examples/ManualAcknowledgements"));
68
69 // To set the radioNumber via the Serial monitor on startup
70 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
71 while (!Serial.available()) {
72 // wait for user input
73 }
74 char input = Serial.parseInt();
75 radioNumber = input == 1;
76 Serial.print(F("radioNumber = "));
77 Serial.println((int)radioNumber);
78
79 // role variable is hardcoded to RX behavior, inform the user of this
80 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
81
82 // Set the PA Level low to try preventing power supply related problems
83 // because these examples are likely run with nodes in close proximity to
84 // each other.
85 radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
86
87 // save on transmission time by setting the radio to only transmit the
88 // number of bytes we need to transmit a float
89 radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes
90
91 // set the TX address of the RX node into the TX pipe
92 radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
93
94 // set the RX address of the TX node into a RX pipe
95 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
96
97 if (role) {
98 // setup the TX node
99
100 memcpy(payload.message, "Hello ", 6); // set the outgoing message
101 radio.stopListening(); // put radio in TX mode
102 } else {
103 // setup the RX node
104
105 memcpy(payload.message, "World ", 6); // set the outgoing message
106 radio.startListening(); // put radio in RX mode
107 }
108
109 // For debugging info
110 // printf_begin(); // needed only once for printing details
111 // radio.printDetails(); // (smaller) function that prints raw register values
112 // radio.printPrettyDetails(); // (larger) function that prints human readable data
113
114} // setup()
115
116void loop() {
117
118 if (role) {
119 // This device is a TX node
120
121 unsigned long start_timer = micros(); // start the timer
122 bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
123
124 if (report) {
125 // transmission successful; wait for response and print results
126
127 radio.startListening(); // put in RX mode
128 unsigned long start_timeout = millis(); // timer to detect timeout
129 while (!radio.available()) { // wait for response
130 if (millis() - start_timeout > 200) // only wait 200 ms
131 break;
132 delayMicroseconds(200); // relax probing of available()
133 }
134 unsigned long end_timer = micros(); // end the timer
135 radio.stopListening(); // put back in TX mode
136
137 // print summary of transactions
138 Serial.print(F("Transmission successful!")); // payload was delivered
139 uint8_t pipe;
140 if (radio.available(&pipe)) { // is there a payload received
141 Serial.print(F(" Round-trip delay: "));
142 Serial.print(end_timer - start_timer); // print the timer result
143 Serial.print(F(" us. Sent: "));
144 Serial.print(payload.message); // print the outgoing payload's message
145 Serial.print(payload.counter); // print outgoing payload's counter
146 PayloadStruct received;
147 radio.read(&received, sizeof(received)); // get payload from RX FIFO
148 Serial.print(F(" Received "));
149 Serial.print(radio.getPayloadSize()); // print the size of the payload
150 Serial.print(F(" bytes on pipe "));
151 Serial.print(pipe); // print the pipe number
152 Serial.print(F(": "));
153 Serial.print(received.message); // print the incoming payload's message
154 Serial.println(received.counter); // print the incoming payload's counter
155 payload.counter = received.counter; // save incoming counter for next outgoing counter
156 } else {
157 Serial.println(F(" Received no response.")); // no response received
158 }
159 } else {
160 Serial.println(F("Transmission failed or timed out")); // payload was not delivered
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 uint8_t pipe;
170 if (radio.available(&pipe)) { // is there a payload? get 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
178 radio.writeFast(&payload, sizeof(payload)); // load response to TX FIFO
179 bool report = radio.txStandBy(150); // keep retrying for 150 ms
180
181 radio.startListening(); // put back in RX mode
182
183 // print summary of transactions
184 Serial.print(F("Received "));
185 Serial.print(radio.getPayloadSize()); // print the size of the payload
186 Serial.print(F(" bytes on pipe "));
187 Serial.print(pipe); // print the pipe number
188 Serial.print(F(": "));
189 Serial.print(received.message); // print incoming message
190 Serial.print(received.counter); // print incoming counter
191
192 if (report) {
193 Serial.print(F(" Sent: "));
194 Serial.print(payload.message); // print outgoing message
195 Serial.println(payload.counter); // print outgoing counter
196 } else {
197 Serial.println(" Response failed."); // failed to send response
198 }
199 }
200 } // role
201
202 if (Serial.available()) {
203 // change the role via the serial monitor
204
205 char c = toupper(Serial.read());
206 if (c == 'T' && !role) {
207 // Become the TX node
208
209 role = true;
210 memcpy(payload.message, "Hello ", 6); // set the outgoing message
211 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
212 radio.stopListening(); // put in TX mode
213
214 } else if (c == 'R' && role) {
215 // Become the RX node
216
217 role = false;
218 memcpy(payload.message, "World ", 6); // set the response message
219 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
220 radio.startListening(); // put in RX mode
221 }
222 }
223} // loop
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.
Definition RF24.h:116
@ RF24_PA_LOW
Definition RF24.h:50
#define delay(millisec)
#define delayMicroseconds(usec)
#define millis()