Commit d05a3562 authored by TMRh20's avatar TMRh20

Update many of the example files

- Updated gettingStarted examples to demonstrate proper pipe/address
handling by assigning a unique id to each node
- Updated gettingstarted_call_response to demonstrate 'proper' use of
ack payloads
- Added gettingstarted_handling_data example
- Added pingpair_irq_simple to demonstrate bidirectional communication
via interrupts
- Updated standard pingpair_irq example
- Use Serial.println(F()); instead of printf
parent 350e00a0
/*
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
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 <SPI.h> #include <SPI.h>
#include "nRF24L01.h"
#include "RF24.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); RF24 radio(7,8);
/**********************************************************/
byte addresses[][6] = {"1Node","2Node"}; byte addresses[][6] = {"1Node","2Node"};
// Used to control whether this node is sending or receiving
// Set up roles to simplify testing bool role = 0;
boolean role; // The main role variable, holds the current role identifier
boolean role_ping_out = 1, role_pong_back = 0; // The two different roles.
void setup() { void setup() {
Serial.begin(57600); Serial.begin(57600);
printf_begin(); Serial.println(F("RF24/examples/GettingStarted"));
printf("\n\rRF24/examples/GettingStarted/\n\r"); Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
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]);
radio.startListening(); // Start listening radio.begin();
radio.printDetails(); // Dump the configuration of the rf unit for debugging
}
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 ***************************/ void loop() {
if (role == role_ping_out) {
/****************** Ping Out Role ***************************/
if (role == 1) {
radio.stopListening(); // First, stop listening so we can talk. 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 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 radio.startListening(); // Now, continue listening
...@@ -80,58 +74,69 @@ void loop(void){ ...@@ -80,58 +74,69 @@ void loop(void){
} }
if ( timeout ){ // Describe the results if ( timeout ){ // Describe the results
printf("Failed, response timed out.\n\r"); Serial.println(F("Failed, response timed out."));
}else{ }else{
unsigned long got_time; // Grab the response, compare, and send to debugging spew unsigned long got_time; // Grab the response, compare, and send to debugging spew
radio.read( &got_time, sizeof(unsigned long) ); radio.read( &got_time, sizeof(unsigned long) );
unsigned long time = micros();
// Spew it // 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 // Try again 1s later
delay(1000); delay(1000);
} }
/****************** Pong Back Role ***************************/ /****************** Pong Back Role ***************************/
if ( role == role_pong_back ) if ( role == 0 )
{ {
unsigned long got_time;
if( radio.available()){ 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 while (radio.available()) { // While there is data ready
radio.read( &got_time, sizeof(unsigned long) ); // Get the payload radio.read( &got_time, sizeof(unsigned long) ); // Get the payload
} }
radio.stopListening(); // First, stop listening so we can talk radio.stopListening(); // First, stop listening so we can talk
radio.write( &got_time, sizeof(unsigned long) ); // Send the final one back. radio.write( &got_time, sizeof(unsigned long) ); // Send the final one back.
radio.startListening(); // Now, resume listening so we catch the next packets. 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 ***************************/ /****************** Change Roles via Serial Commands ***************************/
if ( Serial.available() ) if ( Serial.available() )
{ {
char c = toupper(Serial.read()); char c = toupper(Serial.read());
if ( c == 'T' && role == role_pong_back ) if ( c == 'T' && role == 0 ){
{ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r"); role = 1; // Become the primary transmitter (ping out)
role = role_ping_out; // Become the primary transmitter (ping out) }else
radio.openWritingPipe(addresses[0]); if ( c == 'R' && role == 1 ){
radio.openReadingPipe(1,addresses[1]); Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
role = 0; // Become the primary receiver (pong back)
} radio.startListening();
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]);
} }
} }
}
} // Loop
/* /*
March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork Dec 2014 - TMRh20 - Updated
Parts derived from examples by J. Coliz <maniacbug@ymail.com> Derived from examples by J. Coliz <maniacbug@ymail.com>
*/ */
/** /**
* Example for efficient call-response using ack-payloads * Example for efficient call-response using ack-payloads
...@@ -13,12 +13,16 @@ ...@@ -13,12 +13,16 @@
*/ */
#include <SPI.h> #include <SPI.h>
#include "nRF24L01.h"
#include "RF24.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); RF24 radio(7,8);
/**********************************************************/
// Topology // Topology
byte addresses[][6] = {"1Node","2Node"}; // Radio pipe addresses for the 2 nodes to communicate. byte addresses[][6] = {"1Node","2Node"}; // Radio pipe addresses for the 2 nodes to communicate.
...@@ -33,24 +37,28 @@ byte counter = 1; // A ...@@ -33,24 +37,28 @@ byte counter = 1; // A
void setup(){ void setup(){
Serial.begin(57600); Serial.begin(115200);
printf_begin(); Serial.println(F("RF24/examples/GettingStarted_CallResponse"));
printf("\n\rRF24/examples/GettingStarted/\n\r"); Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
printf("ROLE: %s\n\r",role_friendly_name[role]); //printf_begin();
printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
// Setup and configure radio // Setup and configure radio
radio.begin(); radio.begin();
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.enableAckPayload(); // Allow optional ack payloads radio.enableAckPayload(); // Allow optional ack payloads
radio.setRetries(0,15); // Smallest time between retries, max no. of retries radio.enableDynamicAck();
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 if(radioNumber){
radio.openReadingPipe(1,addresses[0]); // Open a reading pipe on address 0, pipe 1 radio.openWritingPipe(addresses[1]); // Both radios listen on the same pipes by default, but opposite addresses
radio.startListening(); // Start listening radio.openReadingPipe(1,addresses[0]); // Open a reading pipe on address 0, pipe 1
radio.powerUp(); }else{
radio.printDetails(); // Dump the configuration of the rf unit for debugging 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) { void loop(void) {
...@@ -63,21 +71,31 @@ void loop(void) { ...@@ -63,21 +71,31 @@ void loop(void) {
byte gotByte; // Initialize a variable for the incoming response byte gotByte; // Initialize a variable for the incoming response
radio.stopListening(); // First, stop listening so we can talk. 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 unsigned long time = micros(); // Record the current microsecond count
if ( radio.write(&counter,1) ){ // Send the counter variable to the other radio 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 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{ }else{
while(radio.available() ){ // If an ack with payload was received while(radio.available() ){ // If an ack with payload was received
radio.read( &gotByte, 1 ); // Read it, and display the response time 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 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 delay(1000); // Try again later
} }
...@@ -90,9 +108,10 @@ void loop(void) { ...@@ -90,9 +108,10 @@ void loop(void) {
while( radio.available(&pipeNo)){ // Read all available payloads while( radio.available(&pipeNo)){ // Read all available payloads
radio.read( &gotByte, 1 ); radio.read( &gotByte, 1 );
// Since this is a call-response. Respond directly with an ack payload. // 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. 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) { ...@@ -103,22 +122,18 @@ void loop(void) {
if ( Serial.available() ) if ( Serial.available() )
{ {
char c = toupper(Serial.read()); char c = toupper(Serial.read());
if ( c == 'T' && role == role_pong_back ) if ( c == 'T' && role == role_pong_back ){
{ Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r"); role = role_ping_out; // Become the primary transmitter (ping out)
counter = 1;
role = role_ping_out; // Change roles (ping out) }else
radio.openWritingPipe(addresses[0]); // Open different pipes when writing. Write on pipe 0, address 0 if ( c == 'R' && role == role_ping_out ){
radio.openReadingPipe(1,addresses[1]); // Read on pipe 1, as address 1 Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
} role = role_pong_back; // Become the primary receiver (pong back)
else if ( c == 'R' && role == role_ping_out ) radio.startListening();
{ counter = 1;
printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r"); radio.writeAckPayload(1,&counter,1);
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
} }
} }
} }
/*
* 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 <SPI.h>
#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
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
#include <SPI.h> #include <SPI.h>
#include "nRF24L01.h" #include "nRF24L01.h"
#include "RF24.h" #include "RF24.h"
#include "printf.h" //#include <printf.h> // Printf is used for debug
// //
// Hardware configuration // Hardware configuration
...@@ -87,10 +87,12 @@ void setup(void) ...@@ -87,10 +87,12 @@ void setup(void)
// Print preamble // Print preamble
// //
Serial.begin(57600); Serial.begin(115200);
printf_begin(); //printf_begin(); //Printf is used for debug
printf("\n\rRF24/examples/pingpair_dyn/\n\r");
printf("ROLE: %s\n\r",role_friendly_name[role]); Serial.println(F("RF24/examples/pingpair_dyn/"));
Serial.print(F("ROLE: "));
Serial.println(role_friendly_name[role]);
// //
// Setup and configure rf radio // Setup and configure rf radio
...@@ -152,7 +154,8 @@ void loop(void) ...@@ -152,7 +154,8 @@ void loop(void)
radio.stopListening(); radio.stopListening();
// Take the time, and send it. This will block until complete // 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 ); radio.write( send_payload, next_payload_size );
// Now, continue listening // Now, continue listening
...@@ -168,19 +171,28 @@ void loop(void) ...@@ -168,19 +171,28 @@ void loop(void)
// Describe the results // Describe the results
if ( timeout ) if ( timeout )
{ {
printf("Failed, response timed out.\n\r"); Serial.println(F("Failed, response timed out."));
} }
else else
{ {
// Grab the response, compare, and send to debugging spew // Grab the response, compare, and send to debugging spew
uint8_t len = radio.getDynamicPayloadSize(); uint8_t len = radio.getDynamicPayloadSize();
// If a corrupt dynamic payload is received, it will be flushed
if(!len){
return;
}
radio.read( receive_payload, len ); radio.read( receive_payload, len );
// Put a zero at the end for easy printing // Put a zero at the end for easy printing
receive_payload[len] = 0; receive_payload[len] = 0;
// Spew it // 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. // Update size for next time.
...@@ -199,30 +211,34 @@ void loop(void) ...@@ -199,30 +211,34 @@ void loop(void)
if ( role == role_pong_back ) if ( role == role_pong_back )
{ {
// if there is data ready // if there is data ready
if ( radio.available() ) while ( radio.available() )
{ {
// Dump the payloads until we've gotten everything
uint8_t len; // Fetch the payload, and see if this was the last one.
bool done = false; uint8_t len = radio.getDynamicPayloadSize();
while (radio.available())
{ // If a corrupt dynamic payload is received, it will be flushed
// Fetch the payload, and see if this was the last one. if(!len){
len = radio.getDynamicPayloadSize(); continue;
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);
} }
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 // First, stop listening so we can talk
radio.stopListening(); radio.stopListening();
// Send the final one back. // Send the final one back.
radio.write( receive_payload, len ); radio.write( receive_payload, len );
printf("Sent response.\n\r"); Serial.println(F("Sent response."));
// Now, resume listening so we catch the next packets. // Now, resume listening so we catch the next packets.
radio.startListening(); radio.startListening();
......
...@@ -21,8 +21,6 @@ ...@@ -21,8 +21,6 @@
#include "nRF24L01.h" #include "nRF24L01.h"
#include "RF24.h" #include "RF24.h"
#include "printf.h" #include "printf.h"
#include <avr/sleep.h>
#include <avr/power.h>
// Hardware configuration // Hardware configuration
RF24 radio(7,8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8 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 ...@@ -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 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 // 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 // Role management
...@@ -42,9 +41,11 @@ typedef enum { role_sender = 1, role_receiver } role_e; // The v ...@@ -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 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 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 *********************/ /********************** Setup *********************/
void setup(){ void setup(){
pinMode(role_pin, INPUT); // set up the role pin pinMode(role_pin, INPUT); // set up the role pin
...@@ -64,7 +65,9 @@ void setup(){ ...@@ -64,7 +65,9 @@ void setup(){
// Setup and configure rf radio // Setup and configure rf radio
radio.begin(); radio.begin();
//radio.setPALevel(RF24_PA_LOW);
radio.enableAckPayload(); // We will be using the Ack Payload feature, so please enable it 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 // 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 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. radio.openWritingPipe(address[0]); // communicate back and forth. One listens on it, the other talks to it.
...@@ -73,13 +76,14 @@ void setup(){ ...@@ -73,13 +76,14 @@ void setup(){
radio.openWritingPipe(address[1]); radio.openWritingPipe(address[1]);
radio.openReadingPipe(1,address[0]); radio.openReadingPipe(1,address[0]);
radio.startListening(); 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); 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 *********************/ /********************** Main Loop *********************/
......
/*
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 <SPI.h>
#include "RF24.h"
#include <printf.h>
// 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"));
}
}
...@@ -28,26 +28,30 @@ TMRh20 2014 - Updated to work with optimized RF24 Arduino library ...@@ -28,26 +28,30 @@ TMRh20 2014 - Updated to work with optimized RF24 Arduino library
using namespace std; using namespace std;
// //
// Hardware configuration // 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 // 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); //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 // 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+ // NEW: Setup for RPi B+
//RF24 radio(RPI_BPLUS_GPIO_J8_15,RPI_BPLUS_GPIO_J8_24, BCM2835_SPI_SPEED_8MHZ); //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); 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. // Radio pipe addresses for the 2 nodes to communicate.
const uint8_t pipes[][6] = {"1Node","2Node"}; const uint8_t pipes[][6] = {"1Node","2Node"};
//const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL };
int main(int argc, char** argv){ int main(int argc, char** argv){
...@@ -55,8 +59,7 @@ 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_ping_out = true, role_pong_back = false;
bool role = role_pong_back; bool role = role_pong_back;
// Print preamble: printf("RF24/examples/GettingStarted/\n");
printf("RF24/examples/pingtest/\n");
// Setup and configure rf radio // Setup and configure rf radio
radio.begin(); radio.begin();
...@@ -87,16 +90,16 @@ int main(int argc, char** argv){ ...@@ -87,16 +90,16 @@ int main(int argc, char** argv){
// This simple sketch opens two pipes for these two nodes to communicate // This simple sketch opens two pipes for these two nodes to communicate
// back and forth. // back and forth.
if ( role == role_ping_out ) { if ( !radioNumber ) {
radio.openWritingPipe(pipes[0]); radio.openWritingPipe(pipes[0]);
radio.openReadingPipe(1,pipes[1]); radio.openReadingPipe(1,pipes[1]);
} else { } else {
radio.openWritingPipe(pipes[1]); radio.openWritingPipe(pipes[1]);
radio.openReadingPipe(1,pipes[0]); radio.openReadingPipe(1,pipes[0]);
radio.startListening();
} }
radio.startListening();
// forever loop // forever loop
while (1) while (1)
{ {
...@@ -141,12 +144,7 @@ int main(int argc, char** argv){ ...@@ -141,12 +144,7 @@ int main(int argc, char** argv){
// Spew it // Spew it
printf("Got response %lu, round-trip delay: %lu\n",got_time,millis()-got_time); printf("Got response %lu, round-trip delay: %lu\n",got_time,millis()-got_time);
} }
// Try again 1s later
// delay(1000);
sleep(1); sleep(1);
} }
// //
...@@ -157,14 +155,11 @@ int main(int argc, char** argv){ ...@@ -157,14 +155,11 @@ int main(int argc, char** argv){
{ {
// if there is data ready // if there is data ready
//printf("Check available...\n");
if ( radio.available() ) if ( radio.available() )
{ {
// Dump the payloads until we've gotten everything // Dump the payloads until we've gotten everything
unsigned long got_time; unsigned long got_time;
// Fetch the payload, and see if this was the last one. // Fetch the payload, and see if this was the last one.
while(radio.available()){ while(radio.available()){
radio.read( &got_time, sizeof(unsigned long) ); radio.read( &got_time, sizeof(unsigned long) );
......
...@@ -23,7 +23,7 @@ using namespace std; ...@@ -23,7 +23,7 @@ using namespace std;
// //
// Hardware configuration // Hardware configuration
// // Configure the appropriate pins for your connections
// CE Pin, CSN Pin, SPI Speed // CE Pin, CSN Pin, SPI Speed
...@@ -39,12 +39,17 @@ using namespace std; ...@@ -39,12 +39,17 @@ using namespace std;
// Setup for GPIO 15 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); 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. // Radio pipe addresses for the 2 nodes to communicate.
const uint8_t addresses[][6] = {"1Node","2Node"}; const uint8_t addresses[][6] = {"1Node","2Node"};
bool role_ping_out = 1, role_pong_back = 0, role = 0; 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 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){ ...@@ -53,10 +58,8 @@ int main(int argc, char** argv){
printf("RPi/RF24/examples/gettingstarted_call_response\n"); printf("RPi/RF24/examples/gettingstarted_call_response\n");
radio.begin(); radio.begin();
radio.setAutoAck(1); // Ensure autoACK is enabled
radio.enableAckPayload(); // Allow optional ack payloads radio.enableAckPayload(); // Allow optional ack payloads
radio.setRetries(1,15); // Smallest time between retries, max no. of retries radio.enableDynamicAck();
radio.setPayloadSize(1); // Here we are sending 1-byte payloads to test the call-response speed
radio.printDetails(); // Dump the configuration of the rf unit for debugging radio.printDetails(); // Dump the configuration of the rf unit for debugging
...@@ -79,14 +82,15 @@ int main(int argc, char** argv){ ...@@ -79,14 +82,15 @@ int main(int argc, char** argv){
/***********************************/ /***********************************/
// This opens two pipes for these two nodes to communicate // This opens two pipes for these two nodes to communicate
// back and forth. // back and forth.
if ( role == role_ping_out ) { if ( !radioNumber ) {
radio.openWritingPipe(addresses[0]); radio.openWritingPipe(addresses[0]);
radio.openReadingPipe(1,addresses[1]); radio.openReadingPipe(1,addresses[1]);
}else{ }else{
radio.openWritingPipe(addresses[1]); radio.openWritingPipe(addresses[1]);
radio.openReadingPipe(1,addresses[0]); radio.openReadingPipe(1,addresses[0]);
radio.startListening();
} }
radio.startListening();
radio.writeAckPayload(1,&counter,1);
// forever loop // forever loop
while (1){ while (1){
...@@ -116,7 +120,6 @@ while (1){ ...@@ -116,7 +120,6 @@ while (1){
}else{ printf("Sending failed.\n\r"); } // If no ack response, sending failed }else{ printf("Sending failed.\n\r"); } // If no ack response, sending failed
sleep(1); // Try again later sleep(1); // Try again later
//delay(250);
} }
/****************** Pong Back Role ***************************/ /****************** Pong Back Role ***************************/
...@@ -124,12 +127,11 @@ while (1){ ...@@ -124,12 +127,11 @@ while (1){
if ( role == role_pong_back ) { if ( role == role_pong_back ) {
uint8_t pipeNo, gotByte; // Declare variables for the pipe and the byte received uint8_t pipeNo, gotByte; // Declare variables for the pipe and the byte received
if( radio.available(&pipeNo)){ // Read all available payloads if( radio.available(&pipeNo)){ // Read all available payloads
radio.flush_tx(); // Clear any unused ACK payloads
radio.read( &gotByte, 1 ); radio.read( &gotByte, 1 );
// Since this is a call-response. Respond directly with an ack payload. // 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. 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 delay(900); //Delay after a response to minimize CPU usage on RPi
//Expects a payload every second //Expects a payload every second
} }
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
using namespace std; using namespace std;
// //
// Hardware configuration // Hardware configuration
// // Configure the appropriate pins for your connections
// CE Pin, CSN Pin, SPI Speed // CE Pin, CSN Pin, SPI Speed
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment