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.