nrf_to_nrf - NRF52 Radio Driver v1.2.2
TMRh20 2023 - OSI Layer 2 radio driver using RF24 API
Loading...
Searching...
No Matches
examples/RF24/AcknowledgementPayloads/AcknowledgementPayloads.ino
/*
* See documentation at https://nRF24.github.io/RF24
* See License information at root directory of this library
* Author: Brendan Doherty (2bndy5)
*/
#include "nrf_to_nrf.h"
// instantiate an object for the nRF24L01 transceiver
nrf_to_nrf radio; // using pin 7 for the CE pin, and pin 8 for the CSN pin
// an identifying device destination
// Let these addresses be used for the pair
uint8_t address[][6] = { "1Node", "2Node" };
// It is very helpful to think of an address as a path instead of as
// an identifying device destination
// to use different addresses on a pair of radios, we need a variable to
// uniquely identify which address this radio will use to transmit
bool radioNumber = 1; // 0 uses address[0] to transmit, 1 uses address[1] to transmit
// Used to control whether this node is sending or receiving
bool role = false; // true = TX role, false = RX role
// For this example, we'll be using a payload containing
// a string & an integer number that will be incremented
// on every successful transmission.
// Make a data structure to store the entire payload of different datatypes
struct PayloadStruct {
char message[7]; // only using 6 characters for TX & ACK payloads
uint8_t counter;
};
PayloadStruct payload;
void setup() {
Serial.begin(115200);
while (!Serial) {
// some boards need to wait to ensure access to serial over USB
}
delay(5000);
// initialize the transceiver on the SPI bus
if (!radio.begin()) {
Serial.println(F("radio hardware is not responding!!"));
while (1) {} // hold in infinite loop
}
// print example's introductory prompt
Serial.println(F("RF24/examples/AcknowledgementPayloads"));
// To set the radioNumber via the Serial monitor on startup
Serial.println(F("Which radio is this? Enter '0' or '1'. Defaults to '0'"));
while (!Serial.available()) {
// wait for user input
}
char input = Serial.parseInt();
radioNumber = input == 1;
Serial.print(F("radioNumber = "));
Serial.println((int)radioNumber);
// role variable is hardcoded to RX behavior, inform the user of this
Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
// Set the PA Level low to try preventing power supply related problems
// because these examples are likely run with nodes in close proximity to
// each other.
radio.setPALevel(NRF_PA_MAX); // RF24_PA_MAX is default.
// to use ACK payloads, we need to enable dynamic payload lengths (for all nodes)
radio.enableDynamicPayloads(); // ACK payloads are dynamically sized
// Acknowledgement packets have no payloads by default. We need to enable
// this feature for all nodes (TX & RX) to use ACK payloads.
// set the TX address of the RX node into the TX pipe
radio.openWritingPipe(address[radioNumber]); // always uses pipe 0
// set the RX address of the TX node into a RX pipe
radio.openReadingPipe(1, address[!radioNumber]); // using pipe 1
// additional setup specific to the node's role
if (role) {
// setup the TX payload
memcpy(payload.message, "Hello ", 6); // set the payload message
radio.stopListening(); // put radio in TX mode
} else {
// setup the ACK payload & load the first response into the FIFO
memcpy(payload.message, "World ", 6); // set the payload message
// load the payload for the first received transmission on pipe 0
radio.writeAckPayload(1, &payload, sizeof(payload));
radio.startListening(); // put radio in RX mode
}
// For debugging info
// radio.printDetails(); // (smaller) function that prints raw register values
// radio.printPrettyDetails(); // (larger) function that prints human readable data
}
void loop() {
if (role) {
// This device is a TX node
unsigned long start_timer = micros(); // start the timer
bool report = radio.write(&payload, sizeof(payload)); // transmit & save the report
unsigned long end_timer = micros(); // end the timer
if (report) {
Serial.print(F("Transmission successful! ")); // payload was delivered
Serial.print(F("Time to transmit = "));
Serial.print(end_timer - start_timer); // print the timer result
Serial.print(F(" us. Sent: "));
Serial.print(payload.message); // print the outgoing message
Serial.print(payload.counter); // print the outgoing counter
uint8_t pipe;
if (radio.available(&pipe)) { // is there an ACK payload? grab the pipe number that received it
PayloadStruct received;
radio.read(&received, sizeof(received)); // get incoming ACK payload
Serial.print(F(" Recieved "));
Serial.print(radio.getDynamicPayloadSize()); // print incoming payload size
Serial.print(F(" bytes on pipe "));
Serial.print(pipe); // print pipe number that received the ACK
Serial.print(F(": "));
Serial.print(received.message); // print incoming message
Serial.println(received.counter); // print incoming counter
// save incoming counter & increment for next outgoing
payload.counter = received.counter + 1;
} else {
Serial.println(F(" Recieved: an empty ACK packet")); // empty ACK packet received
}
} else {
Serial.println(F("Transmission failed or timed out")); // payload was not delivered
}
// to make this example readable in the serial monitor
delay(1000); // slow transmissions down by 1 second
} else {
// This device is a RX node
uint8_t pipe;
if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it
uint8_t bytes = radio.getDynamicPayloadSize(); // get the size of the payload
PayloadStruct received;
radio.read(&received, sizeof(received)); // get incoming payload
Serial.print(F("Received "));
Serial.print(bytes); // print the size of the payload
Serial.print(F(" bytes on pipe "));
Serial.print(pipe); // print the pipe number
Serial.print(F(": "));
Serial.print(received.message); // print incoming message
Serial.print(received.counter); // print incoming counter
Serial.print(F(" Sent: "));
Serial.print(payload.message); // print outgoing message
Serial.println(payload.counter); // print outgoing counter
// save incoming counter & increment for next outgoing
payload.counter = received.counter + 1;
// load the payload for the first received transmission on pipe 0
radio.writeAckPayload(1, &payload, sizeof(payload));
}
} // role
if (Serial.available()) {
// change the role via the serial monitor
char c = toupper(Serial.read());
if (c == 'T' && !role) {
// Become the TX node
role = true;
Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
memcpy(payload.message, "Hello ", 6); // change payload message
radio.stopListening(); // this also discards any unused ACK payloads
} else if (c == 'R' && role) {
// Become the RX node
role = false;
Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
memcpy(payload.message, "World ", 6); // change payload message
// load the payload for the first received transmission on pipe 0
radio.writeAckPayload(1, &payload, sizeof(payload));
radio.startListening();
}
}
} // loop
Driver class for nRF52840 2.4GHz Wireless Transceiver.
Definition nrf_to_nrf.h:115
void startListening(bool resetAddresses=true)
void openReadingPipe(uint8_t child, const uint8_t *address)
bool available()
void setPALevel(uint8_t level, bool lnaEnable=true)
bool write(void *buf, uint8_t len, bool multicast=false, bool doEncryption=true)
uint8_t getDynamicPayloadSize()
bool begin()
bool writeAckPayload(uint8_t pipe, void *buf, uint8_t len)
void enableDynamicPayloads(uint8_t payloadSize=DEFAULT_MAX_PAYLOAD_SIZE)
void enableAckPayload()
void openWritingPipe(const uint8_t *address)
void read(void *buf, uint8_t len)
void stopListening(bool setWritingPipe=true, bool resetAddresses=true)
@ NRF_PA_MAX
Definition nrf_to_nrf.h:62