Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8RF24examplesManualAcknowledgementsManualAcknowledgements.ino

222 lines · 8.4 KB

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
7/**
8 * A simple example of sending data from 1 nRF24L01 transceiver to another
9 * with manually transmitted (non-automatic) Acknowledgement (ACK) payloads.
10 * This example still uses ACK packets, but they have no payloads. Instead the
11 * acknowledging response is sent with `write()`. This tactic allows for more
12 * updated acknowledgement payload data, where actual ACK payloads' data are
13 * outdated by 1 transmission because they have to loaded before receiving a
14 * transmission.
15 *
16 * This example was written to be used on 2 devices acting as "nodes".
17 * Use the Serial Monitor to change each node's behavior.
18 */
19#include <SPI.h>
20#include "printf.h"
21#include "RF24.h"
22
23#define CE_PIN 7
24#define CSN_PIN 8
25// instantiate an object for the nRF24L01 transceiver
26RF24 radio(CE_PIN, CSN_PIN);
27
28// Let these addresses be used for the pair
29uint8_t address[][6] = { "1Node", "2Node" };
30// It is very helpful to think of an address as a path instead of as
31// an identifying device destination
32
33// to use different addresses on a pair of radios, we need a variable to
34// uniquely identify which address this radio will use to transmit
35bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
36
37// Used to control whether this node is sending or receiving
38bool role = false; // true = TX node, false = RX node
39
40// For this example, we'll be using a payload containing
41// a string & an integer number that will be incremented
42// on every successful transmission.
43// Make a data structure to store the entire payload of different datatypes
44struct PayloadStruct {
45 char message[7]; // only using 6 characters for TX & RX payloads
46 uint8_t counter;
47};
48PayloadStruct payload;
49
50void setup() {
51
52 // append a NULL terminating character for printing as a c-string
53 payload.message[6] = 0;
54
55 Serial.begin(115200);
56 while (!Serial) {
57 // some boards need to wait to ensure access to serial over USB
58 }
59
60 // initialize the transceiver on the SPI bus
61 if (!radio.begin()) {
62 Serial.println(F("radio hardware is not responding!!"));
63 while (1) {} // hold in infinite loop
64 }
65
66 // print example's introductory prompt
67 Serial.println(F("RF24/examples/ManualAcknowledgements"));
68
69 // To set the radioNumber via the Serial monitor on startup
70 Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
71 while (!Serial.available()) {
72 // wait for user input
73 }
74 char input = Serial.parseInt();
75 radioNumber = input == 1;
76 Serial.print(F("radioNumber = "));
77 Serial.println((int)radioNumber);
78
79 // role variable is hardcoded to RX behavior, inform the user of this
80 Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
81
82 // Set the PA Level low to try preventing power supply related problems
83 // because these examples are likely run with nodes in close proximity to
84 // each other.
85 radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
86
87 // save on transmission time by setting the radio to only transmit the
88 // number of bytes we need to transmit a float
89 radio.setPayloadSize(sizeof(payload)); // char[7] & uint8_t datatypes occupy 8 bytes
90
91 // set the TX address of the RX node for use on the TX pipe (pipe 0)
92 radio.stopListening(address[radioNumber]); // put radio in TX mode
93
94 // set the RX address of the TX node into a RX pipe
95 radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
96
97 if (role) {
98 // setup the TX node
99
100 memcpy(payload.message, "Hello ", 6); // set the outgoing message
101 } else {
102 // setup the RX node
103
104 memcpy(payload.message, "World ", 6); // set the outgoing message
105 radio.startListening(); // put radio in RX mode
106 }
107
108 // For debugging info
109 // printf_begin(); // needed only once for printing details
110 // radio.printDetails(); // (smaller) function that prints raw register values
111 // radio.printPrettyDetails(); // (larger) function that prints human readable data
112
113} // setup()
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
123 if (report) {
124 // transmission successful; wait for response and print results
125
126 radio.startListening(); // put in RX mode
127 unsigned long start_timeout = millis(); // timer to detect timeout
128 while (!radio.available()) { // wait for response
129 if (millis() - start_timeout > 200) // only wait 200 ms
130 break;
131 delayMicroseconds(200); // relax probing of available()
132 }
133 unsigned long end_timer = micros(); // end the timer
134 radio.stopListening(); // put back in TX mode
135
136 // print summary of transactions
137 Serial.print(F("Transmission successful!")); // payload was delivered
138 uint8_t pipe;
139 if (radio.available(&pipe)) { // is there a payload received
140 Serial.print(F(" Round-trip delay: "));
141 Serial.print(end_timer - start_timer); // print the timer result
142 Serial.print(F(" us. Sent: "));
143 Serial.print(payload.message); // print the outgoing payload's message
144 Serial.print(payload.counter); // print outgoing payload's counter
145 PayloadStruct received;
146 radio.read(&received, sizeof(received)); // get payload from RX FIFO
147 Serial.print(F(" Received "));
148 Serial.print(radio.getPayloadSize()); // print the size of the payload
149 Serial.print(F(" bytes on pipe "));
150 Serial.print(pipe); // print the pipe number
151 Serial.print(F(": "));
152 Serial.print(received.message); // print the incoming payload's message
153 Serial.println(received.counter); // print the incoming payload's counter
154 payload.counter = received.counter; // save incoming counter for next outgoing counter
155 } else {
156 Serial.println(F(" Received no response.")); // no response received
157 }
158 } else {
159 Serial.println(F("Transmission failed or timed out")); // payload was not delivered
160 } // report
161
162 // to make this example readable in the serial monitor
163 delay(1000); // slow transmissions down by 1 second
164
165 } else {
166 // This device is a RX node
167
168 uint8_t pipe;
169 if (radio.available(&pipe)) { // is there a payload? get the pipe number that received it
170 PayloadStruct received;
171 radio.read(&received, sizeof(received)); // get incoming payload
172 payload.counter = received.counter + 1; // increment incoming counter for next outgoing response
173
174 // transmit response & save result to `report`
175 radio.stopListening(); // put in TX mode
176
177 radio.writeFast(&payload, sizeof(payload)); // load response to TX FIFO
178 bool report = radio.txStandBy(150); // keep retrying for 150 ms
179
180 radio.startListening(); // put back in RX mode
181
182 // print summary of transactions
183 Serial.print(F("Received "));
184 Serial.print(radio.getPayloadSize()); // print the size of the payload
185 Serial.print(F(" bytes on pipe "));
186 Serial.print(pipe); // print the pipe number
187 Serial.print(F(": "));
188 Serial.print(received.message); // print incoming message
189 Serial.print(received.counter); // print incoming counter
190
191 if (report) {
192 Serial.print(F(" Sent: "));
193 Serial.print(payload.message); // print outgoing message
194 Serial.println(payload.counter); // print outgoing counter
195 } else {
196 Serial.println(" Response failed."); // failed to send response
197 }
198 }
199 } // role
200
201 if (Serial.available()) {
202 // change the role via the serial monitor
203
204 char c = toupper(Serial.read());
205 if (c == 'T' && !role) {
206 // Become the TX node
207
208 role = true;
209 memcpy(payload.message, "Hello ", 6); // set the outgoing message
210 Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
211 radio.stopListening(); // put in TX mode
212
213 } else if (c == 'R' && role) {
214 // Become the RX node
215
216 role = false;
217 memcpy(payload.message, "World ", 6); // set the response message
218 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
219 radio.startListening(); // put in RX mode
220 }
221 }
222} // loop