A simple example of sending data from as many as 6 nRF24L01 transceivers to 1 receiving transceiver. This technique is trademarked by Nordic Semiconductors as "MultiCeiver".
This example was written to be used on up to 6 devices acting as TX nodes & only 1 device acting as the RX node (that's a maximum of 7 devices). Use ctrl+c
to quit at any time.
1
2
3
4
5
6
16#include <ctime>
17#include <cstring>
18#include <iostream>
19#include <string>
20#include <time.h>
22
23using namespace std;
24
25
26
27
28
29
30#define CSN_PIN 0
31#ifdef MRAA
32 #define CE_PIN 15
33#elif defined(RF24_WIRINGPI)
34 #define CE_PIN 3
35#else
36 #define CE_PIN 22
37#endif
38
39RF24 radio(CE_PIN, CSN_PIN);
40
41
42
43
44
45
46
47
48
49
50
51uint8_t address[6][5] = {{0x78, 0x78, 0x78, 0x78, 0x78},
52 {0xF1, 0xB6, 0xB5, 0xB4, 0xB3},
53 {0xCD, 0xB6, 0xB5, 0xB4, 0xB3},
54 {0xA3, 0xB6, 0xB5, 0xB4, 0xB3},
55 {0x0F, 0xB6, 0xB5, 0xB4, 0xB3},
56 {0x05, 0xB6, 0xB5, 0xB4, 0xB3}};
57
58
59
60
61
62struct PayloadStruct
63{
64 unsigned int nodeID;
65 unsigned int payloadID;
66};
67PayloadStruct payload;
68
69void setRole();
70void master(unsigned int);
71void slave();
72void printHelp(string);
73
74
75struct timespec startTimer, endTimer;
76uint32_t getMicros();
77
78int main(int argc, char** argv)
79{
80
81
82 if (!radio.begin()) {
83 cout << "radio hardware is not responding!!" << endl;
84 return 0;
85 }
86
87
88
89 unsigned int nodeNumber = 'R';
90
91 bool foundArgNode = false;
92 if (argc > 1) {
93 if ((argc - 1) != 2) {
94
95
96 printHelp(string(argv[0]));
97 return 0;
98 }
99 else if (strcmp(argv[1], "-n") == 0 || strcmp(argv[1], "--node") == 0) {
100
101 foundArgNode = true;
102 if ((argv[2][0] - 48) < 6 && (argv[2][0] - 48) >= 0) {
103 nodeNumber = argv[2][0] - 48;
104 }
105 else if (argv[2][0] == 'R' || argv[2][0] == 'r') {
106 nodeNumber = 'R';
107 }
108 else {
109 printHelp(string(argv[0]));
110 return 0;
111 }
112 }
113 else {
114
115 printHelp(string(argv[0]));
116 return 0;
117 }
118 }
119
120
121 cout << argv[0] << endl;
122
123
124
125
127
128
129
130 radio.setPayloadSize(sizeof(payload));
131
132
133
134
135
136
137 if (!foundArgNode) {
138 setRole();
139 }
140 else {
141 nodeNumber < 6 ? master(nodeNumber) : slave();
142 }
143 return 0;
144}
145
150void setRole()
151{
152
153 string input = "";
154 while (!input.length()) {
155 cout << "*** Enter a number between 0 and 5 (inclusive) to act as\n";
156 cout << " a unique node number that transmits to the RX node.\n";
157 cout << "*** PRESS 'R' to begin receiving from the other nodes\n";
158 cout << "*** PRESS 'Q' to exit" << endl;
159 getline(cin, input);
160 if (input.length() >= 1) {
161 unsigned int toNumber = (unsigned int)(input[0]) - 48;
162 if (toNumber < 6 && toNumber >= 0)
163 master(toNumber);
164 else if (input[0] == 'R' || input[0] == 'r')
165 slave();
166 else if (input[0] == 'Q' || input[0] == 'q')
167 break;
168 else
169 cout << input[0] << " is an invalid input. Please try again." << endl;
170 }
171 input = "";
172 }
173}
174
178void master(unsigned int role)
179{
180
181 payload.nodeID = role;
182 payload.payloadID = 0;
183
184
185 radio.stopListening(address[role]);
186
187
188
189
190 radio.setRetries(((role * 3) % 12) + 3, 15);
191
192 unsigned int failures = 0;
193 while (failures < 6) {
194 clock_gettime(CLOCK_MONOTONIC_RAW, &startTimer);
195 bool report = radio.write(&payload, sizeof(payload));
196 uint32_t timerElapsed = getMicros();
197
198 if (report) {
199
200 cout << "Transmission of PayloadID ";
201 cout << payload.payloadID;
202 cout << " as node " << payload.nodeID;
203 cout << " successful! Time to transmit = ";
204 cout << timerElapsed << " us" << endl;
205 }
206 else {
207
208 failures++;
209 cout << "Transmission failed or timed out" << endl;
210 }
211 payload.payloadID++;
212
213
215 }
216 cout << failures << " failures detected. Leaving TX role." << endl;
217}
218
222void slave()
223{
224
225
226 for (uint8_t i = 0; i < 6; ++i)
227 radio.openReadingPipe(i, address[i]);
228
229 radio.startListening();
230
231 time_t startTimer = time(nullptr);
232 while (time(nullptr) - startTimer < 6) {
233 uint8_t pipe;
234 if (radio.available(&pipe)) {
235 uint8_t bytes = radio.getPayloadSize();
236 radio.read(&payload, bytes);
237 cout << "Received " << (unsigned int)bytes;
238 cout << " bytes on pipe " << (unsigned int)pipe;
239 cout << " from node " << payload.nodeID;
240 cout << ". PayloadID: " << payload.payloadID << endl;
241 startTimer = time(nullptr);
242 }
243 }
244 cout << "Nothing received in 6 seconds. Leaving RX role." << endl;
245}
246
250uint32_t getMicros()
251{
252
253
254
255 clock_gettime(CLOCK_MONOTONIC_RAW, &endTimer);
256 uint32_t seconds = endTimer.tv_sec - startTimer.tv_sec;
257 uint32_t useconds = (endTimer.tv_nsec - startTimer.tv_nsec) / 1000;
258
259 return ((seconds)*1000 + useconds) + 0.5;
260}
261
265void printHelp(string progName)
266{
267 cout << "usage: " << progName << " [-h] [-n {0,1,2,3,4,5,r,R}]\n\n"
268 << "A simple example of sending data from as many as 6 nRF24L01 transceivers to\n"
269 << "1 receiving transceiver. This technique is trademarked by\n"
270 << "Nordic Semiconductors as 'MultiCeiver'.\n"
271 << "\nThis example was written to be used on up to 6 devices acting as TX nodes with\n"
272 << "another device acting as a RX node (that's a total of 7 devices).\n"
273 << "\noptional arguments:\n -h, --help\t\tshow this help message and exit\n"
274 << " -n {0,1,2,3,4,5,r,R}, --node {0,1,2,3,4,5,r,R}"
275 << "\n\t\t\t0-5 specifies the identifying node ID number for the TX role."
276 << "\n\t\t\t'r' or 'R' specifies the RX role." << endl;
277}
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.