ATMEGA328P_connectedMailBox/src/libs/RF24-master/examples/MulticeiverDemo/MulticeiverDemo.ino

198 lines
7.4 KiB
C++

/*
* See documentation at https://nRF24.github.io/RF24
* See License information at root directory of this library
* Author: Brendan Doherty 2bndy5
*/
/**
* 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.
*/
#include <SPI.h>
#include "printf.h"
#include "RF24.h"
// instantiate an object for the nRF24L01 transceiver
RF24 radio(7, 8); // using pin 7 for the CE pin, and pin 8 for the CSN pin
// For this example, we'll be using 6 addresses; 1 for each TX node
// It is very helpful to think of an address as a path instead of as
// an identifying device destination
// Notice that the last byte is the only byte that changes in the last 5
// addresses. This is a limitation of the nRF24L01 transceiver for pipes 2-5
// because they use the same first 4 bytes from pipe 1.
uint64_t address[6] = {0x7878787878LL,
0xB3B4B5B6F1LL,
0xB3B4B5B6CDLL,
0xB3B4B5B6A3LL,
0xB3B4B5B60FLL,
0xB3B4B5B605LL
};
// Because this example allow up to 6 nodes (specified by numbers 0-5) to
// transmit and only 1 node to receive, we will use a negative value in our
// role variable to signify this node is a receiver.
// role variable is used to control whether this node is sending or receiving
char role = 'R'; // 0-5 = TX node; any negative number = RX node
// For this example, we'll be using a payload containing
// a node ID number and a single integer number that will be incremented
// on every successful transmission.
// Make a data structure to use as a payload.
struct PayloadStruct
{
unsigned long nodeID;
unsigned long payloadID;
};
PayloadStruct payload;
// This example uses all 6 pipes to receive while TX nodes only use 2 pipes
// To make this easier we'll use a function to manage the addresses, and the
// payload's nodeID
void setRole(); // declare a prototype; definition is found after the loop()
void setup() {
Serial.begin(115200);
while (!Serial) {
// some boards need to wait to ensure access to serial over USB
}
// 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/MulticeiverDemo"));
Serial.println(F("*** Enter a number between 0 and 5 (inclusive) to change"));
Serial.println(F(" the identifying node number that transmits."));
// Set the PA Level low to try preventing power supply related problems
// because these examples are likely run with nodes in close proximity of
// each other.
radio.setPALevel(RF24_PA_LOW); // RF24_PA_MAX is default.
// save on transmission time by setting the radio to only transmit the
// number of bytes we need to transmit a float
radio.setPayloadSize(sizeof(payload)); // 2x int datatype occupy 8 bytes
// Set the pipe addresses accordingly. This function additionally also
// calls startListening() or stopListening() and sets the payload's nodeID
setRole();
// For debugging info
// printf_begin(); // needed only once for printing details
// radio.printDetails(); // (smaller) function that prints raw register values
// radio.printPrettyDetails(); // (larger) function that prints human readable data
} // setup()
void loop() {
if (role <= 53) {
// 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) {
// payload was delivered
Serial.print(F("Transmission of payloadID "));
Serial.print(payload.payloadID); // print payloadID
Serial.print(F(" as node "));
Serial.print(payload.nodeID); // print nodeID
Serial.print(F(" successful!"));
Serial.print(F(" Time to transmit: "));
Serial.print(end_timer - start_timer); // print the timer result
Serial.println(F(" us"));
} else {
Serial.println(F("Transmission failed or timed out")); // payload was not delivered
}
payload.payloadID++; // increment payload number
// to make this example readable in the serial monitor
delay(500); // slow transmissions down by 1 second
} else if (role == 'R') {
// This device is the RX node
uint8_t pipe;
if (radio.available(&pipe)) { // is there a payload? get the pipe number that recieved it
uint8_t bytes = radio.getPayloadSize(); // get the size of the payload
radio.read(&payload, bytes); // fetch payload from FIFO
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(" from node "));
Serial.print(payload.nodeID); // print the payload's origin
Serial.print(F(". PayloadID: "));
Serial.println(payload.payloadID); // print the payload's number
}
} // role
if (Serial.available()) {
// change the role via the serial monitor
char c = Serial.read();
if (toupper(c) == 'R' && role <= 53) {
// Become the RX node
role = 'R';
Serial.println(F("*** CHANGING ROLE TO RECEIVER ***"));
Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to act as"));
Serial.println(F(" a unique node number that transmits to the RX node."));
setRole(); // change address on all pipes to TX nodes
} else if (c >= 48 && c <= 53 && c != role) {
// Become a TX node with identifier 'c'
role = c - 48;
Serial.print(F("*** CHANGING ROLE TO NODE "));
Serial.print(c);
Serial.println(F(" ***"));
Serial.println(F("--- Enter a number between 0 and 5 (inclusive) to change"));
Serial.println(F(" the identifying node number that transmits."));
Serial.println(F("--- PRESS 'R' to act as the RX node."));
setRole(); // change address on pipe 0 to the RX node
}
}
} // loop
void setRole() {
if (role == 'R') {
// For the RX node
// Set the addresses for all pipes to TX nodes
for (uint8_t i = 0; i < 6; ++i)
radio.openReadingPipe(i, address[i]);
radio.startListening(); // put radio in RX mode
} else {
// For the TX node
// set the payload's nodeID & reset the payload's identifying number
payload.nodeID = role;
payload.payloadID = 0;
// Set the address on pipe 0 to the RX node.
radio.stopListening(); // put radio in TX mode
radio.openWritingPipe(address[role]);
// According to the datasheet, the auto-retry features's delay value should
// be "skewed" to allow the RX node to receive 1 transmission at a time.
// So, use varying delay between retry attempts and 15 (at most) retry attempts
radio.setRetries(((role * 3) % 12) + 3, 15); // maximum value is 15 for both args
}
} // setRole