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

Written by 2bndy5 in 2020

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.

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
14#include <SPI.h>
15#include "printf.h"
16#include "RF24.h"
17
18#define CE_PIN 7
19#define CSN_PIN 8
20// instantiate an object for the nRF24L01 transceiver
21RF24 radio(CE_PIN, CSN_PIN);
22
23// an identifying device destination
24// Let these addresses be used for the pair
25uint8_t address[][6] = { "1Node", "2Node" };
26// It is very helpful to think of an address as a path instead of as
27// an identifying device destination
28// to use different addresses on a pair of radios, we need a variable to
29
30// uniquely identify which address this radio will use to transmit
31bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
32
33// Used to control whether this node is sending or receiving
34bool role = false; // true = TX role, false = RX role
35
36// For this example, we'll be using a payload containing
37// a string & an integer number that will be incremented
38// on every successful transmission.
39// Make a data structure to store the entire payload of different datatypes
40struct PayloadStruct {
41 char message[7]; // only using 6 characters for TX & ACK payloads
42 uint8_t counter;
43};
44PayloadStruct payload;
45
46void setup() {
47
48 Serial.begin(115200);
49 while (!Serial) {
50 // some boards need to wait to ensure access to serial over USB
51 }
52
53 // initialize the transceiver on the SPI bus
54 if (!radio.begin()) {
55 Serial.println(F("radio hardware is not responding!!"));
56 while (1) {} // hold in infinite loop
57 }
58
59 // print example's introductory prompt
60 Serial.println(F("RF24/examples/AcknowledgementPayloads"));
61
62 // To set the radioNumber via the Serial monitor on startup
63 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
64 while (!Serial.available()) {
65 // wait for user input
66 }
67 char input = Serial.parseInt();
68 radioNumber = input == 1;
69 Serial.print(F("radioNumber = "));
70 Serial.println((int)radioNumber);
71
72 // role variable is hardcoded to RX behavior, inform the user of this
73 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
74
75 // Set the PA Level low to try preventing power supply related problems
76 // because these examples are likely run with nodes in close proximity to
77 // each other.
78 radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
79
80 // to use ACK payloads, we need to enable dynamic payload lengths (for all nodes)
81 radio.enableDynamicPayloads(); // ACK payloads are dynamically sized
82
83 // Acknowledgement packets have no payloads by default. We need to enable
84 // this feature for all nodes (TX & RX) to use ACK payloads.
85 radio.enableAckPayload();
86
87 // set the TX address of the RX node into the TX pipe
88 radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
89
90 // set the RX address of the TX node into a RX pipe
91 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
92
93 // additional setup specific to the node's role
94 if (role) {
95 // setup the TX payload
96
97 memcpy(payload.message, "Hello ", 6); // set the payload message
98 radio.stopListening(); // put radio in TX mode
99 } else {
100 // setup the ACK payload & load the first response into the FIFO
101
102 memcpy(payload.message, "World ", 6); // set the payload message
103 // load the payload for the first received transmission on pipe 0
104 radio.writeAckPayload(1, &payload, sizeof(payload));
105
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
115void loop() {
116
117 if (role) {
118 // This device is a TX node
119
120 unsigned long start_timer = micros(); // start the timer
121 bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
122 unsigned long end_timer = micros(); // end the timer
123
124 if (report) {
125 Serial.print(F("Transmission successful! ")); // payload was delivered
126 Serial.print(F("Time to transmit = "));
127 Serial.print(end_timer - start_timer); // print the timer result
128 Serial.print(F(" us. Sent: "));
129 Serial.print(payload.message); // print the outgoing message
130 Serial.print(payload.counter); // print the outgoing counter
131 uint8_t pipe;
132 if (radio.available(&pipe)) { // is there an ACK payload? grab the pipe number that received it
133 PayloadStruct received;
134 radio.read(&received, sizeof(received)); // get incoming ACK payload
135 Serial.print(F(" Received "));
136 Serial.print(radio.getDynamicPayloadSize()); // print incoming payload size
137 Serial.print(F(" bytes on pipe "));
138 Serial.print(pipe); // print pipe number that received the ACK
139 Serial.print(F(": "));
140 Serial.print(received.message); // print incoming message
141 Serial.println(received.counter); // print incoming counter
142
143 // save incoming counter & increment for next outgoing
144 payload.counter = received.counter + 1;
145
146 } else {
147 Serial.println(F(" Received: an empty ACK packet")); // empty ACK packet received
148 }
149
150
151 } else {
152 Serial.println(F("Transmission failed or timed out")); // payload was not delivered
153 }
154
155 // to make this example readable in the serial monitor
156 delay(1000); // slow transmissions down by 1 second
157
158 } else {
159 // This device is a RX node
160
161 uint8_t pipe;
162 if (radio.available(&pipe)) { // is there a payload? get the pipe number that received it
163 uint8_t bytes = radio.getDynamicPayloadSize(); // get the size of the payload
164 PayloadStruct received;
165 radio.read(&received, sizeof(received)); // get incoming payload
166 Serial.print(F("Received "));
167 Serial.print(bytes); // print the size of the payload
168 Serial.print(F(" bytes on pipe "));
169 Serial.print(pipe); // print the pipe number
170 Serial.print(F(": "));
171 Serial.print(received.message); // print incoming message
172 Serial.print(received.counter); // print incoming counter
173 Serial.print(F(" Sent: "));
174 Serial.print(payload.message); // print outgoing message
175 Serial.println(payload.counter); // print outgoing counter
176
177 // save incoming counter & increment for next outgoing
178 payload.counter = received.counter + 1;
179 // load the payload for the first received transmission on pipe 0
180 radio.writeAckPayload(1, &payload, sizeof(payload));
181 }
182 } // role
183
184 if (Serial.available()) {
185 // change the role via the serial monitor
186
187 char c = toupper(Serial.read());
188 if (c == 'T' && !role) {
189 // Become the TX node
190
191 role = true;
192 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
193
194 memcpy(payload.message, "Hello ", 6); // change payload message
195 radio.stopListening(); // this also discards any unused ACK payloads
196
197 } else if (c == 'R' && role) {
198 // Become the RX node
199
200 role = false;
201 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
202 memcpy(payload.message, "World ", 6); // change payload message
203
204 // load the payload for the first received transmission on pipe 0
205 radio.writeAckPayload(1, &payload, sizeof(payload));
206 radio.startListening();
207 }
208 }
209} // loop
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.
Definition RF24.h:116
@ RF24_PA_LOW
Definition RF24.h:50
#define delay(millisec)