diff --git a/examples/GettingStarted/GettingStarted.ino b/examples/GettingStarted/GettingStarted.ino index e67c58c59..1524a6424 100644 --- a/examples/GettingStarted/GettingStarted.ino +++ b/examples/GettingStarted/GettingStarted.ino @@ -1,71 +1,65 @@ -/* - Copyright (C) 2011 J. Coliz - - This program is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License - version 2 as published by the Free Software Foundation. -//2014 - TMRh20 - Updated along with Optimized RF24 Library fork - */ - -/** - * Example for Getting Started with nRF24L01+ radios. - * - * This is an example of how to use the RF24 class to communicate on a basic level. 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 ping node sends the current time to the pong node, which responds by sending the value - * back. The ping node can then see how long the whole cycle took. - * Note: For a more efficient call-response scenario see the GettingStarted_CallResponse.ino example. - * Note: When switching between sketches, the radio may need to be powered down to clear settings that are not "un-set" otherwise - */ +/* +* Getting Started example sketch for nRF24L01+ radios +* This is a very basic example of how to send data from one node to another +* Updated: Dec 2014 by TMRh20 +*/ #include -#include "nRF24L01.h" #include "RF24.h" -#include "printf.h" -// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 +/****************** User Config ***************************/ +/*** Set this radio as radio number 0 or 1 ***/ +bool radioNumber = 0; + +/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */ RF24 radio(7,8); +/**********************************************************/ byte addresses[][6] = {"1Node","2Node"}; - -// Set up roles to simplify testing -boolean role; // The main role variable, holds the current role identifier -boolean role_ping_out = 1, role_pong_back = 0; // The two different roles. +// Used to control whether this node is sending or receiving +bool role = 0; void setup() { - - Serial.begin(57600); - printf_begin(); - printf("\n\rRF24/examples/GettingStarted/\n\r"); - printf("*** PRESS 'T' to begin transmitting to the other node\n\r"); - - // Setup and configure rf radio - radio.begin(); // Start up the radio - radio.setAutoAck(1); // Ensure autoACK is enabled - radio.setRetries(15,15); // Max delay between retries & number of retries - radio.openWritingPipe(addresses[1]); - radio.openReadingPipe(1,addresses[0]); + Serial.println(F("RF24/examples/GettingStarted")); + Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); - radio.startListening(); // Start listening - radio.printDetails(); // Dump the configuration of the rf unit for debugging -} + radio.begin(); -void loop(void){ - + // Set the PA Level low to prevent power supply related issues since this is a + // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default. + radio.setPALevel(RF24_PA_LOW); + + // Open a writing and reading pipe on each radio, with opposite addresses + if(radioNumber){ + radio.openWritingPipe(addresses[1]); + radio.openReadingPipe(1,addresses[0]); + }else{ + radio.openWritingPipe(addresses[0]); + radio.openReadingPipe(1,addresses[1]); + } + + // Start the radio listening for data + radio.startListening(); +} -/****************** Ping Out Role ***************************/ - if (role == role_ping_out) { +void loop() { + + +/****************** Ping Out Role ***************************/ +if (role == 1) { radio.stopListening(); // First, stop listening so we can talk. - printf("Now sending \n\r"); + Serial.println(F("Now sending")); unsigned long time = micros(); // Take the time, and send it. This will block until complete - if (!radio.write( &time, sizeof(unsigned long) )){ printf("failed.\n\r"); } + if (!radio.write( &time, sizeof(unsigned long) )){ + Serial.println(F("failed")); + } radio.startListening(); // Now, continue listening @@ -80,58 +74,69 @@ void loop(void){ } if ( timeout ){ // Describe the results - printf("Failed, response timed out.\n\r"); + Serial.println(F("Failed, response timed out.")); }else{ unsigned long got_time; // Grab the response, compare, and send to debugging spew radio.read( &got_time, sizeof(unsigned long) ); - + unsigned long time = micros(); + // Spew it - printf("Sent %lu, Got response %lu, round-trip delay: %lu microseconds\n\r",time,got_time,micros()-got_time); + Serial.print(F("Sent ")); + Serial.print(time); + Serial.print(F(", Got response ")); + Serial.print(got_time); + Serial.print(F(", Round-trip delay ")); + Serial.print(time-got_time); + Serial.println(F(" microseconds")); } // Try again 1s later delay(1000); } + + /****************** Pong Back Role ***************************/ - if ( role == role_pong_back ) + if ( role == 0 ) { + unsigned long got_time; + if( radio.available()){ - unsigned long got_time; // Variable for the received timestamp + // Variable for the received timestamp while (radio.available()) { // While there is data ready radio.read( &got_time, sizeof(unsigned long) ); // Get the payload - } + } radio.stopListening(); // First, stop listening so we can talk radio.write( &got_time, sizeof(unsigned long) ); // Send the final one back. radio.startListening(); // Now, resume listening so we catch the next packets. - printf("Sent response %lu \n\r", got_time); + Serial.print(F("Sent response ")); + Serial.println(got_time); } } + + /****************** Change Roles via Serial Commands ***************************/ if ( Serial.available() ) { char c = toupper(Serial.read()); - if ( c == 'T' && role == role_pong_back ) - { - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r"); - - role = role_ping_out; // Become the primary transmitter (ping out) - radio.openWritingPipe(addresses[0]); - radio.openReadingPipe(1,addresses[1]); - - } - else if ( c == 'R' && role == role_ping_out ) - { - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r"); - - role = role_pong_back; // Become the primary receiver (pong back) - radio.openWritingPipe(addresses[1]); - radio.openReadingPipe(1,addresses[0]); + if ( c == 'T' && role == 0 ){ + Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); + role = 1; // Become the primary transmitter (ping out) + + }else + if ( c == 'R' && role == 1 ){ + Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); + role = 0; // Become the primary receiver (pong back) + radio.startListening(); + } } -} + + +} // Loop + diff --git a/examples/GettingStarted_CallResponse/GettingStarted_CallResponse.ino b/examples/GettingStarted_CallResponse/GettingStarted_CallResponse.ino index 5faaf236f..df26cb026 100644 --- a/examples/GettingStarted_CallResponse/GettingStarted_CallResponse.ino +++ b/examples/GettingStarted_CallResponse/GettingStarted_CallResponse.ino @@ -1,6 +1,6 @@ /* - March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork - Parts derived from examples by J. Coliz + Dec 2014 - TMRh20 - Updated + Derived from examples by J. Coliz */ /** * Example for efficient call-response using ack-payloads @@ -13,12 +13,16 @@ */ #include -#include "nRF24L01.h" #include "RF24.h" -#include "printf.h" +//#include "printf.h" -// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 +/****************** User Config ***************************/ +/*** Set this radio as radio number 0 or 1 ***/ +bool radioNumber = 0; + +/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */ RF24 radio(7,8); +/**********************************************************/ // Topology byte addresses[][6] = {"1Node","2Node"}; // Radio pipe addresses for the 2 nodes to communicate. @@ -33,24 +37,28 @@ byte counter = 1; // A void setup(){ - Serial.begin(57600); - printf_begin(); - printf("\n\rRF24/examples/GettingStarted/\n\r"); - printf("ROLE: %s\n\r",role_friendly_name[role]); - printf("*** PRESS 'T' to begin transmitting to the other node\n\r"); - + Serial.begin(115200); + Serial.println(F("RF24/examples/GettingStarted_CallResponse")); + Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); + //printf_begin(); // Setup and configure radio radio.begin(); - radio.setAutoAck(1); // Ensure autoACK is enabled - radio.enableAckPayload(); // Allow optional ack payloads - radio.setRetries(0,15); // Smallest time between retries, max no. of retries - radio.setPayloadSize(1); // Here we are sending 1-byte payloads to test the call-response speed - radio.openWritingPipe(addresses[1]); // Both radios listen on the same pipes by default, and switch when writing - radio.openReadingPipe(1,addresses[0]); // Open a reading pipe on address 0, pipe 1 - radio.startListening(); // Start listening - radio.powerUp(); - radio.printDetails(); // Dump the configuration of the rf unit for debugging + + radio.enableAckPayload(); // Allow optional ack payloads + radio.enableDynamicAck(); + + if(radioNumber){ + radio.openWritingPipe(addresses[1]); // Both radios listen on the same pipes by default, but opposite addresses + radio.openReadingPipe(1,addresses[0]); // Open a reading pipe on address 0, pipe 1 + }else{ + radio.openWritingPipe(addresses[0]); + radio.openReadingPipe(1,addresses[1]); + } + radio.startListening(); // Start listening + + radio.writeAckPayload(1,&counter,1); // Pre-load an ack-paylod into the FIFO buffer for pipe 1 + //radio.printDetails(); } void loop(void) { @@ -63,21 +71,31 @@ void loop(void) { byte gotByte; // Initialize a variable for the incoming response radio.stopListening(); // First, stop listening so we can talk. - printf("Now sending %d as payload. ",counter); // Use a simple byte counter as payload + Serial.print(F("Now sending ")); // Use a simple byte counter as payload + Serial.println(counter); + unsigned long time = micros(); // Record the current microsecond count if ( radio.write(&counter,1) ){ // Send the counter variable to the other radio if(!radio.available()){ // If nothing in the buffer, we got an ack but it is blank - printf("Got blank response. round-trip delay: %lu microseconds\n\r",micros()-time); + Serial.print(F("Got blank response. round-trip delay: ")); + Serial.print(micros()-time); + Serial.println(F(" microseconds")); }else{ while(radio.available() ){ // If an ack with payload was received radio.read( &gotByte, 1 ); // Read it, and display the response time - printf("Got response %d, round-trip delay: %lu microseconds\n\r",gotByte,micros()-time); + unsigned long timer = micros(); + + Serial.print(F("Got response ")); + Serial.print(gotByte); + Serial.print(F(" round-trip delay: ")); + Serial.print(timer-time); + Serial.println(F(" microseconds")); counter++; // Increment the counter variable } } - }else{ printf("Sending failed.\n\r"); } // If no ack response, sending failed + }else{ Serial.println(F("Sending failed.")); } // If no ack response, sending failed delay(1000); // Try again later } @@ -90,9 +108,10 @@ void loop(void) { while( radio.available(&pipeNo)){ // Read all available payloads radio.read( &gotByte, 1 ); // Since this is a call-response. Respond directly with an ack payload. - // Ack payloads are much more efficient than switching to transmit mode to respond to a call + gotByte += 1; // Ack payloads are much more efficient than switching to transmit mode to respond to a call radio.writeAckPayload(pipeNo,&gotByte, 1 ); // This can be commented out to send empty payloads. - printf("Sent response %d \n\r", gotByte); + Serial.print(F("Loaded next response ")); + Serial.println(gotByte); } } @@ -103,22 +122,18 @@ void loop(void) { if ( Serial.available() ) { char c = toupper(Serial.read()); - if ( c == 'T' && role == role_pong_back ) - { - printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r"); - - role = role_ping_out; // Change roles (ping out) - radio.openWritingPipe(addresses[0]); // Open different pipes when writing. Write on pipe 0, address 0 - radio.openReadingPipe(1,addresses[1]); // Read on pipe 1, as address 1 - } - else if ( c == 'R' && role == role_ping_out ) - { - printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r"); - - role = role_pong_back; // Become the primary receiver (pong back) - radio.openWritingPipe(addresses[1]); // Since only two radios involved, both listen on the same addresses and pipe numbers in RX mode - radio.openReadingPipe(1,addresses[0]); // then switch pipes & addresses to transmit. - radio.startListening(); // Need to start listening after opening new reading pipes + if ( c == 'T' && role == role_pong_back ){ + Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); + role = role_ping_out; // Become the primary transmitter (ping out) + counter = 1; + }else + if ( c == 'R' && role == role_ping_out ){ + Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); + role = role_pong_back; // Become the primary receiver (pong back) + radio.startListening(); + counter = 1; + radio.writeAckPayload(1,&counter,1); + } } } diff --git a/examples/GettingStarted_HandlingData/GettingStarted_HandlingData.ino b/examples/GettingStarted_HandlingData/GettingStarted_HandlingData.ino new file mode 100644 index 000000000..26bb1784a --- /dev/null +++ b/examples/GettingStarted_HandlingData/GettingStarted_HandlingData.ino @@ -0,0 +1,163 @@ + +/* +* Getting Started example sketch for nRF24L01+ radios +* This is an example of how to send data from one node to another using data structures +* Updated: Dec 2014 by TMRh20 +*/ + +#include +#include "RF24.h" + +byte addresses[][6] = {"1Node","2Node"}; + + +/****************** User Config ***************************/ +/*** Set this radio as radio number 0 or 1 ***/ +bool radioNumber = 1; + +/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */ +RF24 radio(7,8); +/**********************************************************/ + + +// Used to control whether this node is sending or receiving +bool role = 0; + + +void setup() { + + Serial.begin(115200); + Serial.println(F("RF24/examples/GettingStarted")); + Serial.println(F("*** PRESS 'T' to begin transmitting to the other node")); + + radio.begin(); + + // Set the PA Level low to prevent power supply related issues since this is a + // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default. + radio.setPALevel(RF24_PA_LOW); + + // Open a writing and reading pipe on each radio, with opposite addresses + if(radioNumber){ + radio.openWritingPipe(addresses[1]); + radio.openReadingPipe(1,addresses[0]); + }else{ + radio.openWritingPipe(addresses[0]); + radio.openReadingPipe(1,addresses[1]); + } + + // Start the radio listening for data + radio.startListening(); +} + + + +/** +* Create a data structure for transmitting and receiving data +* This allows many variables to be easily sent and received in a single transmission +* See http://www.cplusplus.com/doc/tutorial/structures/ +*/ +struct dataStruct{ + unsigned long _micros; + float value = 1.22; +}myData; + + + +void loop() { + + +/****************** Ping Out Role ***************************/ +if (role == 1) { + + radio.stopListening(); // First, stop listening so we can talk. + + + Serial.println(F("Now sending")); + + myData._micros = micros(); + if (!radio.write( &myData, sizeof(myData) )){ + Serial.println(F("failed")); + } + + radio.startListening(); // Now, continue listening + + unsigned long started_waiting_at = micros(); // Set up a timeout period, get the current microseconds + boolean timeout = false; // Set up a variable to indicate if a response was received or not + + while ( ! radio.available() ){ // While nothing is received + if (micros() - started_waiting_at > 200000 ){ // If waited longer than 200ms, indicate timeout and exit while loop + timeout = true; + break; + } + } + + if ( timeout ){ // Describe the results + Serial.println(F("Failed, response timed out.")); + }else{ + // Grab the response, compare, and send to debugging spew + radio.read( &myData, sizeof(myData) ); + unsigned long time = micros(); + + // Spew it + Serial.print(F("Sent ")); + Serial.print(time); + Serial.print(F(", Got response ")); + Serial.print(myData._micros); + Serial.print(F(", Round-trip delay ")); + Serial.print(time-myData._micros); + Serial.print(F(" microseconds Value ")); + Serial.println(myData.value); + } + + // Try again 1s later + delay(1000); + } + + + +/****************** Pong Back Role ***************************/ + + if ( role == 0 ) + { + + if( radio.available()){ + // Variable for the received timestamp + while (radio.available()) { // While there is data ready + radio.read( &myData, sizeof(myData) ); // Get the payload + } + + radio.stopListening(); // First, stop listening so we can talk + myData.value += 0.01; // Increment the float value + radio.write( &myData, sizeof(myData) ); // Send the final one back. + radio.startListening(); // Now, resume listening so we catch the next packets. + Serial.print(F("Sent response ")); + Serial.print(myData._micros); + Serial.print(" : "); + Serial.println(myData.value); + } + } + + + + +/****************** Change Roles via Serial Commands ***************************/ + + if ( Serial.available() ) + { + char c = toupper(Serial.read()); + if ( c == 'T' && role == 0 ){ + Serial.print(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK")); + role = 1; // Become the primary transmitter (ping out) + + }else + if ( c == 'R' && role == 1 ){ + Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK")); + role = 0; // Become the primary receiver (pong back) + radio.startListening(); + + } + } + + +} // Loop + diff --git a/examples/pingpair_dyn/pingpair_dyn.ino b/examples/pingpair_dyn/pingpair_dyn.ino index 043c912d8..bd16b1ac2 100644 --- a/examples/pingpair_dyn/pingpair_dyn.ino +++ b/examples/pingpair_dyn/pingpair_dyn.ino @@ -15,7 +15,7 @@ #include #include "nRF24L01.h" #include "RF24.h" -#include "printf.h" +//#include // Printf is used for debug // // Hardware configuration @@ -87,10 +87,12 @@ void setup(void) // Print preamble // - Serial.begin(57600); - printf_begin(); - printf("\n\rRF24/examples/pingpair_dyn/\n\r"); - printf("ROLE: %s\n\r",role_friendly_name[role]); + Serial.begin(115200); + //printf_begin(); //Printf is used for debug + + Serial.println(F("RF24/examples/pingpair_dyn/")); + Serial.print(F("ROLE: ")); + Serial.println(role_friendly_name[role]); // // Setup and configure rf radio @@ -152,7 +154,8 @@ void loop(void) radio.stopListening(); // Take the time, and send it. This will block until complete - printf("Now sending length %i...",next_payload_size); + Serial.print(F("Now sending length ")); + Serial.println(next_payload_size); radio.write( send_payload, next_payload_size ); // Now, continue listening @@ -168,19 +171,28 @@ void loop(void) // Describe the results if ( timeout ) { - printf("Failed, response timed out.\n\r"); + Serial.println(F("Failed, response timed out.")); } else { // Grab the response, compare, and send to debugging spew uint8_t len = radio.getDynamicPayloadSize(); + + // If a corrupt dynamic payload is received, it will be flushed + if(!len){ + return; + } + radio.read( receive_payload, len ); // Put a zero at the end for easy printing receive_payload[len] = 0; // Spew it - printf("Got response size=%i value=%s\n\r",len,receive_payload); + Serial.print(F("Got response size=")); + Serial.print(len); + Serial.print(F(" value=")); + Serial.println(receive_payload); } // Update size for next time. @@ -199,30 +211,34 @@ void loop(void) if ( role == role_pong_back ) { // if there is data ready - if ( radio.available() ) + while ( radio.available() ) { - // Dump the payloads until we've gotten everything - uint8_t len; - bool done = false; - while (radio.available()) - { - // Fetch the payload, and see if this was the last one. - len = radio.getDynamicPayloadSize(); - radio.read( receive_payload, len ); - - // Put a zero at the end for easy printing - receive_payload[len] = 0; - - // Spew it - printf("Got payload size=%i value=%s\n\r",len,receive_payload); + + // Fetch the payload, and see if this was the last one. + uint8_t len = radio.getDynamicPayloadSize(); + + // If a corrupt dynamic payload is received, it will be flushed + if(!len){ + continue; } + + radio.read( receive_payload, len ); + + // Put a zero at the end for easy printing + receive_payload[len] = 0; + + // Spew it + Serial.print(F("Got response size=")); + Serial.print(len); + Serial.print(F(" value=")); + Serial.println(receive_payload); // First, stop listening so we can talk radio.stopListening(); // Send the final one back. radio.write( receive_payload, len ); - printf("Sent response.\n\r"); + Serial.println(F("Sent response.")); // Now, resume listening so we catch the next packets. radio.startListening(); diff --git a/examples/pingpair_irq/pingpair_irq.ino b/examples/pingpair_irq/pingpair_irq.ino index ba6b9864d..3f57e0bf4 100644 --- a/examples/pingpair_irq/pingpair_irq.ino +++ b/examples/pingpair_irq/pingpair_irq.ino @@ -21,8 +21,6 @@ #include "nRF24L01.h" #include "RF24.h" #include "printf.h" -#include -#include // Hardware configuration RF24 radio(7,8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8 @@ -30,7 +28,8 @@ RF24 radio(7,8); // Set up nRF24L01 radio on SPI bus pl const short role_pin = 5; // sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver // Leave open to be the 'ping' transmitter - const uint64_t address[2] = {0xABCDABCD71LL, 0x544d52687CLL}; // Radio pipe addresses for the 2 nodes to communicate. +// Demonstrates another method of setting up the addresses +byte address[][5] = { 0xCC,0xCE,0xCC,0xCE,0xCC , 0xCE,0xCC,0xCE,0xCC,0xCE}; // Role management @@ -42,9 +41,11 @@ typedef enum { role_sender = 1, role_receiver } role_e; // The v const char* role_friendly_name[] = { "invalid", "Sender", "Receiver"}; // The debug-friendly names of those roles role_e role; // The role of the current running sketch -boolean gotMsg = 0; // So we know when to go to sleep +static uint32_t message_count = 0; + /********************** Setup *********************/ + void setup(){ pinMode(role_pin, INPUT); // set up the role pin @@ -64,7 +65,9 @@ void setup(){ // Setup and configure rf radio radio.begin(); + //radio.setPALevel(RF24_PA_LOW); radio.enableAckPayload(); // We will be using the Ack Payload feature, so please enable it + radio.enableDynamicPayloads(); // Ack payloads are dynamic payloads // Open pipes to other node for communication if ( role == role_sender ) { // This simple sketch opens a pipe on a single address for these two nodes to radio.openWritingPipe(address[0]); // communicate back and forth. One listens on it, the other talks to it. @@ -73,13 +76,14 @@ void setup(){ radio.openWritingPipe(address[1]); radio.openReadingPipe(1,address[0]); radio.startListening(); + radio.writeAckPayload( 1, &message_count, sizeof(message_count) ); // Add an ack packet for the next time around. This is a simple + ++message_count; } - radio.printDetails(); // Dump the configuration of the rf unit for debugging + radio.printDetails(); // Dump the configuration of the rf unit for debugging delay(50); - attachInterrupt(0, check_radio, FALLING); // Attach interrupt handler to interrupt #0 (using pin 2) on BOTH the sender and receiver + attachInterrupt(0, check_radio, LOW); // Attach interrupt handler to interrupt #0 (using pin 2) on BOTH the sender and receiver } -static uint32_t message_count = 0; /********************** Main Loop *********************/ diff --git a/examples/pingpair_irq_simple/pingpair_irq_simple.ino b/examples/pingpair_irq_simple/pingpair_irq_simple.ino new file mode 100644 index 000000000..ecd95a48a --- /dev/null +++ b/examples/pingpair_irq_simple/pingpair_irq_simple.ino @@ -0,0 +1,119 @@ +/* + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + version 2 as published by the Free Software Foundation. + + Created Dec 2014 - TMRh20 + */ + +/** + * Example of using interrupts + * + * This is a very simple example of using two devices to communicate using interrupts. + * With multiple devices, each device would need to have a separate reading pipe + */ + +#include +#include "RF24.h" +#include + +// Hardware configuration +// Set up nRF24L01 radio on SPI bus plus pins 7 & 8 +RF24 radio(7,8); + +// Use the same address for both devices +uint8_t address[] = { "radio" }; + +// Simple messages to represent a 'ping' and 'pong' +uint8_t ping = 111; +uint8_t pong = 222; + +volatile uint32_t round_trip_timer = 0; + + +/********************** Setup *********************/ + +void setup(){ + + Serial.begin(115200); + Serial.println(F("Simple pingpair example")); + Serial.println(F("Send a 'T' via Serial to transmit a single 'ping' ")); + //printf_begin(); + + // Setup and configure rf radio + radio.begin(); + + // Use dynamic payloads to improve response time + radio.enableDynamicPayloads(); + radio.openWritingPipe(address); // communicate back and forth. One listens on it, the other talks to it. + radio.openReadingPipe(1,address); + radio.startListening(); + + //radio.printDetails(); // Dump the configuration of the rf unit for debugging + + attachInterrupt(0, check_radio, LOW); // Attach interrupt handler to interrupt #0 (using pin 2) on BOTH the sender and receiver +} + + + +/********************** Main Loop *********************/ +void loop() { + + if(Serial.available()){ + switch(toupper(Serial.read())){ + case 'T': + // Only allow 1 transmission per 45ms to prevent overlapping IRQ/reads/writes + // Default retries = 5,15 = ~20ms per transmission max + while(micros() - round_trip_timer < 45000){ + //delay between writes + } + Serial.println(F("Sending ping")); + radio.stopListening(); + round_trip_timer = micros(); + radio.startWrite( &ping, sizeof(uint8_t),0 ); + break; + } + } +} + +/********************** Interrupt *********************/ + +void check_radio(void) // Receiver role: Does nothing! All the work is in IRQ +{ + + bool tx,fail,rx; + radio.whatHappened(tx,fail,rx); // What happened? + + + // If data is available, handle it accordingly + if ( rx ){ + + if(radio.getDynamicPayloadSize() < 1){ + // Corrupt payload has been flushed + return; + } + // Read in the data + uint8_t received; + radio.read(&received,sizeof(received)); + + // If this is a ping, send back a pong + if(received == ping){ + radio.stopListening(); + // Can be important to flush the TX FIFO here if using 250KBPS data rate + //radio.flush_tx(); + radio.startWrite(&pong,sizeof(pong),0); + }else + // If this is a pong, get the current micros() + if(received == pong){ + round_trip_timer = micros() - round_trip_timer; + Serial.print(F("Received Pong, Round Trip Time: ")); + Serial.println(round_trip_timer); + } + } + + // Start listening if transmission is complete + if( tx || fail ){ + radio.startListening(); + Serial.println(tx ? F("Send:OK") : F("Send:Fail")); + } +} diff --git a/examples_RPi/gettingstarted.cpp b/examples_RPi/gettingstarted.cpp index 0d85f3424..a3b31c98c 100644 --- a/examples_RPi/gettingstarted.cpp +++ b/examples_RPi/gettingstarted.cpp @@ -28,26 +28,30 @@ TMRh20 2014 - Updated to work with optimized RF24 Arduino library using namespace std; // // Hardware configuration -// +// Configure the appropriate pins for your connections -// CE Pin, CSN Pin, SPI Speed +// Radio CE Pin, CSN Pin, SPI Speed // Setup for GPIO 22 CE and CE1 CSN with SPI Speed @ 1Mhz //RF24 radio(RPI_V2_GPIO_P1_22, RPI_V2_GPIO_P1_26, BCM2835_SPI_SPEED_1MHZ); // Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 4Mhz -//RF24 radio(RPI_V2_GPIO_P1_15, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ); +//RF24 radio(RPI_V2_GPIO_P1_22, BCM2835_SPI_CS0, BCM2835_SPI_SPEED_4MHZ); // NEW: Setup for RPi B+ //RF24 radio(RPI_BPLUS_GPIO_J8_15,RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ); -// Setup for GPIO 22 CE and CE0 CSN with SPI Speed @ 8Mhz +// Setup for GPIO 15 CE and CE0 CSN with SPI Speed @ 8Mhz RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ); +/********** User Config *********/ +// Assign a unique identifier for this node, 0 or 1 +bool radioNumber = 1; + +/********************************/ // Radio pipe addresses for the 2 nodes to communicate. const uint8_t pipes[][6] = {"1Node","2Node"}; -//const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; int main(int argc, char** argv){ @@ -55,8 +59,7 @@ int main(int argc, char** argv){ bool role_ping_out = true, role_pong_back = false; bool role = role_pong_back; - // Print preamble: - printf("RF24/examples/pingtest/\n"); + printf("RF24/examples/GettingStarted/\n"); // Setup and configure rf radio radio.begin(); @@ -87,16 +90,16 @@ int main(int argc, char** argv){ // This simple sketch opens two pipes for these two nodes to communicate // back and forth. - if ( role == role_ping_out ) { + if ( !radioNumber ) { radio.openWritingPipe(pipes[0]); radio.openReadingPipe(1,pipes[1]); } else { radio.openWritingPipe(pipes[1]); radio.openReadingPipe(1,pipes[0]); - radio.startListening(); - } + radio.startListening(); + // forever loop while (1) { @@ -141,12 +144,7 @@ int main(int argc, char** argv){ // Spew it printf("Got response %lu, round-trip delay: %lu\n",got_time,millis()-got_time); } - - // Try again 1s later - // delay(1000); - sleep(1); - } // @@ -157,14 +155,11 @@ int main(int argc, char** argv){ { // if there is data ready - //printf("Check available...\n"); - if ( radio.available() ) { // Dump the payloads until we've gotten everything unsigned long got_time; - // Fetch the payload, and see if this was the last one. while(radio.available()){ radio.read( &got_time, sizeof(unsigned long) ); diff --git a/examples_RPi/gettingstarted_call_response.cpp b/examples_RPi/gettingstarted_call_response.cpp index dc42780ff..15e28cc7c 100644 --- a/examples_RPi/gettingstarted_call_response.cpp +++ b/examples_RPi/gettingstarted_call_response.cpp @@ -23,7 +23,7 @@ using namespace std; // // Hardware configuration -// +// Configure the appropriate pins for your connections // CE Pin, CSN Pin, SPI Speed @@ -39,12 +39,17 @@ using namespace std; // Setup for GPIO 15 CE and CE0 CSN with SPI Speed @ 8Mhz RF24 radio(RPI_V2_GPIO_P1_15, RPI_V2_GPIO_P1_24, BCM2835_SPI_SPEED_8MHZ); +/********** User Config *********/ +// Assign a unique identifier for this node, 0 or 1. Arduino example uses radioNumber 0 by default. +bool radioNumber = 1; + +/********************************/ + // Radio pipe addresses for the 2 nodes to communicate. const uint8_t addresses[][6] = {"1Node","2Node"}; bool role_ping_out = 1, role_pong_back = 0, role = 0; - uint8_t counter = 1; // A single byte to keep track of the data being sent back and forth @@ -53,10 +58,8 @@ int main(int argc, char** argv){ printf("RPi/RF24/examples/gettingstarted_call_response\n"); radio.begin(); - radio.setAutoAck(1); // Ensure autoACK is enabled radio.enableAckPayload(); // Allow optional ack payloads - radio.setRetries(1,15); // Smallest time between retries, max no. of retries - radio.setPayloadSize(1); // Here we are sending 1-byte payloads to test the call-response speed + radio.enableDynamicAck(); radio.printDetails(); // Dump the configuration of the rf unit for debugging @@ -79,14 +82,15 @@ int main(int argc, char** argv){ /***********************************/ // This opens two pipes for these two nodes to communicate // back and forth. - if ( role == role_ping_out ) { + if ( !radioNumber ) { radio.openWritingPipe(addresses[0]); radio.openReadingPipe(1,addresses[1]); }else{ radio.openWritingPipe(addresses[1]); radio.openReadingPipe(1,addresses[0]); - radio.startListening(); } + radio.startListening(); + radio.writeAckPayload(1,&counter,1); // forever loop while (1){ @@ -116,7 +120,6 @@ while (1){ }else{ printf("Sending failed.\n\r"); } // If no ack response, sending failed sleep(1); // Try again later - //delay(250); } /****************** Pong Back Role ***************************/ @@ -124,12 +127,11 @@ while (1){ if ( role == role_pong_back ) { uint8_t pipeNo, gotByte; // Declare variables for the pipe and the byte received if( radio.available(&pipeNo)){ // Read all available payloads - radio.flush_tx(); // Clear any unused ACK payloads radio.read( &gotByte, 1 ); // Since this is a call-response. Respond directly with an ack payload. - // Ack payloads are much more efficient than switching to transmit mode to respond to a call + gotByte += 1; // Ack payloads are much more efficient than switching to transmit mode to respond to a call radio.writeAckPayload(pipeNo,&gotByte, 1 ); // This can be commented out to send empty payloads. - printf("Sent response %d \n\r", gotByte); + printf("Loaded next response %d \n\r", gotByte); delay(900); //Delay after a response to minimize CPU usage on RPi //Expects a payload every second } diff --git a/examples_RPi/pingpair_dyn.cpp b/examples_RPi/pingpair_dyn.cpp index a9eebff90..d3a2a48bb 100644 --- a/examples_RPi/pingpair_dyn.cpp +++ b/examples_RPi/pingpair_dyn.cpp @@ -18,7 +18,7 @@ using namespace std; // // Hardware configuration -// +// Configure the appropriate pins for your connections // CE Pin, CSN Pin, SPI Speed