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

Written by 2bndy5 in 2020

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 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
16#include <SPI.h>
17#include "printf.h"
18#include "RF24.h"
19
20#define CE_PIN 7
21#define CSN_PIN 8
22// instantiate an object for the nRF24L01 transceiver
23RF24 radio(CE_PIN, CSN_PIN);
24
25// For this example, we'll be using 6 addresses; 1 for each TX node
26// It is very helpful to think of an address as a path instead of as
27// an identifying device destination
28// Notice that the last byte is the only byte that changes in the last 5
29// addresses. This is a limitation of the nRF24L01 transceiver for pipes 2-5
30// because they use the same first 4 bytes from pipe 1.
31uint64_t address[6] = { 0x7878787878LL,
32 0xB3B4B5B6F1LL,
33 0xB3B4B5B6CDLL,
34 0xB3B4B5B6A3LL,
35 0xB3B4B5B60FLL,
36 0xB3B4B5B605LL };
37
38// role variable is used to control whether this node is sending or receiving
39char role = 'R'; // integers 0-5 = TX node; character 'R' or integer 82 = RX node
40
41// For this example, we'll be using a payload containing
42// a node ID number and a single integer number that will be incremented
43// on every successful transmission.
44// Make a data structure to use as a payload.
45struct PayloadStruct {
46 unsigned long nodeID;
47 unsigned long payloadID;
48};
49PayloadStruct payload;
50
51// This example uses all 6 pipes to receive while TX nodes only use 2 pipes
52// To make this easier we'll use a function to manage the addresses, and the
53// payload's nodeID
54void setRole(); // declare a prototype; definition is found after the loop()
55
56void setup() {
57
58 Serial.begin(115200);
59 while (!Serial) {
60 // some boards need to wait to ensure access to serial over USB
61 }
62
63 // initialize the transceiver on the SPI bus
64 if (!radio.begin()) {
65 Serial.println(F("radio hardware is not responding!!"));
66 while (1) {} // hold in infinite loop
67 }
68
69 // print example's introductory prompt
70 Serial.println(F("RF24/examples/MulticeiverDemo"));
71 Serial.println(F("*** Enter a number between 0 and 5 (inclusive) to change"));
72 Serial.println(F(" the identifying node number that transmits."));
73
74 // Set the PA Level low to try preventing power supply related problems
75 // because these examples are likely run with nodes in close proximity of
76 // each other.
77 radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
78
79 // save on transmission time by setting the radio to only transmit the
80 // number of bytes we need to transmit a float
81 radio.setPayloadSize(sizeof(payload)); // 2x int datatype occupy 8 bytes
82
83 // Set the pipe addresses accordingly. This function additionally also
84 // calls startListening() or stopListening() and sets the payload's nodeID
85 setRole();
86
87 // For debugging info
88 // printf_begin(); // needed only once for printing details
89 // radio.printDetails(); // (smaller) function that prints raw register values
90 // radio.printPrettyDetails(); // (larger) function that prints human readable data
91
92} // setup()
93
94void loop() {
95
96 if (role <= 53) {
97 // This device is a TX node
98
99 unsigned long start_timer = micros(); // start the timer
100 bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
101 unsigned long end_timer = micros(); // end the timer
102
103 if (report) {
104 // payload was delivered
105
106 Serial.print(F("Transmission of payloadID "));
107 Serial.print(payload.payloadID); // print payloadID
108 Serial.print(F(" as node "));
109 Serial.print(payload.nodeID); // print nodeID
110 Serial.print(F(" successful!"));
111 Serial.print(F(" Time to transmit: "));
112 Serial.print(end_timer - start_timer); // print the timer result
113 Serial.println(F(" us"));
114 } else {
115 Serial.println(F("Transmission failed or timed out")); // payload was not delivered
116 }
117 payload.payloadID++; // increment payload number
118
119 // to make this example readable in the serial monitor
120 delay(1000); // slow transmissions down by 1 second
121
122 } else if (role == 'R') {
123 // This device is the RX node
124
125 uint8_t pipe;
126 if (radio.available(&pipe)) { // is there a payload? get the pipe number that received it
127 uint8_t bytes = radio.getPayloadSize(); // get the size of the payload
128 radio.read(&payload, bytes); // fetch payload from FIFO
129 Serial.print(F("Received "));
130 Serial.print(bytes); // print the size of the payload
131 Serial.print(F(" bytes on pipe "));
132 Serial.print(pipe); // print the pipe number
133 Serial.print(F(" from node "));
134 Serial.print(payload.nodeID); // print the payload's origin
135 Serial.print(F(". PayloadID: "));
136 Serial.println(payload.payloadID); // print the payload's number
137 }
138 } // role
139
140 if (Serial.available()) {
141 // change the role via the serial monitor
142
143 char c = Serial.read();
144 if (toupper(c) == 'R' && role <= 53) {
145 // Become the RX node
146
147 role = 'R';
148 Serial.println(F("*** CHANGING ROLE TO RECEIVER ***"));
149 Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to act as"));
150 Serial.println(F(" a unique node number that transmits to the RX node."));
151 setRole(); // change address on all pipes to TX nodes
152
153 } else if (c >= 48 && c <= 53 && c != role) {
154 // Become a TX node with identifier 'c'
155
156 role = c - 48;
157 Serial.print(F("*** CHANGING ROLE TO NODE "));
158 Serial.print(c);
159 Serial.println(F(" ***"));
160 Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to change"));
161 Serial.println(F(" the identifying node number that transmits."));
162 Serial.println(F("--- PRESS 'R' to act as the RX node."));
163 setRole(); // change address on pipe 0 to the RX node
164 }
165 }
166
167} // loop
168
169void setRole() {
170 if (role == 'R') {
171 // For the RX node
172
173 // Set the addresses for all pipes to TX nodes
174 for (uint8_t i = 0; i < 6; ++i)
175 radio.openReadingPipe(i, address[i]);
176
177 radio.startListening(); // put radio in RX mode
178
179 } else {
180 // For the TX node
181
182 // set the payload's nodeID & reset the payload's identifying number
183 payload.nodeID = role;
184 payload.payloadID = 0;
185
186 // Set the address on pipe 0 to the RX node.
187 radio.stopListening(); // put radio in TX mode
188 radio.openWritingPipe(address[role]);
189
190 // According to the datasheet, the auto-retry features's delay value should
191 // be "skewed" to allow the RX node to receive 1 transmission at a time.
192 // So, use varying delay between retry attempts and 15 (at most) retry attempts
193 radio.setRetries(((role * 3) % 12) + 3, 15); // maximum value is 15 for both args
194 }
195} // setRole
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.
Definition RF24.h:136
@ RF24_PA_LOW
Definition RF24.h:50
#define delay(millisec)