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

Written by TMRh20

This example demonstrates the use of and extended timeout period and auto-retries/auto-reUse to increase reliability in noisy or low signal scenarios.

Write this sketch to two different nodes. Put one of the nodes into 'transmit' mode by connecting with the serial monitor and sending a 'T'. The data
transfer will begin, with the receiver displaying the payload count and the data transfer rate.

1/*
2 TMRh20 2014
3
4 This program is free software; you can redistribute it and/or
5 modify it under the terms of the GNU General Public License
6 version 2 as published by the Free Software Foundation.
7*/
8
23#include <SPI.h>
24#include "nRF24L01.h"
25#include "RF24.h"
26#include "printf.h"
27
28/************* USER Configuration *****************************/
29
30RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
31unsigned long timeoutPeriod = 3000; // Set a user-defined timeout period. With auto-retransmit set to (15,15) retransmission will take up to 60ms and as little as 7.5ms with it set to (1,15).
32// With a timeout period of 1000, the radio will retry each payload for up to 1 second before giving up on the transmission and starting over
33
34/***************************************************************/
35
36const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate.
37
38byte data[32]; //Data buffer
39
40volatile unsigned long counter;
41unsigned long rxTimer, startTime, stopTime, payloads = 0;
42bool tx = 1, rx = 0, role = 0, transferInProgress = 0;
43
44
45void setup(void) {
46
47 Serial.begin(115200);
49
50 radio.begin(); // Setup and configure rf radio
51 radio.setChannel(1); // Set the channel
52 radio.setPALevel(RF24_PA_LOW); // Set PA LOW for this demonstration. We want the radio to be as lossy as possible for this example.
53 radio.setDataRate(RF24_1MBPS); // Raise the data rate to reduce transmission distance and increase lossiness
54 radio.setAutoAck(1); // Ensure autoACK is enabled
55 radio.setRetries(2, 15); // Optionally, increase the delay between retries. Want the number of auto-retries as high as possible (15)
56 radio.setCRCLength(RF24_CRC_16); // Set CRC length to 16-bit to ensure quality of data
57 radio.openWritingPipe(pipes[0]); // Open the default reading and writing pipe
58 radio.openReadingPipe(1, pipes[1]);
59
60 radio.startListening(); // Start listening
61 radio.printDetails(); // Dump the configuration of the rf unit for debugging
62
63 printf("\n\rRF24/examples/Transfer Rates/\n\r");
64 printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
65
66 randomSeed(analogRead(0)); //Seed for random number generation
67 for (int i = 0; i < 32; i++) {
68 data[i] = random(255); //Load the buffer with random data
69 }
70 radio.powerUp(); //Power up the radio
71}
72
73
74
75void loop(void) {
76
77
78 if (role == tx) {
79 delay(2000); // Pause for a couple seconds between transfers
80 printf("Initiating Extended Timeout Data Transfer\n\r");
81
82 unsigned long cycles = 1000; // Change this to a higher or lower number. This is the number of payloads that will be sent.
83
84 unsigned long transferCMD[] = { 'H', 'S', cycles }; // Indicate to the other radio that we are starting, and provide the number of payloads that will be sent
85 radio.writeFast(&transferCMD, 12); // Send the transfer command
86 if (radio.txStandBy(timeoutPeriod)) { // If transfer initiation was successful, do the following
87
88 startTime = millis(); // For calculating transfer rate
89 boolean timedOut = 0; // Boolean for keeping track of failures
90
91 for (unsigned long i = 0; i < cycles; i++) // Loop through a number of cycles
92 {
93 data[0] = i; // Change the first byte of the payload for identification
94
95 if (!radio.writeBlocking(&data, 32, timeoutPeriod)) { // If retries are failing and the user defined timeout is exceeded
96 timedOut = 1; // Indicate failure
97 counter = cycles; // Set the fail count to maximum
98 break; // Break out of the for loop
99 }
100 }
101
102
103 stopTime = millis(); // Capture the time of completion or failure
104
105 //This should be called to wait for completion and put the radio in standby mode after transmission, returns 0 if data still in FIFO (timed out), 1 if success
106 if (timedOut) {
107 radio.txStandBy(); //Partially blocking standby, blocks until success or max retries. FIFO flushed if auto timeout reached
108 } else {
109 radio.txStandBy(timeoutPeriod); //Standby, block until FIFO empty (sent) or user specified timeout reached. FIFO flushed if user timeout reached.
110 }
111
112 } else {
113 Serial.println("Communication not established"); //If unsuccessful initiating transfer, exit and retry later
114 }
115
116 float rate = cycles * 32 / (stopTime - startTime); //Display results:
117
118 Serial.print("Transfer complete at ");
119 Serial.print(rate);
120 Serial.println(" KB/s");
121 Serial.print(counter);
122 Serial.print(" of ");
123 Serial.print(cycles);
124 Serial.println(" Packets Failed to Send");
125 counter = 0;
126 }
127
128
129
130 if (role == rx) {
131
132 if (!transferInProgress) { // If a bulk data transfer has not been started
133 if (radio.available()) {
134 radio.read(&data, 32); //Read any available payloads for analysis
135
136 if (data[0] == 'H' && data[4] == 'S') { // If a bulk data transfer command has been received
137 payloads = data[8]; // Read the first two bytes of the unsigned long. Need to read the 3rd and 4th if sending more than 65535 payloads
138 payloads |= data[9] << 8; // This is the number of payloads that will be sent
139 counter = 0; // Reset the payload counter to 0
140 transferInProgress = 1; // Indicate it has started
141 startTime = rxTimer = millis(); // Capture the start time to measure transfer rate and calculate timeouts
142 }
143 }
144 } else {
145 if (radio.available()) { // If in bulk transfer mode, and a payload is available
146 radio.read(&data, 32); // Read the payload
147 rxTimer = millis(); // Reset the timeout timer
148 counter++; // Keep a count of received payloads
149 } else if (millis() - rxTimer > timeoutPeriod) { // If no data available, check the timeout period
150 Serial.println("Transfer Failed"); // If per-payload timeout exceeded, end the transfer
151 transferInProgress = 0;
152 } else if (counter >= payloads) { // If the specified number of payloads is reached, transfer is completed
153 startTime = millis() - startTime; // Calculate the total time spent during transfer
154 float numBytes = counter * 32; // Calculate the number of bytes transferred
155 Serial.print("Rate: "); // Print the transfer rate and number of payloads
156 Serial.print(numBytes / startTime);
157 Serial.println(" KB/s");
158 Serial.print("Payload Count: ");
159 Serial.println(counter);
160 transferInProgress = 0; // End the transfer as complete
161 }
162 }
163 }
164
165 //
166 // Change roles
167 //
168
169 if (Serial.available()) {
170 char c = toupper(Serial.read());
171 if (c == 'T' && role == rx) {
172 printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
173 radio.openWritingPipe(pipes[1]);
174 radio.openReadingPipe(1, pipes[0]);
175 radio.stopListening();
176 role = tx; // Become the primary transmitter (ping out)
177 } else if (c == 'R' && role == tx) {
178 radio.openWritingPipe(pipes[0]);
179 radio.openReadingPipe(1, pipes[1]);
180 radio.startListening();
181 printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
182 role = rx; // Become the primary receiver (pong back)
183 }
184 }
185}
Driver class for nRF24L01(+) 2.4GHz Wireless Transceiver.
Definition RF24.h:116
@ RF24_CRC_16
Definition RF24.h:108
@ RF24_1MBPS
Definition RF24.h:83
@ RF24_PA_LOW
Definition RF24.h:50
#define delay(millisec)
#define millis()
void printf_begin(void)
Definition printf.h:33