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 ctrl+c to quit at any time.
1
2
3
4
5
6
19#include <ctime>
20#include <iostream>
21#include <string>
22#include <time.h>
24
25using namespace std;
26
27
28
29
30
31
32#define CSN_PIN 0
33#ifdef MRAA
34 #define CE_PIN 15
35#elif defined(RF24_WIRINGPI)
36 #define CE_PIN 3
37#else
38 #define CE_PIN 22
39#endif
40
41RF24 radio(CE_PIN, CSN_PIN);
42
43
44
45
46
47
48
49
50
51struct PayloadStruct
52{
53 char message[7];
54 uint8_t counter;
55};
56PayloadStruct payload;
57
58void setRole();
59void master();
60void slave();
61
62
63struct timespec startTimer, endTimer;
64uint32_t getMicros();
65
66int main(int argc, char** argv)
67{
68
69
70 if (!radio.begin()) {
71 cout << "radio hardware is not responding!!" << endl;
72 return 0;
73 }
74
75
76 payload.message[6] = 0;
77
78
79 uint8_t address[2][6] = {"1Node", "2Node"};
80
81
82
83
84
85
86 bool radioNumber = 1;
87
88
89 cout << argv[0] << endl;
90
91
92 cout << "Which radio is this? Enter '0' or '1'. Defaults to '0' ";
93 string input;
94 getline(cin, input);
95 radioNumber = input.length() > 0 && (uint8_t)input[0] == 49;
96
97
98
99
101
102
103
104 radio.setPayloadSize(sizeof(payload));
105
106
107 radio.stopListening(address[radioNumber]);
108
109
110 radio.openReadingPipe(1, address[!radioNumber]);
111
112
113
114
115
116
117 setRole();
118 return 0;
119}
120
125void setRole()
126{
127 string input = "";
128 while (!input.length()) {
129 cout << "*** PRESS 'T' to begin transmitting to the other node\n";
130 cout << "*** PRESS 'R' to begin receiving from the other node\n";
131 cout << "*** PRESS 'Q' to exit" << endl;
132 getline(cin, input);
133 if (input.length() >= 1) {
134 if (input[0] == 'T' || input[0] == 't')
135 master();
136 else if (input[0] == 'R' || input[0] == 'r')
137 slave();
138 else if (input[0] == 'Q' || input[0] == 'q')
139 break;
140 else
141 cout << input[0] << " is an invalid input. Please try again." << endl;
142 }
143 input = "";
144 }
145}
146
150void master()
151{
152
153 memcpy(payload.message, "Hello ", 6);
154 radio.stopListening();
155
156 unsigned int failures = 0;
157 while (failures < 6) {
158 clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer);
159 bool report = radio.write(&payload, sizeof(payload));
160
161 if (report) {
162
163
164 radio.startListening();
165 unsigned long start_timeout =
millis();
166 while (!radio.available()) {
167 if (
millis() - start_timeout > 200)
168 break;
169 }
170 unsigned long elapsedTime = getMicros();
171 radio.stopListening();
172
173
174 uint8_t pipe;
175 cout << "Transmission successful! ";
176 if (radio.available(&pipe)) {
177 uint8_t bytes = radio.getPayloadSize();
178 cout << "Round trip delay = ";
179 cout << elapsedTime;
180 cout << " us. Sent: " << payload.message;
181 cout << (unsigned int)payload.counter;
182 PayloadStruct received;
183 radio.read(&received, sizeof(received));
184 cout << " Received " << (unsigned int)bytes;
185 cout << " on pipe " << (unsigned int)pipe;
186 cout << ": " << received.message;
187 cout << (unsigned int)received.counter;
188 cout << endl;
189 payload.counter = received.counter;
190 }
191 else {
192 cout << "Received no response." << endl;
193 }
194 }
195 else {
196 cout << "Transmission failed or timed out";
197 cout << endl;
198 failures++;
199 }
200
201
203 }
204
205 cout << failures << " failures detected. Leaving TX role." << endl;
206}
207
211void slave()
212{
213 memcpy(payload.message, "World ", 6);
214 radio.startListening();
215
216 time_t startTimer = time(nullptr);
217 while (time(nullptr) - startTimer < 6) {
218 uint8_t pipe;
219 if (radio.available(&pipe)) {
220 uint8_t bytes = radio.getPayloadSize();
221 PayloadStruct received;
222 radio.read(&received, sizeof(received));
223 payload.counter = received.counter + 1;
224
225
226 radio.stopListening();
227 radio.writeFast(&payload, sizeof(payload));
228 bool report = radio.txStandBy(150);
229 radio.startListening();
230
231
232 cout << "Received " << (unsigned int)bytes;
233 cout << " bytes on pipe ";
234 cout << (unsigned int)pipe;
235 cout << ": " << received.message;
236 cout << (unsigned int)received.counter;
237
238 if (report) {
239 cout << " Sent: " << payload.message;
240 cout << (unsigned int)payload.counter;
241 cout << endl;
242 }
243 else {
244 cout << " Response failed to send." << endl;
245 }
246 startTimer = time(nullptr);
247 }
248 }
249
250 cout << "Nothing received in 6 seconds. Leaving RX role." << endl;
251 radio.stopListening();
252}
253
257uint32_t getMicros()
258{
259
260
261
262 clock_gettime(CLOCK_MONOTONIC_RAW, &endTimer);
263 uint32_t seconds = endTimer.tv_sec - startTimer.tv_sec;
264 uint32_t useconds = (endTimer.tv_nsec - startTimer.tv_nsec) / 1000;
265
266 return ((seconds)*1000 + useconds) + 0.5;
267}
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.