初始化提交
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
|
||||
/*
|
||||
* 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 "RF24.h"
|
||||
|
||||
/****************** 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"};
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
|
||||
/****************** Ping Out Role ***************************/
|
||||
if (role == 1) {
|
||||
|
||||
radio.stopListening(); // First, stop listening so we can talk.
|
||||
|
||||
|
||||
Serial.println(F("Now sending"));
|
||||
|
||||
unsigned long start_time = micros(); // Take the time, and send it. This will block until complete
|
||||
if (!radio.write( &start_time, sizeof(unsigned long) )){
|
||||
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{
|
||||
unsigned long got_time; // Grab the response, compare, and send to debugging spew
|
||||
radio.read( &got_time, sizeof(unsigned long) );
|
||||
unsigned long end_time = micros();
|
||||
|
||||
// Spew it
|
||||
Serial.print(F("Sent "));
|
||||
Serial.print(start_time);
|
||||
Serial.print(F(", Got response "));
|
||||
Serial.print(got_time);
|
||||
Serial.print(F(", Round-trip delay "));
|
||||
Serial.print(end_time-start_time);
|
||||
Serial.println(F(" microseconds"));
|
||||
}
|
||||
|
||||
// Try again 1s later
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************** Pong Back Role ***************************/
|
||||
|
||||
if ( role == 0 )
|
||||
{
|
||||
unsigned long got_time;
|
||||
|
||||
if( radio.available()){
|
||||
// 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.
|
||||
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 == 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
|
||||
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Dec 2014 - TMRh20 - Updated
|
||||
Derived from examples by J. Coliz <maniacbug@ymail.com>
|
||||
*/
|
||||
/**
|
||||
* Example for efficient call-response using ack-payloads
|
||||
*
|
||||
* This example continues to make use of all the normal functionality of the radios including
|
||||
* the auto-ack and auto-retry features, but allows ack-payloads to be written optionlly as well.
|
||||
* This allows very fast call-response communication, with the responding radio never having to
|
||||
* switch out of Primary Receiver mode to send back a payload, but having the option to switch to
|
||||
* primary transmitter if wanting to initiate communication instead of respond to a commmunication.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "RF24.h"
|
||||
|
||||
// You must include printf and run printf_begin() if you wish to use radio.printDetails();
|
||||
//#include "printf.h"
|
||||
|
||||
/****************** 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.
|
||||
|
||||
// Role management: Set up role. This sketch uses the same software for all the nodes
|
||||
// in this system. Doing so greatly simplifies testing.
|
||||
typedef enum { role_ping_out = 1, role_pong_back } role_e; // The various roles supported by this sketch
|
||||
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; // The debug-friendly names of those roles
|
||||
role_e role = role_pong_back; // The role of the current running sketch
|
||||
|
||||
byte counter = 1; // A single byte to keep track of the data being sent back and forth
|
||||
|
||||
|
||||
void setup(){
|
||||
|
||||
Serial.begin(115200);
|
||||
// printf_begin(); // This is for initializing printf that is used by printDetails()
|
||||
Serial.println(F("RF24/examples/GettingStarted_CallResponse"));
|
||||
Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
|
||||
|
||||
// Setup and configure radio
|
||||
|
||||
radio.begin();
|
||||
|
||||
radio.enableAckPayload(); // Allow optional ack payloads
|
||||
radio.enableDynamicPayloads(); // Ack payloads are dynamic payloads
|
||||
|
||||
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) {
|
||||
|
||||
|
||||
/****************** Ping Out Role ***************************/
|
||||
|
||||
if (role == role_ping_out){ // Radio is in ping mode
|
||||
|
||||
byte gotByte; // Initialize a variable for the incoming response
|
||||
|
||||
radio.stopListening(); // First, stop listening so we can talk.
|
||||
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
|
||||
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
|
||||
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{ Serial.println(F("Sending failed.")); } // If no ack response, sending failed
|
||||
|
||||
delay(1000); // Try again later
|
||||
}
|
||||
|
||||
|
||||
/****************** Pong Back Role ***************************/
|
||||
|
||||
if ( role == role_pong_back ) {
|
||||
byte pipeNo, gotByte; // Declare variables for the pipe and the byte received
|
||||
while( radio.available(&pipeNo)){ // Read all available payloads
|
||||
radio.read( &gotByte, 1 );
|
||||
// Since this is a call-response. Respond directly with an ack payload.
|
||||
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.
|
||||
Serial.print(F("Loaded next response "));
|
||||
Serial.println(gotByte);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************** Change Roles via Serial Commands ***************************/
|
||||
|
||||
if ( Serial.available() )
|
||||
{
|
||||
char c = toupper(Serial.read());
|
||||
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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,161 @@
|
||||
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}myData;
|
||||
|
||||
void setup() {
|
||||
|
||||
Serial.begin(115200);
|
||||
Serial.println(F("RF24/examples/GettingStarted_HandlingData"));
|
||||
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]);
|
||||
}
|
||||
|
||||
myData.value = 1.22;
|
||||
// Start the radio listening for data
|
||||
radio.startListening();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
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(F(" : "));
|
||||
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
|
||||
@@ -0,0 +1,218 @@
|
||||
|
||||
/*
|
||||
* Getting Started example sketch for nRF24L01+ radios
|
||||
* This is a very basic example of how to send data from one node to another
|
||||
* but modified to include failure handling.
|
||||
*
|
||||
* The nrf24l01+ radios are fairly reliable devices, but on breadboards etc, with inconsistent wiring, failures may
|
||||
* occur randomly after many hours to days or weeks. This sketch demonstrates how to handle the various failures and
|
||||
* keep the radio operational.
|
||||
*
|
||||
* The three main failure modes of the radio include:
|
||||
* Writing to radio: Radio unresponsive - Fixed internally by adding a timeout to the internal write functions in RF24 (failure handling)
|
||||
* Reading from radio: Available returns true always - Fixed by adding a timeout to available functions by the user. This is implemented internally in RF24Network.
|
||||
* Radio configuration settings are lost - Fixed by monitoring a value that is different from the default, and re-configuring the radio if this setting reverts to the default.
|
||||
*
|
||||
* The printDetails output should appear as follows for radio #0:
|
||||
*
|
||||
* STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
|
||||
* RX_ADDR_P0-1 = 0x65646f4e31 0x65646f4e32
|
||||
* RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
|
||||
* TX_ADDR = 0x65646f4e31
|
||||
* RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
|
||||
* EN_AA = 0x3f
|
||||
* EN_RXADDR = 0x02
|
||||
* RF_CH = 0x4c
|
||||
* RF_SETUP = 0x03
|
||||
* CONFIG = 0x0f
|
||||
* DYNPD/FEATURE = 0x00 0x00
|
||||
* Data Rate = 1MBPS
|
||||
* Model = nRF24L01+
|
||||
* CRC Length = 16 bits
|
||||
* PA Power = PA_LOW
|
||||
*
|
||||
*Users can use this sketch to troubleshoot radio module wiring etc. as it makes the radios hot-swapable
|
||||
*
|
||||
* Updated: 2019 by TMRh20
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
/****************** 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"};
|
||||
|
||||
// Used to control whether this node is sending or receiving
|
||||
bool role = 0;
|
||||
|
||||
/**********************************************************/
|
||||
//Function to configure the radio
|
||||
void configureRadio(){
|
||||
|
||||
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();
|
||||
radio.printDetails();
|
||||
}
|
||||
|
||||
/**********************************************************/
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
Serial.println(F("RF24/examples/GettingStarted"));
|
||||
Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
|
||||
|
||||
printf_begin();
|
||||
|
||||
configureRadio();
|
||||
}
|
||||
|
||||
uint32_t configTimer = millis();
|
||||
|
||||
void loop() {
|
||||
|
||||
if(radio.failureDetected){
|
||||
radio.failureDetected = false;
|
||||
delay(250);
|
||||
Serial.println("Radio failure detected, restarting radio");
|
||||
configureRadio();
|
||||
}
|
||||
//Every 5 seconds, verify the configuration of the radio. This can be done using any
|
||||
//setting that is different from the radio defaults.
|
||||
if(millis() - configTimer > 5000){
|
||||
configTimer = millis();
|
||||
if(radio.getDataRate() != RF24_1MBPS){
|
||||
radio.failureDetected = true;
|
||||
Serial.print("Radio configuration error detected");
|
||||
}
|
||||
}
|
||||
|
||||
/****************** Ping Out Role ***************************/
|
||||
if (role == 1) {
|
||||
|
||||
radio.stopListening(); // First, stop listening so we can talk.
|
||||
|
||||
|
||||
Serial.println(F("Now sending"));
|
||||
|
||||
unsigned long start_time = micros(); // Take the time, and send it. This will block until complete
|
||||
if (!radio.write( &start_time, sizeof(unsigned long) )){
|
||||
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{
|
||||
unsigned long got_time; // Grab the response, compare, and send to debugging spew
|
||||
|
||||
//Failure Handling:
|
||||
uint32_t failTimer = millis();
|
||||
while(radio.available()){ //If available always returns true, there is a problem
|
||||
if(millis() - failTimer > 250){
|
||||
radio.failureDetected = true;
|
||||
Serial.println("Radio available failure detected");
|
||||
break;
|
||||
}
|
||||
radio.read( &got_time, sizeof(unsigned long) );
|
||||
}
|
||||
unsigned long end_time = micros();
|
||||
|
||||
// Spew it
|
||||
Serial.print(F("Sent "));
|
||||
Serial.print(start_time);
|
||||
Serial.print(F(", Got response "));
|
||||
Serial.print(got_time);
|
||||
Serial.print(F(", Round-trip delay "));
|
||||
Serial.print(end_time-start_time);
|
||||
Serial.println(F(" microseconds"));
|
||||
}
|
||||
|
||||
// Try again 1s later
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************** Pong Back Role ***************************/
|
||||
|
||||
if ( role == 0 )
|
||||
{
|
||||
unsigned long got_time;
|
||||
|
||||
if( radio.available()){
|
||||
|
||||
uint32_t failTimer = millis(); // Variable for the received timestamp
|
||||
while (radio.available()) { // While there is data ready
|
||||
if(millis()-failTimer > 500){
|
||||
Serial.println("Radio available failure detected");
|
||||
radio.failureDetected = true;
|
||||
break;
|
||||
}
|
||||
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.
|
||||
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 == 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
|
||||
146
arduino-cli/libraries/RF24/examples/Transfer/Transfer.ino
Normal file
146
arduino-cli/libraries/RF24/examples/Transfer/Transfer.ino
Normal file
@@ -0,0 +1,146 @@
|
||||
/*
|
||||
TMRh20 2014
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/*
|
||||
General Data Transfer Rate Test
|
||||
|
||||
This example demonstrates basic data transfer functionality with the
|
||||
updated library. This example will display the transfer rates acheived
|
||||
using the slower form of high-speed transfer using blocking-writes.
|
||||
*/
|
||||
|
||||
|
||||
#include <SPI.h>
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
/************* USER Configuration *****************************/
|
||||
// Hardware configuration
|
||||
RF24 radio(7, 8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate.
|
||||
|
||||
byte data[32]; //Data buffer for testing data transfer speeds
|
||||
|
||||
unsigned long counter, rxTimer; //Counter and timer for keeping track transfer info
|
||||
unsigned long startTime, stopTime;
|
||||
bool TX = 1, RX = 0, role = 0;
|
||||
|
||||
void setup(void) {
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
|
||||
radio.begin(); // Setup and configure rf radio
|
||||
radio.setChannel(1);
|
||||
radio.setPALevel(RF24_PA_LOW); // If you want to save power use "RF24_PA_MIN" but keep in mind that reduces the module's range
|
||||
radio.setDataRate(RF24_2MBPS);
|
||||
radio.setAutoAck(1); // Ensure autoACK is enabled
|
||||
radio.setRetries(2, 15); // Optionally, increase the delay between retries & # of retries
|
||||
|
||||
radio.setCRCLength(RF24_CRC_8); // Use 8-bit CRC for performance
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1, pipes[1]);
|
||||
|
||||
radio.startListening(); // Start listening
|
||||
radio.printDetails(); // Dump the configuration of the rf unit for debugging
|
||||
|
||||
Serial.println(F("\n\rRF24/examples/Transfer/"));
|
||||
Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
|
||||
|
||||
randomSeed(analogRead(0)); //Seed for random number generation
|
||||
|
||||
for (int i = 0; i < 32; i++) {
|
||||
data[i] = random(255); //Load the buffer with random data
|
||||
}
|
||||
radio.powerUp(); //Power up the radio
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
if (role == TX) {
|
||||
delay(2000);
|
||||
|
||||
Serial.println(F("Initiating Basic Data Transfer"));
|
||||
|
||||
unsigned long cycles = 10000; //Change this to a higher or lower number.
|
||||
|
||||
startTime = millis();
|
||||
unsigned long pauseTime = millis();
|
||||
|
||||
for (int i = 0; i < cycles; i++) { //Loop through a number of cycles
|
||||
data[0] = i; //Change the first byte of the payload for identification
|
||||
if (!radio.writeFast(&data, 32)) { //Write to the FIFO buffers
|
||||
counter++; //Keep count of failed payloads
|
||||
}
|
||||
|
||||
//This is only required when NO ACK ( enableAutoAck(0) ) payloads are used
|
||||
// if(millis() - pauseTime > 3){
|
||||
// pauseTime = millis();
|
||||
// radio.txStandBy(); // Need to drop out of TX mode every 4ms if sending a steady stream of multicast data
|
||||
// //delayMicroseconds(130); // This gives the PLL time to sync back up
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
stopTime = millis();
|
||||
//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
|
||||
if (!radio.txStandBy()) {
|
||||
counter += 3; //Standby, block only until FIFO empty or auto-retry timeout. Flush TX FIFO if failed
|
||||
}
|
||||
//radio.txStandBy(1000); //Standby, using extended timeout period of 1 second
|
||||
|
||||
float numBytes = cycles * 32;
|
||||
float rate = numBytes / (stopTime - startTime);
|
||||
|
||||
Serial.print("Transfer complete at "); Serial.print(rate); Serial.println(" KB/s");
|
||||
Serial.print(counter); Serial.print(" of "); Serial.print(cycles); Serial.println(" Packets Failed to Send");
|
||||
counter = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (role == RX) {
|
||||
while (radio.available()) {
|
||||
radio.read(&data, 32);
|
||||
counter++;
|
||||
}
|
||||
if (millis() - rxTimer > 1000) {
|
||||
rxTimer = millis();
|
||||
unsigned long numBytes = counter * 32;
|
||||
Serial.print(F("Rate: "));
|
||||
//Prevent dividing into 0, which will cause issues over a period of time
|
||||
Serial.println(numBytes > 0 ? numBytes / 1000.0 : 0);
|
||||
Serial.print(F("Payload Count: "));
|
||||
Serial.println(counter);
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
//
|
||||
// Change roles
|
||||
//
|
||||
|
||||
if ( Serial.available()) {
|
||||
char c = toupper(Serial.read());
|
||||
if (c == 'T' && role == RX) {
|
||||
Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
|
||||
delay(10);
|
||||
radio.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1, pipes[0]);
|
||||
radio.stopListening();
|
||||
role = TX; // Become the primary transmitter (ping out)
|
||||
} else if (c == 'R' && role == TX) {
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1, pipes[1]);
|
||||
radio.startListening();
|
||||
Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));
|
||||
role = RX; // Become the primary receiver (pong back)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
TMRh20 2014
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/** Reliably transmitting large volumes of data with a low signal or in noisy environments
|
||||
* This example demonstrates data transfer functionality with the use of auto-retry
|
||||
and auto-reUse functionality enabled. This sketch demonstrates how a user can extend
|
||||
the auto-retry functionality to any chosen time period, preventing data loss and ensuring
|
||||
the consistency of data.
|
||||
|
||||
This sketh demonstrates use of the writeBlocking() functionality, and extends the standard
|
||||
retry functionality of the radio. Payloads will be auto-retried until successful or the
|
||||
extended timeout period is reached.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#include <SPI.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
/************* USER Configuration *****************************/
|
||||
|
||||
RF24 radio(7,8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
unsigned 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).
|
||||
// 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
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate.
|
||||
|
||||
byte data[32]; //Data buffer
|
||||
|
||||
volatile unsigned long counter;
|
||||
unsigned long rxTimer,startTime, stopTime, payloads = 0;
|
||||
bool TX=1,RX=0,role=0, transferInProgress = 0;
|
||||
|
||||
|
||||
void setup(void) {
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
|
||||
radio.begin(); // Setup and configure rf radio
|
||||
radio.setChannel(1); // Set the channel
|
||||
radio.setPALevel(RF24_PA_LOW); // Set PA LOW for this demonstration. We want the radio to be as lossy as possible for this example.
|
||||
radio.setDataRate(RF24_1MBPS); // Raise the data rate to reduce transmission distance and increase lossiness
|
||||
radio.setAutoAck(1); // Ensure autoACK is enabled
|
||||
radio.setRetries(2,15); // Optionally, increase the delay between retries. Want the number of auto-retries as high as possible (15)
|
||||
radio.setCRCLength(RF24_CRC_16); // Set CRC length to 16-bit to ensure quality of data
|
||||
radio.openWritingPipe(pipes[0]); // Open the default reading and writing pipe
|
||||
radio.openReadingPipe(1,pipes[1]);
|
||||
|
||||
radio.startListening(); // Start listening
|
||||
radio.printDetails(); // Dump the configuration of the rf unit for debugging
|
||||
|
||||
printf("\n\rRF24/examples/Transfer Rates/\n\r");
|
||||
printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
|
||||
|
||||
randomSeed(analogRead(0)); //Seed for random number generation
|
||||
for(int i=0; i<32; i++){
|
||||
data[i] = random(255); //Load the buffer with random data
|
||||
}
|
||||
radio.powerUp(); //Power up the radio
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
void loop(void){
|
||||
|
||||
|
||||
if(role == TX){
|
||||
delay(2000); // Pause for a couple seconds between transfers
|
||||
printf("Initiating Extended Timeout Data Transfer\n\r");
|
||||
|
||||
unsigned long cycles = 1000; // Change this to a higher or lower number. This is the number of payloads that will be sent.
|
||||
|
||||
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
|
||||
radio.writeFast(&transferCMD,12); // Send the transfer command
|
||||
if(radio.txStandBy(timeoutPeriod)){ // If transfer initiation was successful, do the following
|
||||
|
||||
startTime = millis(); // For calculating transfer rate
|
||||
boolean timedOut = 0; // Boolean for keeping track of failures
|
||||
|
||||
for(int i=0; i<cycles; i++){ // Loop through a number of cycles
|
||||
data[0] = i; // Change the first byte of the payload for identification
|
||||
|
||||
if(!radio.writeBlocking(&data,32,timeoutPeriod)){ // If retries are failing and the user defined timeout is exceeded
|
||||
timedOut = 1; // Indicate failure
|
||||
counter = cycles; // Set the fail count to maximum
|
||||
break; // Break out of the for loop
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
stopTime = millis(); // Capture the time of completion or failure
|
||||
|
||||
//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
|
||||
if(timedOut){ radio.txStandBy(); } //Partially blocking standby, blocks until success or max retries. FIFO flushed if auto timeout reached
|
||||
else{ radio.txStandBy(timeoutPeriod); } //Standby, block until FIFO empty (sent) or user specified timeout reached. FIFO flushed if user timeout reached.
|
||||
|
||||
}else{
|
||||
Serial.println("Communication not established"); //If unsuccessful initiating transfer, exit and retry later
|
||||
}
|
||||
|
||||
float rate = cycles * 32 / (stopTime - startTime); //Display results:
|
||||
|
||||
Serial.print("Transfer complete at "); Serial.print(rate); printf(" KB/s \n\r");
|
||||
Serial.print(counter);
|
||||
Serial.print(" of ");
|
||||
Serial.print(cycles); Serial.println(" Packets Failed to Send");
|
||||
counter = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(role == RX){
|
||||
|
||||
if(!transferInProgress){ // If a bulk data transfer has not been started
|
||||
if(radio.available()){
|
||||
radio.read(&data,32); //Read any available payloads for analysis
|
||||
|
||||
if(data[0] == 'H' && data[4] == 'S'){ // If a bulk data transfer command has been received
|
||||
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
|
||||
payloads |= data[9] << 8; // This is the number of payloads that will be sent
|
||||
counter = 0; // Reset the payload counter to 0
|
||||
transferInProgress = 1; // Indicate it has started
|
||||
startTime = rxTimer = millis(); // Capture the start time to measure transfer rate and calculate timeouts
|
||||
}
|
||||
}
|
||||
}else{
|
||||
if(radio.available()){ // If in bulk transfer mode, and a payload is available
|
||||
radio.read(&data,32); // Read the payload
|
||||
rxTimer = millis(); // Reset the timeout timer
|
||||
counter++; // Keep a count of received payloads
|
||||
}else
|
||||
if(millis() - rxTimer > timeoutPeriod){ // If no data available, check the timeout period
|
||||
Serial.println("Transfer Failed"); // If per-payload timeout exceeeded, end the transfer
|
||||
transferInProgress = 0;
|
||||
}else
|
||||
if(counter >= payloads){ // If the specified number of payloads is reached, transfer is completed
|
||||
startTime = millis() - startTime; // Calculate the total time spent during transfer
|
||||
float numBytes = counter*32; // Calculate the number of bytes transferred
|
||||
Serial.print("Rate: "); // Print the transfer rate and number of payloads
|
||||
Serial.print(numBytes/startTime);
|
||||
Serial.println(" KB/s");
|
||||
printf("Payload Count: %d \n\r", counter);
|
||||
transferInProgress = 0; // End the transfer as complete
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Change roles
|
||||
//
|
||||
|
||||
if ( Serial.available() )
|
||||
{
|
||||
char c = toupper(Serial.read());
|
||||
if ( c == 'T' && role == RX )
|
||||
{
|
||||
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
|
||||
radio.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1,pipes[0]);
|
||||
radio.stopListening();
|
||||
role = TX; // Become the primary transmitter (ping out)
|
||||
}
|
||||
else if ( c == 'R' && role == TX )
|
||||
{
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1,pipes[1]);
|
||||
radio.startListening();
|
||||
printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
|
||||
role = RX; // Become the primary receiver (pong back)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
206
arduino-cli/libraries/RF24/examples/Usage/led_remote/Jamfile
Normal file
206
arduino-cli/libraries/RF24/examples/Usage/led_remote/Jamfile
Normal file
@@ -0,0 +1,206 @@
|
||||
PROJECT_NAME = $(PWD:B) ;
|
||||
PROJECT_DIR = . ;
|
||||
PROJECT_LIBS = SPI RF24 ;
|
||||
|
||||
OUT_DIR = ojam ;
|
||||
F_CPU = 16000000 ;
|
||||
MCU = atmega328p ;
|
||||
PORTS = /dev/tty.usbserial-A600eHIs /dev/tty.usbserial-A40081RP /dev/tty.usbserial-A9007LmI ;
|
||||
|
||||
UPLOAD_RATE = 57600 ;
|
||||
AVRDUDE_PROTOCOL = stk500v1 ;
|
||||
COM = 33 ;
|
||||
|
||||
# Host-specific overrides for locations
|
||||
if $(OS) = MACOSX
|
||||
{
|
||||
ARDUINO_VERSION = 22 ;
|
||||
OLD_DIR = /opt/arduino-0021 ;
|
||||
AVR_TOOLS_PATH = $(OLD_DIR)/hardware/tools/avr/bin ;
|
||||
AVRDUDECONFIG_PATH = $(OLD_DIR)/hardware/tools/avr/etc ;
|
||||
ARDUINO_DIR = /opt/Arduino ;
|
||||
ARDUINO_AVR = /usr/lib/avr/include ;
|
||||
}
|
||||
|
||||
# Where is everything?
|
||||
ARDUINO_VERSION ?= 22 ;
|
||||
AVR_TOOLS_PATH ?= /usr/bin ;
|
||||
ARDUINO_DIR ?= /opt/arduino-00$(ARDUINO_VERSION) ;
|
||||
ARDUINO_AVR ?= $(ARDUINO_DIR)/hardware/tools/avr/avr/include/avr ;
|
||||
AVRDUDECONFIG_PATH ?= $(ARDUINO_DIR)/hardware/tools ;
|
||||
ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/arduino ;
|
||||
ARDUINO_LIB = $(ARDUINO_DIR)/libraries ;
|
||||
SKETCH_LIB = $(HOME)/Source/Arduino/libraries ;
|
||||
AVR_CC = $(AVR_TOOLS_PATH)/avr-gcc ;
|
||||
AVR_CXX = $(AVR_TOOLS_PATH)/avr-g++ ;
|
||||
AVR_LD = $(AVR_TOOLS_PATH)/avr-gcc ;
|
||||
AVR_OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy ;
|
||||
AVRDUDE = $(AVR_TOOLS_PATH)/avrdude ;
|
||||
|
||||
DEFINES = F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ;
|
||||
CTUNING = -ffunction-sections -fdata-sections ;
|
||||
CXXTUNING = -fno-exceptions -fno-strict-aliasing ;
|
||||
CFLAGS = -Os -Wall -Wextra -mmcu=$(MCU) $(CTUNING) ;
|
||||
CXXFLAGS = $(CFLAGS) $(CXXTUNING) ;
|
||||
LDFLAGS = -Os -lm -Wl,--gc-sections -mmcu=atmega328p ;
|
||||
|
||||
# Search everywhere for headers
|
||||
HDRS = $(PROJECT_DIR) $(ARDUINO_AVR) $(ARDUINO_CORE) [ GLOB $(ARDUINO_LIB) $(SKETCH_LIB) : [^.]* ] ;
|
||||
|
||||
# Grab everything from the core directory
|
||||
CORE_MODULES = [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ;
|
||||
|
||||
# Grab everything from libraries. To avoid this "grab everything" behaviour, you
|
||||
# can specify specific modules to pick up in PROJECT_MODULES
|
||||
LIB_MODULES = [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp ] ;
|
||||
|
||||
# In addition to explicitly-specified program modules, pick up anything from the current
|
||||
# dir.
|
||||
PROJECT_MODULES += [ GLOB $(PROJECT_DIR) : *.c *.cpp *.pde ] ;
|
||||
|
||||
# Shortcut for the out files
|
||||
OUT = $(OUT_DIR)/$(PROJECT_NAME) ;
|
||||
|
||||
# AvrDude setup
|
||||
AVRDUDE_FLAGS = -V -F -D -C $(AVRDUDECONFIG_PATH)/avrdude.conf -p $(MCU) -c $(AVRDUDE_PROTOCOL) -b $(UPLOAD_RATE) ;
|
||||
|
||||
rule GitVersion
|
||||
{
|
||||
Always $(<) ;
|
||||
Depends all : $(<) ;
|
||||
}
|
||||
|
||||
actions GitVersion
|
||||
{
|
||||
echo "const char program_version[] = \"\\" > $(<)
|
||||
git log -1 --pretty=format:%h >> $(<)
|
||||
echo "\";" >> $(<)
|
||||
}
|
||||
|
||||
GitVersion version.h ;
|
||||
|
||||
rule AvrCc
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
actions AvrCc
|
||||
{
|
||||
$(AVR_CC) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CFLAGS) $(>)
|
||||
}
|
||||
|
||||
rule AvrC++
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
actions AvrC++
|
||||
{
|
||||
$(AVR_CXX) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CXXFLAGS) $(>)
|
||||
}
|
||||
|
||||
rule Pde
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
}
|
||||
|
||||
actions Pde
|
||||
{
|
||||
echo "#include <WProgram.h>" > $(<)
|
||||
echo "#line 1 \"$(>)\"" >> $(<)
|
||||
cat $(>) >> $(<)
|
||||
}
|
||||
|
||||
rule AvrPde
|
||||
{
|
||||
local _CPP = $(OUT_DIR)/$(_I:B).cpp ;
|
||||
Pde $(_CPP) : $(>) ;
|
||||
AvrC++ $(<) : $(_CPP) ;
|
||||
}
|
||||
|
||||
rule AvrObject
|
||||
{
|
||||
switch $(>:S)
|
||||
{
|
||||
case .c : AvrCc $(<) : $(>) ;
|
||||
case .cpp : AvrC++ $(<) : $(>) ;
|
||||
case .pde : AvrPde $(<) : $(>) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule AvrObjects
|
||||
{
|
||||
for _I in $(<)
|
||||
{
|
||||
AvrObject $(OUT_DIR)/$(_I:B).o : $(_I) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule AvrMainFromObjects
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
MkDir $(<:D) ;
|
||||
Depends all : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions AvrMainFromObjects
|
||||
{
|
||||
$(AVR_LD) $(LDFLAGS) -o $(<) $(>)
|
||||
}
|
||||
|
||||
rule AvrMain
|
||||
{
|
||||
AvrMainFromObjects $(<) : $(OUT_DIR)/$(>:B).o ;
|
||||
AvrObjects $(>) ;
|
||||
}
|
||||
|
||||
rule AvrHex
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Depends hex : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions AvrHex
|
||||
{
|
||||
$(AVR_OBJCOPY) -O ihex -R .eeprom $(>) $(<)
|
||||
}
|
||||
|
||||
rule AvrUpload
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
Depends $(2) : $(3) ;
|
||||
NotFile $(1) ;
|
||||
Always $(1) ;
|
||||
Always $(2) ;
|
||||
AvrUploadAction $(2) : $(3) ;
|
||||
}
|
||||
|
||||
actions AvrUploadAction
|
||||
{
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i
|
||||
}
|
||||
|
||||
AvrMain $(OUT).elf : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ;
|
||||
AvrHex $(OUT).hex : $(OUT).elf ;
|
||||
|
||||
AvrUpload p6 : /dev/tty.usbserial-A600eHIs : $(OUT).hex ;
|
||||
AvrUpload p4 : /dev/tty.usbserial-A40081RP : $(OUT).hex ;
|
||||
AvrUpload p9 : /dev/tty.usbserial-A9007LmI : $(OUT).hex ;
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example LED Remote
|
||||
*
|
||||
* This is an example of how to use the RF24 class to control a remote
|
||||
* bank of LED's using buttons on a remote control.
|
||||
*
|
||||
* On the 'remote', connect any number of buttons or switches from
|
||||
* an arduino pin to ground. Update 'button_pins' to reflect the
|
||||
* pins used.
|
||||
*
|
||||
* On the 'led' board, connect the same number of LED's from an
|
||||
* arduino pin to a resistor to ground. Update 'led_pins' to reflect
|
||||
* the pins used. Also connect a separate pin to ground and change
|
||||
* the 'role_pin'. This tells the sketch it's running on the LED board.
|
||||
*
|
||||
* Every time the buttons change on the remote, the entire state of
|
||||
* buttons is send to the led board, which displays the state.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 (CE & CS)
|
||||
|
||||
RF24 radio(9,10);
|
||||
|
||||
// sets the role of this unit in hardware. Connect to GND to be the 'led' board receiver
|
||||
// Leave open to be the 'remote' transmitter
|
||||
const int role_pin = A4;
|
||||
|
||||
// Pins on the remote for buttons
|
||||
const uint8_t button_pins[] = { 2,3,4,5,6,7 };
|
||||
const uint8_t num_button_pins = sizeof(button_pins);
|
||||
|
||||
// Pins on the LED board for LED's
|
||||
const uint8_t led_pins[] = { 2,3,4,5,6,7 };
|
||||
const uint8_t num_led_pins = sizeof(led_pins);
|
||||
|
||||
//
|
||||
// Topology
|
||||
//
|
||||
|
||||
// Single radio pipe address for the 2 nodes to communicate.
|
||||
const uint64_t pipe = 0xE8E8F0F0E1LL;
|
||||
|
||||
//
|
||||
// Role management
|
||||
//
|
||||
// Set up role. This sketch uses the same software for all the nodes in this
|
||||
// system. Doing so greatly simplifies testing. The hardware itself specifies
|
||||
// which node it is.
|
||||
//
|
||||
// This is done through the role_pin
|
||||
//
|
||||
|
||||
// The various roles supported by this sketch
|
||||
typedef enum { role_remote = 1, role_led } role_e;
|
||||
|
||||
// The debug-friendly names of those roles
|
||||
const char* role_friendly_name[] = { "invalid", "Remote", "LED Board"};
|
||||
|
||||
// The role of the current running sketch
|
||||
role_e role;
|
||||
|
||||
//
|
||||
// Payload
|
||||
//
|
||||
|
||||
uint8_t button_states[num_button_pins];
|
||||
uint8_t led_states[num_led_pins];
|
||||
|
||||
//
|
||||
// Setup
|
||||
//
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Role
|
||||
//
|
||||
|
||||
// set up the role pin
|
||||
pinMode(role_pin, INPUT);
|
||||
digitalWrite(role_pin,HIGH);
|
||||
delay(20); // Just to get a solid reading on the role pin
|
||||
|
||||
// read the address pin, establish our role
|
||||
if ( digitalRead(role_pin) )
|
||||
role = role_remote;
|
||||
else
|
||||
role = role_led;
|
||||
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/led_remote/\n\r");
|
||||
printf("ROLE: %s\n\r",role_friendly_name[role]);
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
|
||||
radio.begin();
|
||||
|
||||
//
|
||||
// Open pipes to other nodes for communication
|
||||
//
|
||||
|
||||
// This simple sketch opens a single pipes for these two nodes to communicate
|
||||
// back and forth. One listens on it, the other talks to it.
|
||||
|
||||
if ( role == role_remote )
|
||||
{
|
||||
radio.openWritingPipe(pipe);
|
||||
}
|
||||
else
|
||||
{
|
||||
radio.openReadingPipe(1,pipe);
|
||||
}
|
||||
|
||||
//
|
||||
// Start listening
|
||||
//
|
||||
|
||||
if ( role == role_led )
|
||||
radio.startListening();
|
||||
|
||||
//
|
||||
// Dump the configuration of the rf unit for debugging
|
||||
//
|
||||
|
||||
radio.printDetails();
|
||||
|
||||
//
|
||||
// Set up buttons / LED's
|
||||
//
|
||||
|
||||
// Set pull-up resistors for all buttons
|
||||
if ( role == role_remote )
|
||||
{
|
||||
int i = num_button_pins;
|
||||
while(i--)
|
||||
{
|
||||
pinMode(button_pins[i],INPUT);
|
||||
digitalWrite(button_pins[i],HIGH);
|
||||
}
|
||||
}
|
||||
|
||||
// Turn LED's ON until we start getting keys
|
||||
if ( role == role_led )
|
||||
{
|
||||
int i = num_led_pins;
|
||||
while(i--)
|
||||
{
|
||||
pinMode(led_pins[i],OUTPUT);
|
||||
led_states[i] = HIGH;
|
||||
digitalWrite(led_pins[i],led_states[i]);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//
|
||||
// Loop
|
||||
//
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
//
|
||||
// Remote role. If the state of any button has changed, send the whole state of
|
||||
// all buttons.
|
||||
//
|
||||
|
||||
if ( role == role_remote )
|
||||
{
|
||||
// Get the current state of buttons, and
|
||||
// Test if the current state is different from the last state we sent
|
||||
int i = num_button_pins;
|
||||
bool different = false;
|
||||
while(i--)
|
||||
{
|
||||
uint8_t state = ! digitalRead(button_pins[i]);
|
||||
if ( state != button_states[i] )
|
||||
{
|
||||
different = true;
|
||||
button_states[i] = state;
|
||||
}
|
||||
}
|
||||
|
||||
// Send the state of the buttons to the LED board
|
||||
if ( different )
|
||||
{
|
||||
printf("Now sending...");
|
||||
bool ok = radio.write( button_states, num_button_pins );
|
||||
if (ok)
|
||||
printf("ok\n\r");
|
||||
else
|
||||
printf("failed\n\r");
|
||||
}
|
||||
|
||||
// Try again in a short while
|
||||
delay(20);
|
||||
}
|
||||
|
||||
//
|
||||
// LED role. Receive the state of all buttons, and reflect that in the LEDs
|
||||
//
|
||||
|
||||
if ( role == role_led )
|
||||
{
|
||||
// if there is data ready
|
||||
if ( radio.available() )
|
||||
{
|
||||
// Dump the payloads until we've gotten everything
|
||||
while (radio.available())
|
||||
{
|
||||
// Fetch the payload, and see if this was the last one.
|
||||
radio.read( button_states, num_button_pins );
|
||||
|
||||
// Spew it
|
||||
printf("Got buttons\n\r");
|
||||
|
||||
// For each button, if the button now on, then toggle the LED
|
||||
int i = num_led_pins;
|
||||
while(i--)
|
||||
{
|
||||
if ( button_states[i] )
|
||||
{
|
||||
led_states[i] ^= HIGH;
|
||||
digitalWrite(led_pins[i],led_states[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim:ai:cin:sts=2 sw=2 ft=cpp
|
||||
219
arduino-cli/libraries/RF24/examples/Usage/nordic_fob/Jamfile
Normal file
219
arduino-cli/libraries/RF24/examples/Usage/nordic_fob/Jamfile
Normal file
@@ -0,0 +1,219 @@
|
||||
# (1) Project Information
|
||||
|
||||
PROJECT_LIBS = RF24 SPI ;
|
||||
PROJECT_DIRS = $(PWD) ;
|
||||
|
||||
# (2) Board Information
|
||||
|
||||
UPLOAD_PROTOCOL ?= stk500v1 ;
|
||||
UPLOAD_SPEED ?= 115200 ;
|
||||
MCU ?= atmega328p ;
|
||||
F_CPU ?= 16000000 ;
|
||||
CORE ?= arduino ;
|
||||
VARIANT ?= standard ;
|
||||
ARDUINO_VERSION ?= 100 ;
|
||||
|
||||
# (3) USB Ports
|
||||
|
||||
PORTS = p4 p6 p9 u0 u1 u2 ;
|
||||
PORT_p6 = /dev/tty.usbserial-A600eHIs ;
|
||||
PORT_p4 = /dev/tty.usbserial-A40081RP ;
|
||||
PORT_p9 = /dev/tty.usbserial-A9007LmI ;
|
||||
PORT_u0 = /dev/ttyUSB0 ;
|
||||
PORT_u1 = /dev/ttyUSB1 ;
|
||||
PORT_u2 = /dev/ttyUSB2 ;
|
||||
|
||||
# (4) Location of AVR tools
|
||||
#
|
||||
# This configuration assumes using avr-tools that were obtained separate from the Arduino
|
||||
# distribution.
|
||||
|
||||
if $(OS) = MACOSX
|
||||
{
|
||||
AVR_BIN = /usr/local/avrtools/bin ;
|
||||
AVR_ETC = /usr/local/avrtools/etc ;
|
||||
AVR_INCLUDE = /usr/local/avrtools/include ;
|
||||
}
|
||||
else
|
||||
{
|
||||
AVR_BIN = /usr/bin ;
|
||||
AVR_INCLUDE = /usr/lib/avr/include ;
|
||||
AVR_ETC = /etc ;
|
||||
}
|
||||
|
||||
# (5) Directories where Arduino core and libraries are located
|
||||
|
||||
ARDUINO_DIR ?= /opt/Arduino ;
|
||||
ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/$(CORE) $(ARDUINO_DIR)/hardware/arduino/variants/$(VARIANT) ;
|
||||
ARDUINO_LIB = $(ARDUINO_DIR)/libraries ;
|
||||
SKETCH_LIB = $(HOME)/Source/Arduino/libraries ;
|
||||
|
||||
#
|
||||
# --------------------------------------------------
|
||||
# Below this line usually never needs to be modified
|
||||
#
|
||||
|
||||
# Tool locations
|
||||
|
||||
CC = $(AVR_BIN)/avr-gcc ;
|
||||
C++ = $(AVR_BIN)/avr-g++ ;
|
||||
LINK = $(AVR_BIN)/avr-gcc ;
|
||||
AR = $(AVR_BIN)/avr-ar rcs ;
|
||||
RANLIB = ;
|
||||
OBJCOPY = $(AVR_BIN)/avr-objcopy ;
|
||||
AVRDUDE = $(AVR_BIN)/avrdude ;
|
||||
|
||||
# Flags
|
||||
|
||||
DEFINES += F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ;
|
||||
OPTIM = -Os ;
|
||||
CCFLAGS = -Wall -Wextra -Wno-strict-aliasing -mmcu=$(MCU) -ffunction-sections -fdata-sections ;
|
||||
C++FLAGS = $(CCFLAGS) -fno-exceptions -fno-strict-aliasing ;
|
||||
LINKFLAGS = $(OPTIM) -lm -Wl,--gc-sections -mmcu=$(MCU) ;
|
||||
AVRDUDEFLAGS = -V -F -D -C $(AVR_ETC)/avrdude.conf -p $(MCU) -c $(UPLOAD_PROTOCOL) -b $(UPLOAD_SPEED) ;
|
||||
|
||||
# Search everywhere for headers
|
||||
|
||||
HDRS = $(PROJECT_DIRS) $(AVR_INCLUDE) $(ARDUINO_CORE) $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) ;
|
||||
|
||||
# Output locations
|
||||
|
||||
LOCATE_TARGET = $(F_CPU) ;
|
||||
LOCATE_SOURCE = $(F_CPU) ;
|
||||
|
||||
#
|
||||
# Custom rules
|
||||
#
|
||||
|
||||
rule GitVersion
|
||||
{
|
||||
Always $(<) ;
|
||||
Depends all : $(<) ;
|
||||
}
|
||||
|
||||
actions GitVersion
|
||||
{
|
||||
echo "const char program_version[] = \"\\" > $(<)
|
||||
git log -1 --pretty=format:%h >> $(<)
|
||||
echo "\";" >> $(<)
|
||||
}
|
||||
|
||||
GitVersion version.h ;
|
||||
|
||||
rule Pde
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
MakeLocate $(<) : $(LOCATE_SOURCE) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
if ( $(ARDUINO_VERSION) < 100 )
|
||||
{
|
||||
ARDUINO_H = WProgram.h ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ARDUINO_H = Arduino.h ;
|
||||
}
|
||||
|
||||
actions Pde
|
||||
{
|
||||
echo "#include <$(ARDUINO_H)>" > $(<)
|
||||
echo "#line 1 \"$(>)\"" >> $(<)
|
||||
cat $(>) >> $(<)
|
||||
}
|
||||
|
||||
rule C++Pde
|
||||
{
|
||||
local _CPP = $(>:B).cpp ;
|
||||
Pde $(_CPP) : $(>) ;
|
||||
C++ $(<) : $(_CPP) ;
|
||||
}
|
||||
|
||||
rule UserObject
|
||||
{
|
||||
switch $(>:S)
|
||||
{
|
||||
case .ino : C++Pde $(<) : $(>) ;
|
||||
case .pde : C++Pde $(<) : $(>) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule Objects
|
||||
{
|
||||
local _i ;
|
||||
|
||||
for _i in [ FGristFiles $(<) ]
|
||||
{
|
||||
local _b = $(_i:B)$(SUFOBJ) ;
|
||||
local _o = $(_b:G=$(SOURCE_GRIST:E)) ;
|
||||
Object $(_o) : $(_i) ;
|
||||
Depends obj : $(_o) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule Library
|
||||
{
|
||||
LibraryFromObjects $(<) : $(>:B)$(SUFOBJ) ;
|
||||
Objects $(>) ;
|
||||
}
|
||||
|
||||
rule Main
|
||||
{
|
||||
MainFromObjects $(<) : $(>:B)$(SUFOBJ) ;
|
||||
Objects $(>) ;
|
||||
}
|
||||
|
||||
rule Hex
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
MakeLocate $(<) : $(LOCATE_TARGET) ;
|
||||
Depends hex : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions Hex
|
||||
{
|
||||
$(OBJCOPY) -O ihex -R .eeprom $(>) $(<)
|
||||
}
|
||||
|
||||
rule Upload
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
Depends $(2) : $(3) ;
|
||||
NotFile $(1) ;
|
||||
Always $(1) ;
|
||||
Always $(2) ;
|
||||
UploadAction $(2) : $(3) ;
|
||||
}
|
||||
|
||||
actions UploadAction
|
||||
{
|
||||
$(AVRDUDE) $(AVRDUDEFLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i
|
||||
}
|
||||
|
||||
rule Arduino
|
||||
{
|
||||
LINKFLAGS on $(<) = $(LINKFLAGS) -Wl,-Map=$(LOCATE_TARGET)/$(<:B).map ;
|
||||
Main $(<) : $(>) ;
|
||||
LinkLibraries $(<) : libs core ;
|
||||
Hex $(<:B).hex : $(<) ;
|
||||
for _p in $(PORTS)
|
||||
{
|
||||
Upload $(_p) : $(PORT_$(_p)) : $(<:B).hex ;
|
||||
}
|
||||
}
|
||||
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
|
||||
# Grab everything from the core directory
|
||||
Library core : [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ;
|
||||
|
||||
# Grab everything from libraries. To avoid this "grab everything" behaviour, you
|
||||
# can specify specific modules to pick up in PROJECT_MODULES
|
||||
Library libs : [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp *.c ] ;
|
||||
|
||||
# Main output executable
|
||||
Arduino $(PWD:B).elf : $(PROJECT_MODULES) [ GLOB $(PROJECT_DIRS) : *.c *.cpp *.pde *.ino ] ;
|
||||
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
Copyright (C) 2012 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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example Nordic FOB Receiver
|
||||
*
|
||||
* This is an example of how to use the RF24 class to receive signals from the
|
||||
* Sparkfun Nordic FOB. Thanks to Kirk Mower for providing test hardware.
|
||||
*
|
||||
* See blog post at http://maniacbug.wordpress.com/2012/01/08/nordic-fob/
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <RF24.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "printf.h"
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10
|
||||
|
||||
RF24 radio(9,10);
|
||||
|
||||
//
|
||||
// Payload
|
||||
//
|
||||
|
||||
struct payload_t
|
||||
{
|
||||
uint8_t buttons;
|
||||
uint16_t id;
|
||||
uint8_t empty;
|
||||
};
|
||||
|
||||
const char* button_names[] = { "Up", "Down", "Left", "Right", "Center" };
|
||||
const int num_buttons = 5;
|
||||
|
||||
//
|
||||
// Forward declarations
|
||||
//
|
||||
|
||||
uint16_t flip_endian(uint16_t in);
|
||||
|
||||
//
|
||||
// Setup
|
||||
//
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
printf("\r\nRF24/examples/nordic_fob/\r\n");
|
||||
|
||||
//
|
||||
// Setup and configure rf radio according to the built-in parameters
|
||||
// of the FOB.
|
||||
//
|
||||
|
||||
radio.begin();
|
||||
radio.setChannel(2);
|
||||
radio.setPayloadSize(4);
|
||||
radio.setAutoAck(false);
|
||||
radio.setCRCLength(RF24_CRC_8);
|
||||
radio.openReadingPipe(1,0xE7E7E7E7E7LL);
|
||||
|
||||
//
|
||||
// Start listening
|
||||
//
|
||||
|
||||
radio.startListening();
|
||||
|
||||
//
|
||||
// Dump the configuration of the rf unit for debugging
|
||||
//
|
||||
|
||||
radio.printDetails();
|
||||
}
|
||||
|
||||
//
|
||||
// Loop
|
||||
//
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
//
|
||||
// Receive each packet, dump it out
|
||||
//
|
||||
|
||||
// if there is data ready
|
||||
if ( radio.available() )
|
||||
{
|
||||
// Get the packet from the radio
|
||||
payload_t payload;
|
||||
radio.read( &payload, sizeof(payload) );
|
||||
|
||||
// Print the ID of this message. Note that the message
|
||||
// is sent 'big-endian', so we have to flip it.
|
||||
printf("#%05u Buttons ",flip_endian(payload.id));
|
||||
|
||||
// Print the name of each button
|
||||
int i = num_buttons;
|
||||
while (i--)
|
||||
{
|
||||
if ( ! ( payload.buttons & _BV(i) ) )
|
||||
{
|
||||
printf("%s ",button_names[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// If no buttons, print None
|
||||
if ( payload.buttons == _BV(num_buttons) - 1 )
|
||||
printf("None");
|
||||
|
||||
printf("\r\n");
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Helper functions
|
||||
//
|
||||
|
||||
// Change a big-endian word into a little-endian
|
||||
uint16_t flip_endian(uint16_t in)
|
||||
{
|
||||
uint16_t low = in >> 8;
|
||||
uint16_t high = in << 8;
|
||||
|
||||
return high | low;
|
||||
}
|
||||
|
||||
// vim:cin:ai:sts=2 sw=2 ft=cpp
|
||||
182
arduino-cli/libraries/RF24/examples/Usage/pingpair_maple/Jamfile
Normal file
182
arduino-cli/libraries/RF24/examples/Usage/pingpair_maple/Jamfile
Normal file
@@ -0,0 +1,182 @@
|
||||
MCU = cortex-m3 ;
|
||||
CHIP = STM32F103ZE ;
|
||||
BOARD = maple_native ;
|
||||
|
||||
#CHIP = at91sam3u4 ;
|
||||
#BOARD = sam3u-ek ;
|
||||
|
||||
if ! $(TOOLSET)
|
||||
{
|
||||
TOOLSET = devkit ;
|
||||
Echo "Assuming TOOLSET=devkit" ;
|
||||
}
|
||||
|
||||
if $(TOOLSET) = yagarto
|
||||
{
|
||||
TOOLS_PATH = ~/Source/yagarto-4.6.2/bin ;
|
||||
TOOLS_ARCH = arm-none-eabi- ;
|
||||
}
|
||||
if $(TOOLSET) = yagarto-install
|
||||
{
|
||||
TOOLS_PATH = ~/Source/yagarto/install/bin ;
|
||||
TOOLS_ARCH = arm-none-eabi- ;
|
||||
}
|
||||
else if $(TOOLSET) = devkit
|
||||
{
|
||||
TOOLS_PATH = /opt/devkitARM/bin ;
|
||||
TOOLS_ARCH = arm-eabi- ;
|
||||
}
|
||||
else if $(TOOLSET) = maple
|
||||
{
|
||||
TOOLS_PATH = /opt/Maple/Resources/Java/hardware/tools/arm/bin ;
|
||||
TOOLS_ARCH = arm-none-eabi- ;
|
||||
}
|
||||
else if $(TOOLSET) = ports
|
||||
{
|
||||
TOOLS_PATH = /opt/local/bin ;
|
||||
TOOLS_ARCH = arm-none-eabi- ;
|
||||
}
|
||||
|
||||
CC = $(TOOLS_PATH)/$(TOOLS_ARCH)gcc ;
|
||||
C++ = $(TOOLS_PATH)/$(TOOLS_ARCH)g++ ;
|
||||
AS = $(TOOLS_PATH)/$(TOOLS_ARCH)gcc -c ;
|
||||
LINK = $(TOOLS_PATH)/$(TOOLS_ARCH)g++ ;
|
||||
OBJCOPY = $(TOOLS_PATH)/$(TOOLS_ARCH)objcopy ;
|
||||
DFU = dfu-util ;
|
||||
|
||||
DEFINES += VECT_TAB_FLASH BOARD_$(BOARD) MCU_$(CHIP) ERROR_LED_PORT=GPIOC ERROR_LED_PIN=15 STM32_HIGH_DENSITY MAPLE_IDE ;
|
||||
OPTIM = -Os ;
|
||||
MFLAGS = cpu=$(MCU) thumb arch=armv7-m ;
|
||||
CCFLAGS = -Wall -m$(MFLAGS) -g -nostdlib -ffunction-sections -fdata-sections -Wl,--gc-sections ;
|
||||
C++FLAGS = $(CCFLAGS) -fno-rtti -fno-exceptions ;
|
||||
LINKFLAGS += -m$(MFLAGS) -Xlinker --gc-sections ;
|
||||
DFUFLAGS = -a1 -d 0x1eaf:0x0003 -R ;
|
||||
|
||||
MAPLE_DIR = $(HOME)/Source/SAM3U/libmaple ;
|
||||
MAPLE_LIBS = Servo LiquidCrystal Wire FreeRTOS ;
|
||||
MAPLE_SUBDIRS = wirish wirish/comm wirish/boards libmaple libmaple/usb libmaple/usb/usb_lib ;
|
||||
|
||||
SKETCH_DIR = $(HOME)/Source/Arduino ;
|
||||
SKETCH_LIBS = RF24 ;
|
||||
|
||||
MODULE_DIRS = . $(MAPLE_DIR)/$(MAPLE_SUBDIRS) $(MAPLE_DIR)/libraries/$(MAPLE_LIBS) $(SKETCH_DIR)/libraries/$(SKETCH_LIBS) ;
|
||||
HDRS = $(MODULE_DIRS) ;
|
||||
LOCATE_TARGET = out/$(TOOLSET) ;
|
||||
LOCATE_SOURCE = $(LOCATE_TARGET) ;
|
||||
|
||||
rule Pde
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
MakeLocate $(<) : $(LOCATE_SOURCE) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
if ( $(ARDUINO_VERSION) < 100 )
|
||||
{
|
||||
ARDUINO_H = WProgram.h ;
|
||||
}
|
||||
else
|
||||
{
|
||||
ARDUINO_H = Arduino.h ;
|
||||
}
|
||||
|
||||
actions Pde
|
||||
{
|
||||
echo "#include <$(ARDUINO_H)>" > $(<)
|
||||
echo "#line 1 \"$(>)\"" >> $(<)
|
||||
cat $(>) >> $(<)
|
||||
}
|
||||
|
||||
rule C++Pde
|
||||
{
|
||||
local _CPP = $(>:B).cpp ;
|
||||
Pde $(_CPP) : $(>) ;
|
||||
C++ $(<) : $(_CPP) ;
|
||||
}
|
||||
|
||||
rule Hex
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
MakeLocate $(<) : $(LOCATE_TARGET) ;
|
||||
Depends hex : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions Hex
|
||||
{
|
||||
$(OBJCOPY) -O ihex $(>) $(<)
|
||||
}
|
||||
|
||||
rule Binary
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
MakeLocate $(<) : $(LOCATE_TARGET) ;
|
||||
Depends binary : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions Binary
|
||||
{
|
||||
$(OBJCOPY) -O binary $(>) $(<)
|
||||
}
|
||||
|
||||
rule UserObject
|
||||
{
|
||||
switch $(>:S)
|
||||
{
|
||||
case .S : As $(<) : $(>) ;
|
||||
case .ino : C++Pde $(<) : $(>) ;
|
||||
case .pde : C++Pde $(<) : $(>) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule Upload
|
||||
{
|
||||
Depends up : $(<) ;
|
||||
NotFile up ;
|
||||
Always $(<) ;
|
||||
Always up ;
|
||||
}
|
||||
|
||||
actions Upload
|
||||
{
|
||||
$(DFU) $(DFUFLAGS) -D $(<)
|
||||
}
|
||||
|
||||
# Override base objects rule, so all output can go in the output dir
|
||||
rule Objects
|
||||
{
|
||||
local _i ;
|
||||
|
||||
for _i in [ FGristFiles $(<) ]
|
||||
{
|
||||
local _b = $(_i:B)$(SUFOBJ) ;
|
||||
local _o = $(_b:G=$(SOURCE_GRIST:E)) ;
|
||||
Object $(_o) : $(_i) ;
|
||||
Depends obj : $(_o) ;
|
||||
}
|
||||
}
|
||||
|
||||
# Override base main rule, so all output can go in the output dir
|
||||
rule Main
|
||||
{
|
||||
MainFromObjects $(<) : $(>:B)$(SUFOBJ) ;
|
||||
Objects $(>) ;
|
||||
}
|
||||
|
||||
# Modules
|
||||
MODULES = [ GLOB $(MODULE_DIRS) : *.pde *.c *.cpp *.S ] ;
|
||||
|
||||
# Main output executable
|
||||
MAIN = $(PWD:B).elf ;
|
||||
|
||||
# Linker script
|
||||
LINK_DIR = $(MAPLE_DIR)/support/ld ;
|
||||
LINKSCRIPT = $(LINK_DIR)/$(BOARD)/flash.ld ;
|
||||
|
||||
# Bring in the map and link script
|
||||
LINKFLAGS += -Wl,-Map=$(LOCATE_TARGET)/$(MAIN:B).map -T$(LINKSCRIPT) -L$(LINK_DIR) ;
|
||||
|
||||
Main $(MAIN) : $(MODULES) ;
|
||||
Binary $(MAIN:B).bin : $(MAIN) ;
|
||||
Upload $(MAIN:B).bin ;
|
||||
@@ -0,0 +1,87 @@
|
||||
#ifdef MAPLE_IDE
|
||||
|
||||
#include <stdio.h>
|
||||
#include "wirish.h"
|
||||
|
||||
extern void setup(void);
|
||||
extern void loop(void);
|
||||
|
||||
void board_start(const char* program_name)
|
||||
{
|
||||
// Set up the LED to steady on
|
||||
pinMode(BOARD_LED_PIN, OUTPUT);
|
||||
digitalWrite(BOARD_LED_PIN, HIGH);
|
||||
|
||||
// Setup the button as input
|
||||
pinMode(BOARD_BUTTON_PIN, INPUT);
|
||||
digitalWrite(BOARD_BUTTON_PIN, HIGH);
|
||||
|
||||
SerialUSB.begin();
|
||||
SerialUSB.println("Press BUT");
|
||||
|
||||
// Wait for button press
|
||||
while ( !isButtonPressed() )
|
||||
{
|
||||
}
|
||||
|
||||
SerialUSB.println("Welcome!");
|
||||
SerialUSB.println(program_name);
|
||||
|
||||
int i = 11;
|
||||
while (i--)
|
||||
{
|
||||
toggleLED();
|
||||
delay(50);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Custom version of _write, which will print to the USB.
|
||||
* In order to use it you MUST ADD __attribute__((weak))
|
||||
* to _write in libmaple/syscalls.c
|
||||
*/
|
||||
extern "C" int _write (int file, char * ptr, int len)
|
||||
{
|
||||
if ( (file != 1) && (file != 2) )
|
||||
return 0;
|
||||
else
|
||||
SerialUSB.write(ptr,len);
|
||||
return len;
|
||||
}
|
||||
|
||||
/**
|
||||
* Re-entrant version of _write. Yagarto and Devkit now use
|
||||
* the re-entrant newlib, so these get called instead of the
|
||||
* non_r versions.
|
||||
*/
|
||||
extern "C" int _write_r (void*, int file, char * ptr, int len)
|
||||
{
|
||||
return _write( file, ptr, len);
|
||||
}
|
||||
|
||||
__attribute__((constructor)) __attribute__ ((weak)) void premain()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
__attribute__((weak)) void setup(void)
|
||||
{
|
||||
board_start("No program defined");
|
||||
}
|
||||
|
||||
__attribute__((weak)) void loop(void)
|
||||
{
|
||||
}
|
||||
|
||||
__attribute__((weak)) int main(void)
|
||||
{
|
||||
setup();
|
||||
|
||||
while (true)
|
||||
{
|
||||
loop();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
#endif // ifdef MAPLE_IDE
|
||||
// vim:cin:ai:sts=2 sw=2 ft=cpp
|
||||
@@ -0,0 +1,242 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example RF Radio Ping Pair ... for Maple
|
||||
*
|
||||
* This is an example of how to use the RF24 class. Write this sketch to two different nodes,
|
||||
* connect the role_pin to ground on one. 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.
|
||||
*/
|
||||
|
||||
#include "WProgram.h"
|
||||
#include <SPI.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
|
||||
//
|
||||
// Maple specific setup. Other than this section, the sketch is the same on Maple as on
|
||||
// Arduino
|
||||
//
|
||||
|
||||
#ifdef MAPLE_IDE
|
||||
|
||||
// External startup function
|
||||
extern void board_start(const char* program_name);
|
||||
|
||||
// Use SPI #2.
|
||||
HardwareSPI SPI(2);
|
||||
|
||||
#else
|
||||
#define board_startup printf
|
||||
#define toggleLED(x) (x)
|
||||
#endif
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 7 & 6
|
||||
// (This works for the Getting Started board plugged into the
|
||||
// Maple Native backwards.)
|
||||
|
||||
RF24 radio(7,6);
|
||||
|
||||
// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
|
||||
// Leave open to be the 'ping' transmitter
|
||||
const int role_pin = 10;
|
||||
|
||||
//
|
||||
// Topology
|
||||
//
|
||||
|
||||
// Radio pipe addresses for the 2 nodes to communicate.
|
||||
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
|
||||
|
||||
//
|
||||
// Role management
|
||||
//
|
||||
// Set up role. This sketch uses the same software for all the nodes
|
||||
// in this system. Doing so greatly simplifies testing. The hardware itself specifies
|
||||
// which node it is.
|
||||
//
|
||||
// This is done through the role_pin
|
||||
//
|
||||
|
||||
// The various roles supported by this sketch
|
||||
typedef enum { role_ping_out = 1, role_pong_back } role_e;
|
||||
|
||||
// The debug-friendly names of those roles
|
||||
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};
|
||||
|
||||
// The role of the current running sketch
|
||||
role_e role;
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Role
|
||||
//
|
||||
|
||||
// set up the role pin
|
||||
pinMode(role_pin, INPUT);
|
||||
digitalWrite(role_pin,HIGH);
|
||||
delay(20); // Just to get a solid reading on the role pin
|
||||
|
||||
// read the address pin, establish our role
|
||||
if ( digitalRead(role_pin) )
|
||||
role = role_ping_out;
|
||||
else
|
||||
role = role_pong_back;
|
||||
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
board_start("\n\rRF24/examples/pingpair/\n\r");
|
||||
printf("ROLE: %s\n\r",role_friendly_name[role]);
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
|
||||
radio.begin();
|
||||
|
||||
// optionally, increase the delay between retries & # of retries
|
||||
radio.setRetries(15,15);
|
||||
|
||||
// optionally, reduce the payload size. seems to
|
||||
// improve reliability
|
||||
radio.setPayloadSize(8);
|
||||
|
||||
//
|
||||
// Open pipes to other nodes for communication
|
||||
//
|
||||
|
||||
// This simple sketch opens two pipes for these two nodes to communicate
|
||||
// back and forth.
|
||||
// Open 'our' pipe for writing
|
||||
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
|
||||
|
||||
if ( role == role_ping_out )
|
||||
{
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1,pipes[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
radio.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1,pipes[0]);
|
||||
}
|
||||
|
||||
//
|
||||
// Start listening
|
||||
//
|
||||
|
||||
radio.startListening();
|
||||
|
||||
//
|
||||
// Dump the configuration of the rf unit for debugging
|
||||
//
|
||||
|
||||
radio.printDetails();
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
//
|
||||
// Ping out role. Repeatedly send the current time
|
||||
//
|
||||
|
||||
if (role == role_ping_out)
|
||||
{
|
||||
toggleLED();
|
||||
|
||||
// First, stop listening so we can talk.
|
||||
radio.stopListening();
|
||||
|
||||
// Take the time, and send it. This will block until complete
|
||||
unsigned long time = millis();
|
||||
printf("Now sending %lu...",time);
|
||||
bool ok = radio.write( &time, sizeof(unsigned long) );
|
||||
|
||||
if (ok)
|
||||
printf("ok...\r\n");
|
||||
else
|
||||
printf("failed.\r\n");
|
||||
|
||||
// Now, continue listening
|
||||
radio.startListening();
|
||||
|
||||
// Wait here until we get a response, or timeout (250ms)
|
||||
unsigned long started_waiting_at = millis();
|
||||
bool timeout = false;
|
||||
while ( ! radio.available() && ! timeout )
|
||||
if (millis() - started_waiting_at > 200 )
|
||||
timeout = true;
|
||||
|
||||
// Describe the results
|
||||
if ( timeout )
|
||||
{
|
||||
printf("Failed, response timed out.\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grab the response, compare, and send to debugging spew
|
||||
unsigned long got_time;
|
||||
radio.read( &got_time, sizeof(unsigned long) );
|
||||
|
||||
// Spew it
|
||||
printf("Got response %lu, round-trip delay: %lu\r\n",got_time,millis()-got_time);
|
||||
}
|
||||
|
||||
toggleLED();
|
||||
|
||||
// Try again 1s later
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
//
|
||||
// Pong back role. Receive each packet, dump it out, and send it back
|
||||
//
|
||||
|
||||
if ( role == role_pong_back )
|
||||
{
|
||||
// if there is data ready
|
||||
if ( radio.available() )
|
||||
{
|
||||
// Dump the payloads until we've gotten everything
|
||||
unsigned long got_time;
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Fetch the payload, and see if this was the last one.
|
||||
done = radio.read( &got_time, sizeof(unsigned long) );
|
||||
|
||||
// Spew it
|
||||
printf("Got payload %lu...",got_time);
|
||||
|
||||
// Delay just a little bit to let the other unit
|
||||
// make the transition to receiver
|
||||
delay(20);
|
||||
}
|
||||
|
||||
// First, stop listening so we can talk
|
||||
radio.stopListening();
|
||||
|
||||
// Send the final one back.
|
||||
radio.write( &got_time, sizeof(unsigned long) );
|
||||
printf("Sent response.\r\n");
|
||||
|
||||
// Now, resume listening so we catch the next packets.
|
||||
radio.startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim:cin:ai:sts=2 sw=2 ft=cpp
|
||||
1
arduino-cli/libraries/RF24/examples/Usage/readme.md
Normal file
1
arduino-cli/libraries/RF24/examples/Usage/readme.md
Normal file
@@ -0,0 +1 @@
|
||||
Note: These examples may have not been maintained with library updates, and are provided as-is for reference purposes.
|
||||
@@ -0,0 +1,114 @@
|
||||
/**
|
||||
Example for efficient call-response using ack-payloads
|
||||
|
||||
This example continues to make use of all the normal functionality of the radios including
|
||||
the auto-ack and auto-retry features, but allows ack-payloads to be written optionally as well.
|
||||
This allows very fast call-response communication, with the responding radio never having to
|
||||
switch out of Primary Receiver mode to send back a payload, but having the option to if wanting
|
||||
to initiate communication instead of respond to a commmunication.
|
||||
*/
|
||||
/*
|
||||
// March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork
|
||||
// Parts derived from examples by J. Coliz <maniacbug@ymail.com>
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
RF24 radio(7, 8);
|
||||
|
||||
// Topology
|
||||
const uint64_t pipes[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate.
|
||||
|
||||
// Role management: Set up role. This sketch uses the same software for all the nodes
|
||||
// in this system. Doing so greatly simplifies testing.
|
||||
|
||||
typedef enum { role_ping_out = 1, role_pong_back } role_e; // The various roles supported by this sketch
|
||||
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"}; // The debug-friendly names of those roles
|
||||
role_e role = role_pong_back; // The role of the current running sketch
|
||||
|
||||
// A single byte to keep track of the data being sent back and forth
|
||||
byte counter = 1;
|
||||
|
||||
void setup() {
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
Serial.print(F("\n\rRF24/examples/pingpair_ack/\n\rROLE: "));
|
||||
Serial.println(role_friendly_name[role]);
|
||||
Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
|
||||
|
||||
// Setup and configure rf 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(pipes[1]); // Both radios listen on the same pipes by default, and switch when writing
|
||||
radio.openReadingPipe(1, pipes[0]);
|
||||
radio.startListening(); // Start listening
|
||||
radio.printDetails(); // Dump the configuration of the rf unit for debugging
|
||||
}
|
||||
|
||||
void loop(void) {
|
||||
if (role == role_ping_out) {
|
||||
radio.stopListening(); // First, stop listening so we can talk.
|
||||
|
||||
printf("Now sending %d as payload. ", counter);
|
||||
byte gotByte;
|
||||
unsigned long time = micros(); // Take the time, and send it. This will block until complete
|
||||
//Called when STANDBY-I mode is engaged (User is finished sending)
|
||||
if (!radio.write(&counter, 1)) {
|
||||
Serial.println(F("failed."));
|
||||
} else {
|
||||
if (!radio.available()) {
|
||||
Serial.println(F("Blank Payload Received."));
|
||||
} else {
|
||||
while (radio.available()) {
|
||||
unsigned long tim = micros();
|
||||
radio.read(&gotByte, 1);
|
||||
printf("Got response %d, round-trip delay: %lu microseconds\n\r", gotByte, tim - time);
|
||||
counter++;
|
||||
}
|
||||
}
|
||||
}
|
||||
// Try again later
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
// Pong back role. Receive each packet, dump it out, and send it back
|
||||
|
||||
if (role == role_pong_back) {
|
||||
byte pipeNo;
|
||||
byte gotByte; // Dump the payloads until we've gotten everything
|
||||
while (radio.available(&pipeNo)) {
|
||||
radio.read(&gotByte, 1);
|
||||
radio.writeAckPayload(pipeNo, &gotByte, 1);
|
||||
Serial.print(F("Received message and replied at "));
|
||||
Serial.println(millis());
|
||||
}
|
||||
}
|
||||
|
||||
// Change roles
|
||||
|
||||
if (Serial.available()) {
|
||||
char c = toupper(Serial.read());
|
||||
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)
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1, pipes[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.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1, pipes[0]);
|
||||
radio.startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
206
arduino-cli/libraries/RF24/examples/pingpair_dyn/Jamfile
Normal file
206
arduino-cli/libraries/RF24/examples/pingpair_dyn/Jamfile
Normal file
@@ -0,0 +1,206 @@
|
||||
PROJECT_NAME = $(PWD:B) ;
|
||||
PROJECT_DIR = . ;
|
||||
PROJECT_LIBS = SPI RF24 ;
|
||||
|
||||
OUT_DIR = ojam ;
|
||||
F_CPU = 16000000 ;
|
||||
MCU = atmega328p ;
|
||||
PORTS = /dev/tty.usbserial-A600eHIs /dev/tty.usbserial-A40081RP /dev/tty.usbserial-A9007LmI ;
|
||||
|
||||
UPLOAD_RATE = 57600 ;
|
||||
AVRDUDE_PROTOCOL = stk500v1 ;
|
||||
COM = 33 ;
|
||||
|
||||
# Host-specific overrides for locations
|
||||
if $(OS) = MACOSX
|
||||
{
|
||||
ARDUINO_VERSION = 22 ;
|
||||
OLD_DIR = /opt/arduino-0021 ;
|
||||
AVR_TOOLS_PATH = $(OLD_DIR)/hardware/tools/avr/bin ;
|
||||
AVRDUDECONFIG_PATH = $(OLD_DIR)/hardware/tools/avr/etc ;
|
||||
ARDUINO_DIR = /opt/Arduino ;
|
||||
ARDUINO_AVR = /usr/lib/avr/include ;
|
||||
}
|
||||
|
||||
# Where is everything?
|
||||
ARDUINO_VERSION ?= 22 ;
|
||||
AVR_TOOLS_PATH ?= /usr/bin ;
|
||||
ARDUINO_DIR ?= /opt/arduino-00$(ARDUINO_VERSION) ;
|
||||
ARDUINO_AVR ?= $(ARDUINO_DIR)/hardware/tools/avr/avr/include/avr ;
|
||||
AVRDUDECONFIG_PATH ?= $(ARDUINO_DIR)/hardware/tools ;
|
||||
ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/arduino ;
|
||||
ARDUINO_LIB = $(ARDUINO_DIR)/libraries ;
|
||||
SKETCH_LIB = $(HOME)/Source/Arduino/libraries ;
|
||||
AVR_CC = $(AVR_TOOLS_PATH)/avr-gcc ;
|
||||
AVR_CXX = $(AVR_TOOLS_PATH)/avr-g++ ;
|
||||
AVR_LD = $(AVR_TOOLS_PATH)/avr-gcc ;
|
||||
AVR_OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy ;
|
||||
AVRDUDE = $(AVR_TOOLS_PATH)/avrdude ;
|
||||
|
||||
DEFINES = F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ;
|
||||
CTUNING = -ffunction-sections -fdata-sections ;
|
||||
CXXTUNING = -fno-exceptions -fno-strict-aliasing ;
|
||||
CFLAGS = -Os -Wall -Wextra -mmcu=$(MCU) $(CTUNING) ;
|
||||
CXXFLAGS = $(CFLAGS) $(CXXTUNING) ;
|
||||
LDFLAGS = -Os -lm -Wl,--gc-sections -mmcu=atmega328p ;
|
||||
|
||||
# Search everywhere for headers
|
||||
HDRS = $(PROJECT_DIR) $(ARDUINO_AVR) $(ARDUINO_CORE) [ GLOB $(ARDUINO_LIB) $(SKETCH_LIB) : [^.]* ] ;
|
||||
|
||||
# Grab everything from the core directory
|
||||
CORE_MODULES = [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ;
|
||||
|
||||
# Grab everything from libraries. To avoid this "grab everything" behaviour, you
|
||||
# can specify specific modules to pick up in PROJECT_MODULES
|
||||
LIB_MODULES = [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp ] ;
|
||||
|
||||
# In addition to explicitly-specified program modules, pick up anything from the current
|
||||
# dir.
|
||||
PROJECT_MODULES += [ GLOB $(PROJECT_DIR) : *.c *.cpp *.pde ] ;
|
||||
|
||||
# Shortcut for the out files
|
||||
OUT = $(OUT_DIR)/$(PROJECT_NAME) ;
|
||||
|
||||
# AvrDude setup
|
||||
AVRDUDE_FLAGS = -V -F -D -C $(AVRDUDECONFIG_PATH)/avrdude.conf -p $(MCU) -c $(AVRDUDE_PROTOCOL) -b $(UPLOAD_RATE) ;
|
||||
|
||||
rule GitVersion
|
||||
{
|
||||
Always $(<) ;
|
||||
Depends all : $(<) ;
|
||||
}
|
||||
|
||||
actions GitVersion
|
||||
{
|
||||
echo "const char program_version[] = \"\\" > $(<)
|
||||
git log -1 --pretty=format:%h >> $(<)
|
||||
echo "\";" >> $(<)
|
||||
}
|
||||
|
||||
GitVersion version.h ;
|
||||
|
||||
rule AvrCc
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
actions AvrCc
|
||||
{
|
||||
$(AVR_CC) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CFLAGS) $(>)
|
||||
}
|
||||
|
||||
rule AvrC++
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
actions AvrC++
|
||||
{
|
||||
$(AVR_CXX) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CXXFLAGS) $(>)
|
||||
}
|
||||
|
||||
rule Pde
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
}
|
||||
|
||||
actions Pde
|
||||
{
|
||||
echo "#include <WProgram.h>" > $(<)
|
||||
echo "#line 1 \"$(>)\"" >> $(<)
|
||||
cat $(>) >> $(<)
|
||||
}
|
||||
|
||||
rule AvrPde
|
||||
{
|
||||
local _CPP = $(OUT_DIR)/$(_I:B).cpp ;
|
||||
Pde $(_CPP) : $(>) ;
|
||||
AvrC++ $(<) : $(_CPP) ;
|
||||
}
|
||||
|
||||
rule AvrObject
|
||||
{
|
||||
switch $(>:S)
|
||||
{
|
||||
case .c : AvrCc $(<) : $(>) ;
|
||||
case .cpp : AvrC++ $(<) : $(>) ;
|
||||
case .pde : AvrPde $(<) : $(>) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule AvrObjects
|
||||
{
|
||||
for _I in $(<)
|
||||
{
|
||||
AvrObject $(OUT_DIR)/$(_I:B).o : $(_I) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule AvrMainFromObjects
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
MkDir $(<:D) ;
|
||||
Depends all : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions AvrMainFromObjects
|
||||
{
|
||||
$(AVR_LD) $(LDFLAGS) -o $(<) $(>)
|
||||
}
|
||||
|
||||
rule AvrMain
|
||||
{
|
||||
AvrMainFromObjects $(<) : $(OUT_DIR)/$(>:B).o ;
|
||||
AvrObjects $(>) ;
|
||||
}
|
||||
|
||||
rule AvrHex
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Depends hex : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions AvrHex
|
||||
{
|
||||
$(AVR_OBJCOPY) -O ihex -R .eeprom $(>) $(<)
|
||||
}
|
||||
|
||||
rule AvrUpload
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
Depends $(2) : $(3) ;
|
||||
NotFile $(1) ;
|
||||
Always $(1) ;
|
||||
Always $(2) ;
|
||||
AvrUploadAction $(2) : $(3) ;
|
||||
}
|
||||
|
||||
actions AvrUploadAction
|
||||
{
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i
|
||||
}
|
||||
|
||||
AvrMain $(OUT).elf : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ;
|
||||
AvrHex $(OUT).hex : $(OUT).elf ;
|
||||
|
||||
AvrUpload p6 : /dev/tty.usbserial-A600eHIs : $(OUT).hex ;
|
||||
AvrUpload p4 : /dev/tty.usbserial-A40081RP : $(OUT).hex ;
|
||||
AvrUpload p9 : /dev/tty.usbserial-A9007LmI : $(OUT).hex ;
|
||||
|
||||
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example using Dynamic Payloads
|
||||
*
|
||||
* This is an example of how to use payloads of a varying (dynamic) size.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
|
||||
RF24 radio(7, 8);
|
||||
|
||||
// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
|
||||
// Leave open to be the 'ping' transmitter
|
||||
const int role_pin = 5;
|
||||
|
||||
//
|
||||
// Topology
|
||||
//
|
||||
|
||||
// Radio pipe addresses for the 2 nodes to communicate.
|
||||
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };
|
||||
|
||||
//
|
||||
// Role management
|
||||
//
|
||||
// Set up role. This sketch uses the same software for all the nodes
|
||||
// in this system. Doing so greatly simplifies testing. The hardware itself specifies
|
||||
// which node it is.
|
||||
//
|
||||
// This is done through the role_pin
|
||||
//
|
||||
|
||||
// The various roles supported by this sketch
|
||||
typedef enum { role_ping_out = 1, role_pong_back } role_e;
|
||||
|
||||
// The debug-friendly names of those roles
|
||||
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};
|
||||
|
||||
// The role of the current running sketch
|
||||
role_e role;
|
||||
|
||||
//
|
||||
// Payload
|
||||
//
|
||||
|
||||
const int min_payload_size = 4;
|
||||
const int max_payload_size = 32;
|
||||
const int payload_size_increments_by = 1;
|
||||
int next_payload_size = min_payload_size;
|
||||
|
||||
char receive_payload[max_payload_size + 1]; // +1 to allow room for a terminating NULL char
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Role
|
||||
//
|
||||
|
||||
// set up the role pin
|
||||
pinMode(role_pin, INPUT);
|
||||
digitalWrite(role_pin,HIGH);
|
||||
delay(20); // Just to get a solid reading on the role pin
|
||||
|
||||
// read the address pin, establish our role
|
||||
if (digitalRead(role_pin)) {
|
||||
role = role_ping_out;
|
||||
} else {
|
||||
role = role_pong_back;
|
||||
}
|
||||
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
|
||||
Serial.println(F("RF24/examples/pingpair_dyn/"));
|
||||
Serial.print(F("ROLE: "));
|
||||
Serial.println(role_friendly_name[role]);
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
radio.begin();
|
||||
|
||||
// Enable dynamic payloads
|
||||
radio.enableDynamicPayloads();
|
||||
|
||||
// Optionally, increase the delay between retries & # of retries
|
||||
radio.setRetries(5, 15);
|
||||
|
||||
//
|
||||
// Open pipes to other nodes for communication
|
||||
//
|
||||
|
||||
// This simple sketch opens two pipes for these two nodes to communicate
|
||||
// back and forth.
|
||||
// Open 'our' pipe for writing
|
||||
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
|
||||
if (role == role_ping_out) {
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1, pipes[1]);
|
||||
} else {
|
||||
radio.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1, pipes[0]);
|
||||
}
|
||||
|
||||
//
|
||||
// Start listening
|
||||
//
|
||||
radio.startListening();
|
||||
|
||||
//
|
||||
// Dump the configuration of the rf unit for debugging
|
||||
//
|
||||
radio.printDetails();
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
//
|
||||
// Ping out role. Repeatedly send the current time
|
||||
//
|
||||
|
||||
if (role == role_ping_out) {
|
||||
// The payload will always be the same, what will change is how much of it we send.
|
||||
static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012";
|
||||
|
||||
// First, stop listening so we can talk.
|
||||
radio.stopListening();
|
||||
|
||||
// Take the time, and send it. This will block until complete
|
||||
Serial.print(F("Now sending length "));
|
||||
Serial.println(next_payload_size);
|
||||
radio.write(send_payload, next_payload_size);
|
||||
|
||||
// Now, continue listening
|
||||
radio.startListening();
|
||||
|
||||
// Wait here until we get a response, or timeout
|
||||
unsigned long started_waiting_at = millis();
|
||||
bool timeout = false;
|
||||
while (!radio.available() && !timeout) {
|
||||
if (millis() - started_waiting_at > 500 ) {
|
||||
timeout = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Describe the results
|
||||
if (timeout) {
|
||||
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
|
||||
Serial.print(F("Got response size="));
|
||||
Serial.print(len);
|
||||
Serial.print(F(" value="));
|
||||
Serial.println(receive_payload);
|
||||
}
|
||||
|
||||
// Update size for next time.
|
||||
next_payload_size += payload_size_increments_by;
|
||||
if (next_payload_size > max_payload_size) {
|
||||
next_payload_size = min_payload_size;
|
||||
}
|
||||
|
||||
// Try again 1s later
|
||||
delay(100);
|
||||
}
|
||||
|
||||
//
|
||||
// Pong back role. Receive each packet, dump it out, and send it back
|
||||
//
|
||||
|
||||
if (role == role_pong_back) {
|
||||
// if there is data ready
|
||||
while (radio.available()) {
|
||||
|
||||
// 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 a reply that the packet was received
|
||||
// you could also use the ACK functionality
|
||||
//
|
||||
// You might have a bit better luck delivering your message
|
||||
// if you wait for the other side to start listening first
|
||||
delay(20);
|
||||
radio.write(receive_payload, len);
|
||||
Serial.println(F("Sent response."));
|
||||
|
||||
// Now, resume listening so we catch the next packets.
|
||||
radio.startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim:cin:ai:sts=2 sw=2 ft=cpp
|
||||
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
Update 2014 - TMRh20
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example of using interrupts
|
||||
*
|
||||
* This is an example of how to user interrupts to interact with the radio, and a demonstration
|
||||
* of how to use them to sleep when receiving, and not miss any payloads.
|
||||
* The pingpair_sleepy example expands on sleep functionality with a timed sleep option for the transmitter.
|
||||
* Sleep functionality is built directly into my fork of the RF24Network library
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
// Hardware configuration
|
||||
RF24 radio(7,8); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
|
||||
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
|
||||
|
||||
// Demonstrates another method of setting up the addresses
|
||||
byte address[][5] = { 0xCC,0xCE,0xCC,0xCE,0xCC , 0xCE,0xCC,0xCE,0xCC,0xCE};
|
||||
|
||||
// Role management
|
||||
|
||||
// Set up role. This sketch uses the same software for all the nodes in this
|
||||
// system. Doing so greatly simplifies testing. The hardware itself specifies
|
||||
// which node it is.
|
||||
// This is done through the role_pin
|
||||
typedef enum { role_sender = 1, role_receiver } role_e; // The various roles supported by this sketch
|
||||
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
|
||||
|
||||
static uint32_t message_count = 0;
|
||||
|
||||
|
||||
/********************** Setup *********************/
|
||||
|
||||
void setup(){
|
||||
|
||||
pinMode(role_pin, INPUT); // set up the role pin
|
||||
digitalWrite(role_pin,HIGH); // Change this to LOW/HIGH instead of using an external pin
|
||||
delay(20); // Just to get a solid reading on the role pin
|
||||
|
||||
if ( digitalRead(role_pin) ) // read the address pin, establish our role
|
||||
role = role_sender;
|
||||
else
|
||||
role = role_receiver;
|
||||
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
Serial.print(F("\n\rRF24/examples/pingpair_irq\n\rROLE: "));
|
||||
Serial.println(role_friendly_name[role]);
|
||||
|
||||
// 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.
|
||||
radio.openReadingPipe(1,address[1]);
|
||||
}else{
|
||||
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
|
||||
delay(50);
|
||||
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 (role == role_sender) { // Sender role. Repeatedly send the current time
|
||||
unsigned long time = millis(); // Take the time, and send it.
|
||||
Serial.print(F("Now sending "));
|
||||
Serial.println(time);
|
||||
radio.startWrite( &time, sizeof(unsigned long) ,0);
|
||||
delay(2000); // Try again soon
|
||||
}
|
||||
|
||||
|
||||
if(role == role_receiver){ // Receiver does nothing except in IRQ
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************** 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 ( tx ) { // Have we successfully transmitted?
|
||||
if ( role == role_sender ){ Serial.println(F("Send:OK")); }
|
||||
if ( role == role_receiver ){ Serial.println(F("Ack Payload:Sent")); }
|
||||
}
|
||||
|
||||
if ( fail ) { // Have we failed to transmit?
|
||||
if ( role == role_sender ){ Serial.println(F("Send:Failed")); }
|
||||
if ( role == role_receiver ){ Serial.println(F("Ack Payload:Failed")); }
|
||||
}
|
||||
|
||||
if ( rx || radio.available()){ // Did we receive a message?
|
||||
|
||||
if ( role == role_sender ) { // If we're the sender, we've received an ack payload
|
||||
radio.read(&message_count,sizeof(message_count));
|
||||
Serial.print(F("Ack: "));
|
||||
Serial.println(message_count);
|
||||
}
|
||||
|
||||
|
||||
if ( role == role_receiver ) { // If we're the receiver, we've received a time message
|
||||
static unsigned long got_time; // Get this payload and dump it
|
||||
radio.read( &got_time, sizeof(got_time) );
|
||||
Serial.print(F("Got payload "));
|
||||
Serial.println(got_time);
|
||||
radio.writeAckPayload( 1, &message_count, sizeof(message_count) ); // Add an ack packet for the next time around. This is a simple
|
||||
++message_count; // packet counter
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
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(); You must uncomment this if you wish to use printDetails()
|
||||
|
||||
// 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.print(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();
|
||||
// Normal delay will not work here, so cycle through some no-operations (16nops @16mhz = 1us delay)
|
||||
for(uint32_t i=0; i<130;i++){
|
||||
__asm__("nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t""nop\n\t");
|
||||
}
|
||||
radio.startWrite(&pong,sizeof(pong),0);
|
||||
Serial.print("pong");
|
||||
}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(":OK") : F(":Fail"));
|
||||
}
|
||||
}
|
||||
206
arduino-cli/libraries/RF24/examples/pingpair_multi_dyn/Jamfile
Normal file
206
arduino-cli/libraries/RF24/examples/pingpair_multi_dyn/Jamfile
Normal file
@@ -0,0 +1,206 @@
|
||||
PROJECT_NAME = $(PWD:B) ;
|
||||
PROJECT_DIR = . ;
|
||||
PROJECT_LIBS = SPI RF24 ;
|
||||
|
||||
OUT_DIR = ojam ;
|
||||
F_CPU = 16000000 ;
|
||||
MCU = atmega328p ;
|
||||
PORTS = /dev/tty.usbserial-A600eHIs /dev/tty.usbserial-A40081RP /dev/tty.usbserial-A9007LmI ;
|
||||
|
||||
UPLOAD_RATE = 57600 ;
|
||||
AVRDUDE_PROTOCOL = stk500v1 ;
|
||||
COM = 33 ;
|
||||
|
||||
# Host-specific overrides for locations
|
||||
if $(OS) = MACOSX
|
||||
{
|
||||
ARDUINO_VERSION = 22 ;
|
||||
OLD_DIR = /opt/arduino-0021 ;
|
||||
AVR_TOOLS_PATH = $(OLD_DIR)/hardware/tools/avr/bin ;
|
||||
AVRDUDECONFIG_PATH = $(OLD_DIR)/hardware/tools/avr/etc ;
|
||||
ARDUINO_DIR = /opt/Arduino ;
|
||||
ARDUINO_AVR = /usr/lib/avr/include ;
|
||||
}
|
||||
|
||||
# Where is everything?
|
||||
ARDUINO_VERSION ?= 22 ;
|
||||
AVR_TOOLS_PATH ?= /usr/bin ;
|
||||
ARDUINO_DIR ?= /opt/arduino-00$(ARDUINO_VERSION) ;
|
||||
ARDUINO_AVR ?= $(ARDUINO_DIR)/hardware/tools/avr/avr/include/avr ;
|
||||
AVRDUDECONFIG_PATH ?= $(ARDUINO_DIR)/hardware/tools ;
|
||||
ARDUINO_CORE = $(ARDUINO_DIR)/hardware/arduino/cores/arduino ;
|
||||
ARDUINO_LIB = $(ARDUINO_DIR)/libraries ;
|
||||
SKETCH_LIB = $(HOME)/Source/Arduino/libraries ;
|
||||
AVR_CC = $(AVR_TOOLS_PATH)/avr-gcc ;
|
||||
AVR_CXX = $(AVR_TOOLS_PATH)/avr-g++ ;
|
||||
AVR_LD = $(AVR_TOOLS_PATH)/avr-gcc ;
|
||||
AVR_OBJCOPY = $(AVR_TOOLS_PATH)/avr-objcopy ;
|
||||
AVRDUDE = $(AVR_TOOLS_PATH)/avrdude ;
|
||||
|
||||
DEFINES = F_CPU=$(F_CPU)L ARDUINO=$(ARDUINO_VERSION) VERSION_H ;
|
||||
CTUNING = -ffunction-sections -fdata-sections ;
|
||||
CXXTUNING = -fno-exceptions -fno-strict-aliasing ;
|
||||
CFLAGS = -Os -Wall -Wextra -mmcu=$(MCU) $(CTUNING) ;
|
||||
CXXFLAGS = $(CFLAGS) $(CXXTUNING) ;
|
||||
LDFLAGS = -Os -lm -Wl,--gc-sections -mmcu=atmega328p ;
|
||||
|
||||
# Search everywhere for headers
|
||||
HDRS = $(PROJECT_DIR) $(ARDUINO_AVR) $(ARDUINO_CORE) [ GLOB $(ARDUINO_LIB) $(SKETCH_LIB) : [^.]* ] ;
|
||||
|
||||
# Grab everything from the core directory
|
||||
CORE_MODULES = [ GLOB $(ARDUINO_CORE) : *.c *.cpp ] ;
|
||||
|
||||
# Grab everything from libraries. To avoid this "grab everything" behaviour, you
|
||||
# can specify specific modules to pick up in PROJECT_MODULES
|
||||
LIB_MODULES = [ GLOB $(ARDUINO_LIB)/$(PROJECT_LIBS) $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp ] ;
|
||||
|
||||
# In addition to explicitly-specified program modules, pick up anything from the current
|
||||
# dir.
|
||||
PROJECT_MODULES += [ GLOB $(PROJECT_DIR) : *.c *.cpp *.pde ] ;
|
||||
|
||||
# Shortcut for the out files
|
||||
OUT = $(OUT_DIR)/$(PROJECT_NAME) ;
|
||||
|
||||
# AvrDude setup
|
||||
AVRDUDE_FLAGS = -V -F -D -C $(AVRDUDECONFIG_PATH)/avrdude.conf -p $(MCU) -c $(AVRDUDE_PROTOCOL) -b $(UPLOAD_RATE) ;
|
||||
|
||||
rule GitVersion
|
||||
{
|
||||
Always $(<) ;
|
||||
Depends all : $(<) ;
|
||||
}
|
||||
|
||||
actions GitVersion
|
||||
{
|
||||
echo "const char program_version[] = \"\\" > $(<)
|
||||
git log -1 --pretty=format:%h >> $(<)
|
||||
echo "\";" >> $(<)
|
||||
}
|
||||
|
||||
GitVersion version.h ;
|
||||
|
||||
rule AvrCc
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
actions AvrCc
|
||||
{
|
||||
$(AVR_CC) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CFLAGS) $(>)
|
||||
}
|
||||
|
||||
rule AvrC++
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
CCHDRS on $(<) = [ on $(<) FIncludes $(HDRS) ] ;
|
||||
CCDEFS on $(<) = [ on $(<) FDefines $(DEFINES) ] ;
|
||||
}
|
||||
|
||||
actions AvrC++
|
||||
{
|
||||
$(AVR_CXX) -c -o $(<) $(CCHDRS) $(CCDEFS) $(CXXFLAGS) $(>)
|
||||
}
|
||||
|
||||
rule Pde
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Clean clean : $(<) ;
|
||||
|
||||
}
|
||||
|
||||
actions Pde
|
||||
{
|
||||
echo "#include <WProgram.h>" > $(<)
|
||||
echo "#line 1 \"$(>)\"" >> $(<)
|
||||
cat $(>) >> $(<)
|
||||
}
|
||||
|
||||
rule AvrPde
|
||||
{
|
||||
local _CPP = $(OUT_DIR)/$(_I:B).cpp ;
|
||||
Pde $(_CPP) : $(>) ;
|
||||
AvrC++ $(<) : $(_CPP) ;
|
||||
}
|
||||
|
||||
rule AvrObject
|
||||
{
|
||||
switch $(>:S)
|
||||
{
|
||||
case .c : AvrCc $(<) : $(>) ;
|
||||
case .cpp : AvrC++ $(<) : $(>) ;
|
||||
case .pde : AvrPde $(<) : $(>) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule AvrObjects
|
||||
{
|
||||
for _I in $(<)
|
||||
{
|
||||
AvrObject $(OUT_DIR)/$(_I:B).o : $(_I) ;
|
||||
}
|
||||
}
|
||||
|
||||
rule AvrMainFromObjects
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
MkDir $(<:D) ;
|
||||
Depends all : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions AvrMainFromObjects
|
||||
{
|
||||
$(AVR_LD) $(LDFLAGS) -o $(<) $(>)
|
||||
}
|
||||
|
||||
rule AvrMain
|
||||
{
|
||||
AvrMainFromObjects $(<) : $(OUT_DIR)/$(>:B).o ;
|
||||
AvrObjects $(>) ;
|
||||
}
|
||||
|
||||
rule AvrHex
|
||||
{
|
||||
Depends $(<) : $(>) ;
|
||||
Depends $(<) : $(<:D) ;
|
||||
Depends hex : $(<) ;
|
||||
Clean clean : $(<) ;
|
||||
}
|
||||
|
||||
actions AvrHex
|
||||
{
|
||||
$(AVR_OBJCOPY) -O ihex -R .eeprom $(>) $(<)
|
||||
}
|
||||
|
||||
rule AvrUpload
|
||||
{
|
||||
Depends $(1) : $(2) ;
|
||||
Depends $(2) : $(3) ;
|
||||
NotFile $(1) ;
|
||||
Always $(1) ;
|
||||
Always $(2) ;
|
||||
AvrUploadAction $(2) : $(3) ;
|
||||
}
|
||||
|
||||
actions AvrUploadAction
|
||||
{
|
||||
$(AVRDUDE) $(AVRDUDE_FLAGS) -P $(<) $(AVRDUDE_WRITE_FLASH) -U flash:w:$(>):i
|
||||
}
|
||||
|
||||
AvrMain $(OUT).elf : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ;
|
||||
AvrHex $(OUT).hex : $(OUT).elf ;
|
||||
|
||||
AvrUpload p6 : /dev/tty.usbserial-A600eHIs : $(OUT).hex ;
|
||||
AvrUpload p4 : /dev/tty.usbserial-A40081RP : $(OUT).hex ;
|
||||
AvrUpload p9 : /dev/tty.usbserial-A9007LmI : $(OUT).hex ;
|
||||
|
||||
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
Copyright (C) 2011 James Coliz, Jr. <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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example using Dynamic Payloads
|
||||
*
|
||||
* This is an example of how to use payloads of a varying (dynamic) size.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "RF24.h"
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 8 & 9
|
||||
RF24 radio(8,9);
|
||||
|
||||
// Use multicast?
|
||||
// sets the multicast behavior this unit in hardware. Connect to GND to use unicast
|
||||
// Leave open (default) to use multicast.
|
||||
const int multicast_pin = 6 ;
|
||||
|
||||
// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
|
||||
// Leave open to be the 'ping' transmitter
|
||||
const int role_pin = 7;
|
||||
bool multicast = true ;
|
||||
|
||||
//
|
||||
// Topology
|
||||
//
|
||||
|
||||
// Radio pipe addresses for the 2 nodes to communicate.
|
||||
const uint64_t pipes[2] = { 0xEEFAFDFDEELL, 0xEEFDFAF50DFLL };
|
||||
|
||||
//
|
||||
// Role management
|
||||
//
|
||||
// Set up role. This sketch uses the same software for all the nodes
|
||||
// in this system. Doing so greatly simplifies testing. The hardware itself specifies
|
||||
// which node it is.
|
||||
//
|
||||
// This is done through the role_pin
|
||||
//
|
||||
|
||||
// The various roles supported by this sketch
|
||||
typedef enum { role_ping_out = 1, role_pong_back } role_e;
|
||||
|
||||
// The debug-friendly names of those roles
|
||||
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};
|
||||
|
||||
// The role of the current running sketch
|
||||
role_e role;
|
||||
|
||||
//
|
||||
// Payload
|
||||
//
|
||||
|
||||
const int min_payload_size = 1;
|
||||
const int max_payload_size = 32;
|
||||
const int payload_size_increments_by = 1;
|
||||
int next_payload_size = min_payload_size;
|
||||
|
||||
char receive_payload[max_payload_size+1]; // +1 to allow room for a terminating NULL char
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Multicast
|
||||
//
|
||||
pinMode(multicast_pin, INPUT);
|
||||
digitalWrite(multicast_pin,HIGH);
|
||||
delay( 20 ) ;
|
||||
|
||||
// read multicast role, LOW for unicast
|
||||
if( digitalRead( multicast_pin ) )
|
||||
multicast = true ;
|
||||
else
|
||||
multicast = false ;
|
||||
|
||||
|
||||
//
|
||||
// Role
|
||||
//
|
||||
|
||||
// set up the role pin
|
||||
pinMode(role_pin, INPUT);
|
||||
digitalWrite(role_pin,HIGH);
|
||||
delay( 20 ); // Just to get a solid reading on the role pin
|
||||
|
||||
// read the address pin, establish our role
|
||||
if ( digitalRead(role_pin) )
|
||||
role = role_ping_out;
|
||||
else
|
||||
role = role_pong_back;
|
||||
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
Serial.begin(115200);
|
||||
|
||||
Serial.println(F("RF24/examples/pingpair_multi_dyn/"));
|
||||
Serial.print(F("ROLE: "));
|
||||
Serial.println(role_friendly_name[role]);
|
||||
|
||||
Serial.print(F("MULTICAST: "));
|
||||
Serial.println(multicast ? F("true (unreliable)") : F("false (reliable)"));
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
|
||||
radio.begin();
|
||||
|
||||
// enable dynamic payloads
|
||||
radio.enableDynamicPayloads();
|
||||
radio.setCRCLength( RF24_CRC_16 ) ;
|
||||
|
||||
// optionally, increase the delay between retries & # of retries
|
||||
radio.setRetries( 15, 5 ) ;
|
||||
radio.setAutoAck( true ) ;
|
||||
//radio.setPALevel( RF24_PA_LOW ) ;
|
||||
|
||||
//
|
||||
// Open pipes to other nodes for communication
|
||||
//
|
||||
|
||||
// This simple sketch opens two pipes for these two nodes to communicate
|
||||
// back and forth.
|
||||
// Open 'our' pipe for writing
|
||||
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
|
||||
|
||||
if ( role == role_ping_out )
|
||||
{
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1,pipes[1]);
|
||||
}
|
||||
else
|
||||
{
|
||||
radio.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1,pipes[0]);
|
||||
}
|
||||
|
||||
//
|
||||
// Start listening
|
||||
//
|
||||
radio.powerUp() ;
|
||||
radio.startListening();
|
||||
|
||||
//
|
||||
// Dump the configuration of the rf unit for debugging
|
||||
//
|
||||
|
||||
radio.printDetails();
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
//
|
||||
// Ping out role. Repeatedly send the current time
|
||||
//
|
||||
|
||||
if (role == role_ping_out)
|
||||
{
|
||||
// The payload will always be the same, what will change is how much of it we send.
|
||||
static char send_payload[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ789012";
|
||||
|
||||
// First, stop listening so we can talk.
|
||||
radio.stopListening();
|
||||
|
||||
// Take the time, and send it. This will block until complete
|
||||
Serial.print(F("Now sending length "));
|
||||
Serial.println(next_payload_size);
|
||||
radio.write( send_payload, next_payload_size, multicast );
|
||||
|
||||
// Now, continue listening
|
||||
radio.startListening();
|
||||
|
||||
// Wait here until we get a response, or timeout
|
||||
unsigned long started_waiting_at = millis();
|
||||
bool timeout = false;
|
||||
while ( ! radio.available() && ! timeout )
|
||||
if (millis() - started_waiting_at > 500 )
|
||||
timeout = true;
|
||||
|
||||
// Describe the results
|
||||
if ( timeout )
|
||||
{
|
||||
Serial.println(F("Failed, response timed out."));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grab the response, compare, and send to debugging spew
|
||||
uint8_t len = radio.getDynamicPayloadSize();
|
||||
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);
|
||||
}
|
||||
|
||||
// Update size for next time.
|
||||
next_payload_size += payload_size_increments_by;
|
||||
if ( next_payload_size > max_payload_size )
|
||||
next_payload_size = min_payload_size;
|
||||
|
||||
// Try again 1s later
|
||||
delay(250);
|
||||
}
|
||||
|
||||
//
|
||||
// Pong back role. Receive each packet, dump it out, and send it back
|
||||
//
|
||||
|
||||
if ( role == role_pong_back )
|
||||
{
|
||||
// if there is data ready
|
||||
if ( 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
|
||||
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, multicast );
|
||||
Serial.println(F("Sent response."));
|
||||
|
||||
// Now, resume listening so we catch the next packets.
|
||||
radio.startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim:cin:ai:sts=2 sw=2 ft=cpp
|
||||
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
TMRh20 2014 - Updates to the library allow sleeping both in TX and RX modes:
|
||||
TX Mode: The radio can be powered down (.9uA current) and the Arduino slept using the watchdog timer
|
||||
RX Mode: The radio can be left in standby mode (22uA current) and the Arduino slept using an interrupt pin
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example RF Radio Ping Pair which Sleeps between Sends
|
||||
*
|
||||
* This is an example of how to use the RF24 class to create a battery-
|
||||
* efficient system. It is just like the GettingStarted_CallResponse example, but the
|
||||
* ping node powers down the radio and sleeps the MCU after every
|
||||
* ping/pong cycle, and the receiver sleeps between payloads.
|
||||
*
|
||||
* Write this sketch to two different nodes,
|
||||
* connect the role_pin to ground on one. 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.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/power.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
RF24 radio(7,8);
|
||||
|
||||
// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
|
||||
// Leave open to be the 'ping' transmitter
|
||||
const int role_pin = 5;
|
||||
|
||||
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; // Radio pipe addresses for the 2 nodes to communicate.
|
||||
|
||||
// Role management
|
||||
// Set up role. This sketch uses the same software for all the nodes
|
||||
// in this system. Doing so greatly simplifies testing. The hardware itself specifies
|
||||
// which node it is.
|
||||
|
||||
// The various roles supported by this sketch
|
||||
typedef enum { role_ping_out = 1, role_pong_back } role_e;
|
||||
|
||||
// The debug-friendly names of those roles
|
||||
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};
|
||||
|
||||
// The role of the current running sketch
|
||||
role_e role;
|
||||
|
||||
|
||||
// Sleep declarations
|
||||
typedef enum { wdt_16ms = 0, wdt_32ms, wdt_64ms, wdt_128ms, wdt_250ms, wdt_500ms, wdt_1s, wdt_2s, wdt_4s, wdt_8s } wdt_prescalar_e;
|
||||
|
||||
void setup_watchdog(uint8_t prescalar);
|
||||
void do_sleep(void);
|
||||
|
||||
const short sleep_cycles_per_transmission = 4;
|
||||
volatile short sleep_cycles_remaining = sleep_cycles_per_transmission;
|
||||
|
||||
|
||||
|
||||
void setup(){
|
||||
|
||||
// set up the role pin
|
||||
pinMode(role_pin, INPUT);
|
||||
digitalWrite(role_pin,HIGH);
|
||||
delay(20); // Just to get a solid reading on the role pin
|
||||
|
||||
// read the address pin, establish our role
|
||||
if ( digitalRead(role_pin) )
|
||||
role = role_ping_out;
|
||||
else
|
||||
role = role_pong_back;
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
Serial.print(F("\n\rRF24/examples/pingpair_sleepy/\n\rROLE: "));
|
||||
Serial.println(role_friendly_name[role]);
|
||||
|
||||
// Prepare sleep parameters
|
||||
// Only the ping out role uses WDT. Wake up every 4s to send a ping
|
||||
//if ( role == role_ping_out )
|
||||
setup_watchdog(wdt_4s);
|
||||
|
||||
// Setup and configure rf radio
|
||||
|
||||
radio.begin();
|
||||
|
||||
// Open pipes to other nodes for communication
|
||||
|
||||
// This simple sketch opens two pipes for these two nodes to communicate
|
||||
// back and forth.
|
||||
// Open 'our' pipe for writing
|
||||
// Open the 'other' pipe for reading, in position #1 (we can have up to 5 pipes open for reading)
|
||||
|
||||
if ( role == role_ping_out ) {
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1,pipes[1]);
|
||||
} else {
|
||||
radio.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1,pipes[0]);
|
||||
}
|
||||
|
||||
// Start listening
|
||||
radio.startListening();
|
||||
|
||||
// Dump the configuration of the rf unit for debugging
|
||||
//radio.printDetails();
|
||||
}
|
||||
|
||||
void loop(){
|
||||
|
||||
|
||||
if (role == role_ping_out) { // Ping out role. Repeatedly send the current time
|
||||
radio.powerUp(); // Power up the radio after sleeping
|
||||
radio.stopListening(); // First, stop listening so we can talk.
|
||||
|
||||
unsigned long time = millis(); // Take the time, and send it.
|
||||
Serial.print(F("Now sending... "));
|
||||
Serial.println(time);
|
||||
|
||||
radio.write( &time, sizeof(unsigned long) );
|
||||
|
||||
radio.startListening(); // Now, continue listening
|
||||
|
||||
unsigned long started_waiting_at = millis(); // Wait here until we get a response, or timeout (250ms)
|
||||
bool timeout = false;
|
||||
while ( ! radio.available() ){
|
||||
if (millis() - started_waiting_at > 250 ){ // Break out of the while loop if nothing available
|
||||
timeout = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( timeout ) { // Describe the results
|
||||
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) );
|
||||
|
||||
printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
|
||||
}
|
||||
|
||||
// Shut down the system
|
||||
delay(500); // Experiment with some delay here to see if it has an effect
|
||||
// Power down the radio.
|
||||
radio.powerDown(); // NOTE: The radio MUST be powered back up again manually
|
||||
|
||||
// Sleep the MCU.
|
||||
do_sleep();
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
// Pong back role. Receive each packet, dump it out, and send it back
|
||||
if ( role == role_pong_back ) {
|
||||
|
||||
if ( radio.available() ) { // if there is data ready
|
||||
|
||||
unsigned long got_time;
|
||||
while (radio.available()) { // Dump the payloads until we've gotten everything
|
||||
radio.read( &got_time, sizeof(unsigned long) ); // Get the payload, and see if this was the last one.
|
||||
// Spew it. Include our time, because the ping_out millis counter is unreliable
|
||||
printf("Got payload %lu @ %lu...",got_time,millis()); // due to it sleeping
|
||||
}
|
||||
|
||||
radio.stopListening(); // First, stop listening so we can talk
|
||||
radio.write( &got_time, sizeof(unsigned long) ); // Send the final one back.
|
||||
Serial.println(F("Sent response."));
|
||||
radio.startListening(); // Now, resume listening so we catch the next packets.
|
||||
} else {
|
||||
Serial.println(F("Sleeping"));
|
||||
delay(50); // Delay so the serial data can print out
|
||||
do_sleep();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void wakeUp(){
|
||||
sleep_disable();
|
||||
}
|
||||
|
||||
// Sleep helpers
|
||||
|
||||
//Prescaler values
|
||||
// 0=16ms, 1=32ms,2=64ms,3=125ms,4=250ms,5=500ms
|
||||
// 6=1 sec,7=2 sec, 8=4 sec, 9= 8sec
|
||||
|
||||
void setup_watchdog(uint8_t prescalar){
|
||||
|
||||
uint8_t wdtcsr = prescalar & 7;
|
||||
if ( prescalar & 8 )
|
||||
wdtcsr |= _BV(WDP3);
|
||||
MCUSR &= ~_BV(WDRF); // Clear the WD System Reset Flag
|
||||
WDTCSR = _BV(WDCE) | _BV(WDE); // Write the WD Change enable bit to enable changing the prescaler and enable system reset
|
||||
WDTCSR = _BV(WDCE) | wdtcsr | _BV(WDIE); // Write the prescalar bits (how long to sleep, enable the interrupt to wake the MCU
|
||||
}
|
||||
|
||||
ISR(WDT_vect)
|
||||
{
|
||||
//--sleep_cycles_remaining;
|
||||
Serial.println(F("WDT"));
|
||||
}
|
||||
|
||||
void do_sleep(void)
|
||||
{
|
||||
set_sleep_mode(SLEEP_MODE_PWR_DOWN); // sleep mode is set here
|
||||
sleep_enable();
|
||||
attachInterrupt(0,wakeUp,LOW);
|
||||
WDTCSR |= _BV(WDIE);
|
||||
sleep_mode(); // System sleeps here
|
||||
// The WDT_vect interrupt wakes the MCU from here
|
||||
sleep_disable(); // System continues execution here when watchdog timed out
|
||||
detachInterrupt(0);
|
||||
WDTCSR &= ~_BV(WDIE);
|
||||
}
|
||||
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
rf24ping85.ino by tong67 ( https://github.com/tong67 )
|
||||
This is an example of how to use the RF24 class to communicate with ATtiny85 and other node.
|
||||
Write this sketch to an ATtiny85. It will act like the 'transmit' mode of GettingStarted.ino
|
||||
Write GettingStarted.ino sketch to UNO (or other board or RPi) and put the node in 'receiver' mode.
|
||||
The ATtiny85 will transmit a counting number every second starting from 1.
|
||||
The ATtiny85 uses the tiny-core by CodingBadly (https://code.google.com/p/arduino-tiny/)
|
||||
When direct use of 3v3 does not work (UNO boards have bad 3v3 line) use 5v with LED (1.8V ~ 2.2V drop)
|
||||
For low power consumption solutions floating pins (SCK and MOSI) should be pulled high or low with eg. 10K
|
||||
|
||||
** Hardware configuration **
|
||||
ATtiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 4
|
||||
+-\/-+
|
||||
NC PB5 1|o |8 Vcc --- nRF24L01 VCC, pin2 --- LED --- 5V
|
||||
nRF24L01 CE, pin3 --- PB3 2| |7 PB2 --- nRF24L01 SCK, pin5
|
||||
nRF24L01 CSN, pin4 --- PB4 3| |6 PB1 --- nRF24L01 MOSI, pin7
|
||||
nRF24L01 GND, pin1 --- GND 4| |5 PB0 --- nRF24L01 MISO, pin6
|
||||
+----+
|
||||
|
||||
ATtiny25/45/85 Pin map with CE_PIN 3 and CSN_PIN 3 => PB3 and PB4 are free to use for application
|
||||
Circuit idea from http://nerdralph.blogspot.ca/2014/01/nrf24l01-control-with-3-attiny85-pins.html
|
||||
Original RC combination was 1K/100nF. 22K/10nF combination worked better.
|
||||
For best settletime delay value in RF24::csn() the timingSearch3pin.ino scatch can be used.
|
||||
This configuration is enabled when CE_PIN and CSN_PIN are equal, e.g. both 3
|
||||
Because CE is always high the power consumption is higher than for 5 pins solution
|
||||
^^
|
||||
+-\/-+ nRF24L01 CE, pin3 ------| //
|
||||
PB5 1|o |8 Vcc --- nRF24L01 VCC, pin2 ------x----------x--|<|-- 5V
|
||||
NC PB3 2| |7 PB2 --- nRF24L01 SCK, pin5 --|<|---x-[22k]--| LED
|
||||
NC PB4 3| |6 PB1 --- nRF24L01 MOSI, pin6 1n4148 |
|
||||
nRF24L01 GND, pin1 -x- GND 4| |5 PB0 --- nRF24L01 MISO, pin7 |
|
||||
| +----+ |
|
||||
|-----------------------------------------------||----x-- nRF24L01 CSN, pin4
|
||||
10nF
|
||||
|
||||
ATtiny24/44/84 Pin map with CE_PIN 8 and CSN_PIN 7
|
||||
Schematic provided and successfully tested by Carmine Pastore (https://github.com/Carminepz)
|
||||
+-\/-+
|
||||
nRF24L01 VCC, pin2 --- VCC 1|o |14 GND --- nRF24L01 GND, pin1
|
||||
PB0 2| |13 AREF
|
||||
PB1 3| |12 PA1
|
||||
PB3 4| |11 PA2 --- nRF24L01 CE, pin3
|
||||
PB2 5| |10 PA3 --- nRF24L01 CSN, pin4
|
||||
PA7 6| |9 PA4 --- nRF24L01 SCK, pin5
|
||||
nRF24L01 MOSI, pin7 --- PA6 7| |8 PA5 --- nRF24L01 MISO, pin6
|
||||
+----+
|
||||
*/
|
||||
|
||||
// CE and CSN are configurable, specified values for ATtiny85 as connected above
|
||||
#define CE_PIN 3
|
||||
#define CSN_PIN 4
|
||||
//#define CSN_PIN 3 // uncomment for ATtiny85 3 pins solution
|
||||
|
||||
#include "RF24.h"
|
||||
|
||||
RF24 radio(CE_PIN, CSN_PIN);
|
||||
|
||||
byte addresses[][6] = {
|
||||
"1Node","2Node"};
|
||||
unsigned long payload = 0;
|
||||
|
||||
void setup() {
|
||||
// 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]); // Write to device address '2Node'
|
||||
radio.openReadingPipe(1,addresses[0]); // Read on pipe 1 for device address '1Node'
|
||||
radio.startListening(); // Start listening
|
||||
}
|
||||
|
||||
void loop(void){
|
||||
|
||||
radio.stopListening(); // First, stop listening so we can talk.
|
||||
payload++;
|
||||
radio.write( &payload, sizeof(unsigned long) );
|
||||
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
|
||||
unsigned long got_time; // Grab the response, compare, and send to debugging spew
|
||||
radio.read( &got_time, sizeof(unsigned long) );
|
||||
}
|
||||
|
||||
// Try again 1s later
|
||||
delay(1000);
|
||||
}
|
||||
@@ -0,0 +1,396 @@
|
||||
/*
|
||||
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.
|
||||
|
||||
timingSearch3pin.ino by tong67 ( https://github.com/tong67 )
|
||||
This sketch can be used to determine the best settleTime values to use in RF24::csn().
|
||||
The used settleTimeValues are 100/20. Depend on used RC combiniation and voltage drop by LED.
|
||||
It is setup to be completely selfcontained, copied defines and code from RF24 library.
|
||||
The ATtiny85 uses the tiny-core by CodingBadly (https://code.google.com/p/arduino-tiny/)
|
||||
(Intermediate) results are written to TX (PB3, pin 2). For schematic see rf24ping85.ino
|
||||
*/
|
||||
|
||||
// nRF24L01.h copy
|
||||
|
||||
/* Memory Map */
|
||||
#define CONFIG 0x00
|
||||
#define EN_AA 0x01
|
||||
#define EN_RXADDR 0x02
|
||||
#define SETUP_AW 0x03
|
||||
#define SETUP_RETR 0x04
|
||||
#define RF_CH 0x05
|
||||
#define RF_SETUP 0x06
|
||||
#define STATUS 0x07
|
||||
#define OBSERVE_TX 0x08
|
||||
#define CD 0x09
|
||||
#define RX_ADDR_P0 0x0A
|
||||
#define RX_ADDR_P1 0x0B
|
||||
#define RX_ADDR_P2 0x0C
|
||||
#define RX_ADDR_P3 0x0D
|
||||
#define RX_ADDR_P4 0x0E
|
||||
#define RX_ADDR_P5 0x0F
|
||||
#define TX_ADDR 0x10
|
||||
#define RX_PW_P0 0x11
|
||||
#define RX_PW_P1 0x12
|
||||
#define RX_PW_P2 0x13
|
||||
#define RX_PW_P3 0x14
|
||||
#define RX_PW_P4 0x15
|
||||
#define RX_PW_P5 0x16
|
||||
#define FIFO_STATUS 0x17
|
||||
#define DYNPD 0x1C
|
||||
#define FEATURE 0x1D
|
||||
|
||||
/* Bit Mnemonics */
|
||||
#define MASK_RX_DR 6
|
||||
#define MASK_TX_DS 5
|
||||
#define MASK_MAX_RT 4
|
||||
#define EN_CRC 3
|
||||
#define CRCO 2
|
||||
#define PWR_UP 1
|
||||
#define PRIM_RX 0
|
||||
#define ENAA_P5 5
|
||||
#define ENAA_P4 4
|
||||
#define ENAA_P3 3
|
||||
#define ENAA_P2 2
|
||||
#define ENAA_P1 1
|
||||
#define ENAA_P0 0
|
||||
#define ERX_P5 5
|
||||
#define ERX_P4 4
|
||||
#define ERX_P3 3
|
||||
#define ERX_P2 2
|
||||
#define ERX_P1 1
|
||||
#define ERX_P0 0
|
||||
#define AW 0
|
||||
#define ARD 4
|
||||
#define ARC 0
|
||||
#define PLL_LOCK 4
|
||||
#define RF_DR 3
|
||||
#define RF_PWR 6
|
||||
#define RX_DR 6
|
||||
#define TX_DS 5
|
||||
#define MAX_RT 4
|
||||
#define RX_P_NO 1
|
||||
#define TX_FULL 0
|
||||
#define PLOS_CNT 4
|
||||
#define ARC_CNT 0
|
||||
#define TX_REUSE 6
|
||||
#define FIFO_FULL 5
|
||||
#define TX_EMPTY 4
|
||||
#define RX_FULL 1
|
||||
#define RX_EMPTY 0
|
||||
#define DPL_P5 5
|
||||
#define DPL_P4 4
|
||||
#define DPL_P3 3
|
||||
#define DPL_P2 2
|
||||
#define DPL_P1 1
|
||||
#define DPL_P0 0
|
||||
#define EN_DPL 2
|
||||
#define EN_ACK_PAY 1
|
||||
#define EN_DYN_ACK 0
|
||||
|
||||
/* Instruction Mnemonics */
|
||||
#define R_REGISTER 0x00
|
||||
#define W_REGISTER 0x20
|
||||
#define REGISTER_MASK 0x1F
|
||||
#define ACTIVATE 0x50
|
||||
#define R_RX_PL_WID 0x60
|
||||
#define R_RX_PAYLOAD 0x61
|
||||
#define W_TX_PAYLOAD 0xA0
|
||||
#define W_ACK_PAYLOAD 0xA8
|
||||
#define FLUSH_TX 0xE1
|
||||
#define FLUSH_RX 0xE2
|
||||
#define REUSE_TX_PL 0xE3
|
||||
#define RF24_NOP 0xFF
|
||||
|
||||
/* Non-P omissions */
|
||||
#define LNA_HCURR 0
|
||||
|
||||
/* P model memory Map */
|
||||
#define RPD 0x09
|
||||
#define W_TX_PAYLOAD_NO_ACK 0xB0
|
||||
|
||||
/* P model bit Mnemonics */
|
||||
#define RF_DR_LOW 5
|
||||
#define RF_DR_HIGH 3
|
||||
#define RF_PWR_LOW 1
|
||||
#define RF_PWR_HIGH 2
|
||||
/****************************************************************************/
|
||||
|
||||
//ATTiny support code pulled in from https://github.com/jscrane/RF24
|
||||
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__)
|
||||
// see http://gammon.com.au/spi
|
||||
# define DI 0 // D0, pin 5 Data In
|
||||
# define DO 1 // D1, pin 6 Data Out (this is *not* MOSI)
|
||||
# define USCK 2 // D2, pin 7 Universal Serial Interface clock
|
||||
# define SS 3 // D3, pin 2 Slave Select
|
||||
#elif defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
||||
// these depend on the core used (check pins_arduino.h)
|
||||
// this is for jeelabs' one (based on google-code core)
|
||||
# define DI 4 // PA6
|
||||
# define DO 5 // PA5
|
||||
# define USCK 6 // PA4
|
||||
# define SS 3 // PA7
|
||||
#endif
|
||||
|
||||
#if defined (ARDUINO) && !defined (__arm__)
|
||||
#if defined(__AVR_ATtiny25__) || defined(__AVR_ATtiny45__) || defined(__AVR_ATtiny85__) || defined(__AVR_ATtiny24__) || defined(__AVR_ATtiny44__) || defined(__AVR_ATtiny84__)
|
||||
#define RF24_TINY
|
||||
#else
|
||||
// #include <SPI.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(RF24_TINY)
|
||||
#include <stdio.h>
|
||||
#include <Arduino.h>
|
||||
#include <avr/pgmspace.h>
|
||||
|
||||
#define SPI_CLOCK_DIV4 0x00
|
||||
#define SPI_CLOCK_DIV16 0x01
|
||||
#define SPI_CLOCK_DIV64 0x02
|
||||
#define SPI_CLOCK_DIV128 0x03
|
||||
#define SPI_CLOCK_DIV2 0x04
|
||||
#define SPI_CLOCK_DIV8 0x05
|
||||
#define SPI_CLOCK_DIV32 0x06
|
||||
//#define SPI_CLOCK_DIV64 0x07
|
||||
|
||||
#define SPI_MODE0 0x00
|
||||
#define SPI_MODE1 0x04
|
||||
#define SPI_MODE2 0x08
|
||||
#define SPI_MODE3 0x0C
|
||||
|
||||
#define SPI_MODE_MASK 0x0C // CPOL = bit 3, CPHA = bit 2 on SPCR
|
||||
#define SPI_CLOCK_MASK 0x03 // SPR1 = bit 1, SPR0 = bit 0 on SPCR
|
||||
#define SPI_2XCLOCK_MASK 0x01 // SPI2X = bit 0 on SPSR
|
||||
|
||||
class SPIClass {
|
||||
public:
|
||||
static byte transfer(byte _data);
|
||||
|
||||
// SPI Configuration methods
|
||||
|
||||
inline static void attachInterrupt();
|
||||
inline static void detachInterrupt(); // Default
|
||||
|
||||
static void begin(); // Default
|
||||
static void end();
|
||||
|
||||
// static void setBitOrder(uint8_t);
|
||||
// static void setDataMode(uint8_t);
|
||||
// static void setClockDivider(uint8_t);
|
||||
};
|
||||
extern SPIClass SPI;
|
||||
|
||||
#endif /* RF24_TINY */
|
||||
|
||||
|
||||
#if defined(RF24_TINY)
|
||||
|
||||
void SPIClass::begin() {
|
||||
digitalWrite(SS, HIGH);
|
||||
pinMode(USCK, OUTPUT);
|
||||
pinMode(DO, OUTPUT);
|
||||
pinMode(SS, OUTPUT);
|
||||
pinMode(DI, INPUT);
|
||||
USICR = _BV(USIWM0);
|
||||
}
|
||||
|
||||
byte SPIClass::transfer(byte b) {
|
||||
USIDR = b;
|
||||
USISR = _BV(USIOIF);
|
||||
do
|
||||
USICR = _BV(USIWM0) | _BV(USICS1) | _BV(USICLK) | _BV(USITC);
|
||||
while ((USISR & _BV(USIOIF)) == 0);
|
||||
return USIDR;
|
||||
}
|
||||
|
||||
void SPIClass::end() {}
|
||||
|
||||
#endif /* RF24_TINY */
|
||||
|
||||
/****************************************************************************/
|
||||
uint8_t ce_pin; /**< "Chip Enable" pin, activates the RX or TX role */
|
||||
uint8_t csn_pin; /**< SPI Chip select */
|
||||
uint8_t csnHighSettle = 255;
|
||||
uint8_t csnLowSettle = 255;
|
||||
/****************************************************************************/
|
||||
void ce(bool level) {
|
||||
if (ce_pin != csn_pin) digitalWrite(ce_pin,level);
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
void setCsnHighSettle(uint8_t level) {
|
||||
csnHighSettle = level;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
void setCsnLowSettle(uint8_t level) {
|
||||
csnLowSettle = level;
|
||||
}
|
||||
/****************************************************************************/
|
||||
void csn(bool mode) {
|
||||
if (ce_pin != csn_pin) {
|
||||
digitalWrite(csn_pin,mode);
|
||||
} else {
|
||||
if (mode == HIGH) {
|
||||
PORTB |= (1<<PINB2); // SCK->CSN HIGH
|
||||
delayMicroseconds(csnHighSettle); // allow csn to settle
|
||||
} else {
|
||||
PORTB &= ~(1<<PINB2); // SCK->CSN LOW
|
||||
delayMicroseconds(csnLowSettle); // allow csn to settle
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
uint8_t read_register(uint8_t reg)
|
||||
{
|
||||
csn(LOW);
|
||||
SPI.transfer( R_REGISTER | ( REGISTER_MASK & reg ) );
|
||||
uint8_t result = SPI.transfer(0xff);
|
||||
csn(HIGH);
|
||||
return result;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
uint8_t write_register2(uint8_t reg, uint8_t value)
|
||||
{
|
||||
uint8_t status;
|
||||
|
||||
csn(LOW);
|
||||
status = SPI.transfer( W_REGISTER | ( REGISTER_MASK & reg ) );
|
||||
SPI.transfer(value);
|
||||
csn(HIGH);
|
||||
return status;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
#if defined(RF24_TINY)
|
||||
#define CE_PIN 3
|
||||
#define CSN_PIN 3
|
||||
#else
|
||||
#define CE_PIN 7
|
||||
#define CSN_PIN 8
|
||||
#endif
|
||||
|
||||
#define MAX_HIGH 100
|
||||
#define MAX_LOW 100
|
||||
#define MINIMAL 8
|
||||
|
||||
void setup(void) {
|
||||
uint8_t status;
|
||||
|
||||
// start serial port and SPI
|
||||
Serial.begin(9600);
|
||||
SPI.begin();
|
||||
|
||||
// configure ce and scn as output when used
|
||||
ce_pin = CE_PIN;
|
||||
csn_pin = CSN_PIN;
|
||||
|
||||
setCsnHighSettle(MAX_HIGH);
|
||||
setCsnLowSettle(MAX_LOW);
|
||||
// csn is used in SPI transfers. Set to LOW at start and HIGH after transfer. Set to HIGH to reflect no transfer active
|
||||
// SPI command are accepted in Power Down state.
|
||||
// ce represent PRX (LOW) or PTX (HIGH) mode apart from register settings. Start in PRX mode.
|
||||
ce(LOW);
|
||||
csn(HIGH);
|
||||
|
||||
// nRF24L01 goes from to Power Down state 100ms after Power on Reset ( Vdd > 1.9V) or when PWR_UP is 0 in config register
|
||||
// Goto Power Down state (Powerup or force) and set in transmit mode
|
||||
write_register2(CONFIG, read_register(CONFIG) & ~_BV(PWR_UP) & ~_BV(PRIM_RX));
|
||||
delay(100);
|
||||
|
||||
// Goto Standby-I
|
||||
// Technically we require 4.5ms Tpd2stby+ 14us as a worst case. We'll just call it 5ms for good measure.
|
||||
// WARNING: Delay is based on P-variant whereby non-P *may* require different timing.
|
||||
write_register2(CONFIG, read_register(CONFIG) | _BV(PWR_UP));
|
||||
delay(5) ;
|
||||
|
||||
// Goto Standby-II
|
||||
ce(HIGH);
|
||||
Serial.print("Scanning for optimal setting time for scn");
|
||||
}
|
||||
|
||||
|
||||
void loop(void) {
|
||||
uint8_t status;
|
||||
uint8_t i;
|
||||
uint8_t j;
|
||||
uint8_t k;
|
||||
bool success = true;
|
||||
uint8_t csnHigh = MAX_HIGH;
|
||||
uint8_t csnLow = MAX_LOW;
|
||||
uint8_t bottom_success;
|
||||
bool bottom_found;
|
||||
uint8_t value[] = {5,10};
|
||||
uint8_t limit[] = {MAX_HIGH,MAX_LOW};
|
||||
uint8_t advice[] = {MAX_HIGH,MAX_LOW};
|
||||
|
||||
// check max values give correct behavior
|
||||
for (k=0;k<2;k++) {
|
||||
bottom_found = false;
|
||||
bottom_success = 0;
|
||||
while(bottom_success < 255) {
|
||||
setCsnHighSettle(limit[0]);
|
||||
setCsnLowSettle(limit[1]);
|
||||
// check current values
|
||||
i = 0;
|
||||
while(i<255 & success) {
|
||||
for (j=0;j<2;j++) {
|
||||
write_register2(EN_AA, value[j]);
|
||||
status = read_register(EN_AA);
|
||||
if (value[j] != status) {
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
i++;
|
||||
}
|
||||
// process result of current values
|
||||
if (!success) {
|
||||
Serial.print("Settle NOK. csnHigh=");
|
||||
Serial.print(limit[0],DEC);
|
||||
Serial.print(" csnLow=");
|
||||
Serial.println(limit[1],DEC);
|
||||
limit[k]++;
|
||||
bottom_found = true;
|
||||
bottom_success = 0;
|
||||
success = true;
|
||||
} else {
|
||||
Serial.print("Settle OK. csnHigh=");
|
||||
Serial.print(limit[0],DEC);
|
||||
Serial.print(" csnLow=");
|
||||
Serial.println(limit[1],DEC);
|
||||
if (!bottom_found) {
|
||||
limit[k]--;
|
||||
if (limit[k] == MINIMAL) {
|
||||
bottom_found = true;
|
||||
bottom_success = 0;
|
||||
success = true;
|
||||
}
|
||||
} else {
|
||||
bottom_success++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Serial.print("Settle value found for ");
|
||||
if (k == 0) {
|
||||
Serial.print("csnHigh: ");
|
||||
} else {
|
||||
Serial.print("csnLow: ");
|
||||
}
|
||||
Serial.println(limit[k],DEC);
|
||||
advice[k] = limit[k] + (limit[k] / 10);
|
||||
limit[k] = 100;
|
||||
}
|
||||
Serial.print("Adviced Settle times are: csnHigh=");
|
||||
Serial.print(advice[0],DEC);
|
||||
Serial.print(" csnLow=");
|
||||
Serial.println(advice[1],DEC);
|
||||
while (true)
|
||||
{
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
BIN
arduino-cli/libraries/RF24/examples/scanner/output/core.a
Normal file
BIN
arduino-cli/libraries/RF24/examples/scanner/output/core.a
Normal file
Binary file not shown.
128
arduino-cli/libraries/RF24/examples/scanner/output/scanner.cpp
Normal file
128
arduino-cli/libraries/RF24/examples/scanner/output/scanner.cpp
Normal file
@@ -0,0 +1,128 @@
|
||||
#include <WProgram.h>
|
||||
#line 1 "scanner.pde"
|
||||
|
||||
/*
|
||||
Copyright (C) 2011 James Coliz, Jr. <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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Channel scanner
|
||||
*
|
||||
* Example to detect interference on the various channels available.
|
||||
* This is a good diagnostic tool to check whether you're picking a
|
||||
* good channel for your application.
|
||||
*
|
||||
* Inspired by cpixip.
|
||||
* See http://arduino.cc/forum/index.php/topic,54795.0.html
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 8 & 9
|
||||
|
||||
RF24 radio(8,9);
|
||||
|
||||
//
|
||||
// Channel info
|
||||
//
|
||||
|
||||
const short num_channels = 128;
|
||||
short values[num_channels];
|
||||
|
||||
//
|
||||
// Setup
|
||||
//
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/scanner/\n\r");
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
|
||||
radio.begin();
|
||||
radio.setAutoAck(false);
|
||||
|
||||
// Get into standby mode
|
||||
radio.startListening();
|
||||
radio.stopListening();
|
||||
|
||||
// Print out header, high then low digit
|
||||
int i = 0;
|
||||
while ( i < num_channels )
|
||||
{
|
||||
printf("%x",i>>4);
|
||||
++i;
|
||||
}
|
||||
printf("\n\r");
|
||||
i = 0;
|
||||
while ( i < num_channels )
|
||||
{
|
||||
printf("%x",i&0xf);
|
||||
++i;
|
||||
}
|
||||
printf("\n\r");
|
||||
}
|
||||
|
||||
//
|
||||
// Loop
|
||||
//
|
||||
|
||||
const short num_reps = 100;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// Clear measurement values
|
||||
memset(values,0,num_channels);
|
||||
|
||||
// Scan all channels num_reps times
|
||||
int rep_counter = num_reps;
|
||||
while (rep_counter--)
|
||||
{
|
||||
int i = num_channels;
|
||||
while (i--)
|
||||
{
|
||||
// Select this channel
|
||||
radio.setChannel(i);
|
||||
|
||||
// Listen for a little
|
||||
radio.startListening();
|
||||
delayMicroseconds(128);
|
||||
radio.stopListening();
|
||||
|
||||
// Did we get a carrier?
|
||||
if ( radio.testCarrier() )
|
||||
++values[i];
|
||||
}
|
||||
}
|
||||
|
||||
// Print out channel measurements, clamped to a single hex digit
|
||||
int i = 0;
|
||||
while ( i < num_channels )
|
||||
{
|
||||
printf("%x",min(0xf,values[i]&0xf));
|
||||
++i;
|
||||
}
|
||||
printf("\n\r");
|
||||
}
|
||||
|
||||
|
||||
// vim:ai:cin:sts=2 sw=2 ft=cpp
|
||||
BIN
arduino-cli/libraries/RF24/examples/scanner/output/scanner.elf
Normal file
BIN
arduino-cli/libraries/RF24/examples/scanner/output/scanner.elf
Normal file
Binary file not shown.
325
arduino-cli/libraries/RF24/examples/scanner/output/scanner.hex
Normal file
325
arduino-cli/libraries/RF24/examples/scanner/output/scanner.hex
Normal file
@@ -0,0 +1,325 @@
|
||||
:100000000C9463000C948B000C948B000C948B006C
|
||||
:100010000C948B000C948B000C948B000C948B0034
|
||||
:100020000C948B000C948B000C948B000C948B0024
|
||||
:100030000C948B000C948B000C948B000C948B0014
|
||||
:100040000C948F050C948B000C9423060C948B005D
|
||||
:100050000C948B000C948B000C948B000C948B00F4
|
||||
:100060000C948B000C948B000000000024002700EF
|
||||
:100070002A0000000000250028002B0000000000DE
|
||||
:1000800023002600290004040404040404040202DA
|
||||
:100090000202020203030303030301020408102007
|
||||
:1000A0004080010204081020010204081020000012
|
||||
:1000B0000007000201000003040600000000000029
|
||||
:1000C000000090043B0711241FBECFEFD8E0DEBF35
|
||||
:1000D000CDBF11E0A0E0B1E0E6EFF3E102C0059092
|
||||
:1000E0000D92AA33B107D9F712E0AAE3B1E001C03B
|
||||
:1000F0001D92A13FB107E1F710E0C6ECD0E004C0CB
|
||||
:100100002297FE010E94F509C23CD107C9F70E945F
|
||||
:100110001C060C94F9090C9400000F931F93CF93C5
|
||||
:10012000DF938C01EB01009731F46115710519F42F
|
||||
:1001300020E030E038C081E090E06EE070E00E94A6
|
||||
:10014000CB02FC019C01009771F180E8838320972A
|
||||
:1001500071F0D387C28781E883838091E702909111
|
||||
:10016000E802892B21F4F093E802E093E7020115FD
|
||||
:100170001105C9F011870087838182608383809194
|
||||
:10018000E9029091EA02892B71F4F093EA02E0937C
|
||||
:10019000E9028091EB029091EC02892B21F4F0931B
|
||||
:1001A000EC02E093EB02C901DF91CF911F910F9117
|
||||
:1001B0000895A0E0B0E0EFEDF0E00C94CC09FE0172
|
||||
:1001C0003596619171918091E9029091EA02AF01B7
|
||||
:1001D0000E94EE002096E2E00C94E809ABE0B0E06B
|
||||
:1001E000E4EFF0E00C94BC093C012B015A01FC0146
|
||||
:1001F00017821682838181FD03C06FEF7FEFC6C136
|
||||
:100200009AE0892E1E010894211C311CF3012381E0
|
||||
:10021000F20123FD859123FF81912F01882309F4A9
|
||||
:10022000B2C1853239F423FD859123FF81912F01DD
|
||||
:10023000853229F490E0B3010E940604E7CF982F9D
|
||||
:10024000FF24EE249924FFE1FF15D0F09B3269F0E2
|
||||
:100250009C3228F4903259F0933291F40EC09D32C2
|
||||
:1002600049F0903369F441E024C052E0F52A84E07B
|
||||
:10027000F82A28C098E0F92A25C0E0E1FE2A22C029
|
||||
:10028000F7FC29C0892F80538A3070F4F6FE05C030
|
||||
:10029000989C902C1124980E15C0E89CE02C1124F9
|
||||
:1002A000E80EF0E2FF2A0EC09E3229F4F6FC6BC184
|
||||
:1002B00040E4F42A07C09C3619F450E8F52A02C03D
|
||||
:1002C000983649F4F20123FD959123FF91912F0176
|
||||
:1002D000992309F0B8CF892F8554833018F08052C4
|
||||
:1002E000833038F444E050E0A40EB51E5FE3598338
|
||||
:1002F0000FC0933631F0933779F0933509F056C03B
|
||||
:1003000020C0F5018081898342E050E0A40EB51E33
|
||||
:10031000610101E010E012C0F501C080D180F6FC5F
|
||||
:1003200003C06FEF7FEF02C0692D70E042E050E044
|
||||
:10033000A40EB51EC6010E94FB038C015FE7F522E7
|
||||
:1003400014C0F501C080D180F6FC03C06FEF7FEFD1
|
||||
:1003500002C0692D70E042E050E0A40EB51EC60157
|
||||
:100360000E94E9038C0150E8F52AF3FE07C01AC089
|
||||
:1003700080E290E0B3010E940604EA948E2D90E0A2
|
||||
:1003800008171907A8F30EC0F601F7FC8591F7FED0
|
||||
:1003900081916F0190E0B3010E940604E110EA949C
|
||||
:1003A000015010400115110579F7EAC0943611F09B
|
||||
:1003B000993669F5F7FE08C0F50120813181428147
|
||||
:1003C000538184E090E00AC0F501808191819C0115
|
||||
:1003D000442737FD4095542F82E090E0A80EB91EC7
|
||||
:1003E0009FE6F92257FF09C0509540953095219519
|
||||
:1003F0003F4F4F4F5F4FE0E8FE2ACA01B901A1010C
|
||||
:100400002AE030E00E943204D82ED21840C095373E
|
||||
:1004100029F41F2D1F7E2AE030E01DC01F2D197FFB
|
||||
:100420009F3661F0903720F4983509F0ACC00FC0CA
|
||||
:10043000903739F0983709F0A6C004C028E030E0C2
|
||||
:100440000AC0106114FD146020E130E004C014FD06
|
||||
:10045000166020E132E017FF08C0F501608171816C
|
||||
:100460008281938144E050E008C0F5018081918150
|
||||
:10047000BC0180E090E042E050E0A40EB51EA10176
|
||||
:100480000E943204D82ED2188FE7F82EF122F6FE01
|
||||
:100490000BC05EEFF522D91438F4F4FE07C0F2FC6D
|
||||
:1004A00005C08FEEF82202C01D2D01C0192DF4FEEB
|
||||
:1004B0000DC0FE01ED0DF11D8081803319F499EE20
|
||||
:1004C000F92208C01F5FF2FE05C003C08F2D867899
|
||||
:1004D00009F01F5F0F2DF3FC14C0F0FE0FC01E15B6
|
||||
:1004E00010F09D2C0BC09D2C9E0C911A1E2D06C049
|
||||
:1004F00080E290E0B3010E9406041F5F1E15C0F366
|
||||
:1005000004C01E1510F4E11A01C0EE2404FF0FC050
|
||||
:1005100080E390E0B3010E94060402FF1DC001FDCC
|
||||
:1005200003C088E790E00EC088E590E00BC0802F04
|
||||
:10053000867891F001FF02C08BE201C080E2F7FCF7
|
||||
:100540008DE290E0B3010E94060406C080E390E0D3
|
||||
:10055000B3010E9406049A94D914C0F3DA94F1010D
|
||||
:10056000ED0DF11D808190E0B3010E940604DD20B5
|
||||
:10057000A9F706C080E290E0B3010E940604EA9465
|
||||
:10058000EE20C1F743CEF30166817781CB012B9634
|
||||
:10059000E2E10C94D8090F931F93CF93DF93689FE8
|
||||
:1005A0008001699F100D789F100D1124C8010E94D1
|
||||
:1005B000E702EC01009729F060E070E0A8010E94DA
|
||||
:1005C000F403CE01DF91CF911F910F910895CF9346
|
||||
:1005D000DF93BC018230910510F462E070E0A091DD
|
||||
:1005E000EF02B091F002ED01E0E0F0E040E050E019
|
||||
:1005F00021C0888199818617970769F48A819B8138
|
||||
:10060000309719F09383828304C09093F002809313
|
||||
:10061000EF02FE0134C06817790738F4411551051F
|
||||
:1006200019F08417950708F4AC01FE018A819B81BB
|
||||
:100630009C01E9012097E9F641155105A9F1CA018C
|
||||
:10064000861B970B049708F4BA01E0E0F0E02AC09B
|
||||
:100650008D919C91119784179507F9F4641775078C
|
||||
:1006600081F412968D919C911397309719F0938392
|
||||
:10067000828304C09093F0028093EF02FD013296D2
|
||||
:100680004CC0CA01861B970BFD01E80FF91F61934F
|
||||
:10069000719302978D939C9340C0FD018281938159
|
||||
:1006A0009C01D9011097A1F68091ED029091EE0284
|
||||
:1006B000892B41F480912301909124019093EE02C3
|
||||
:1006C0008093ED024091250150912601411551057D
|
||||
:1006D00041F44DB75EB78091210190912201481BF2
|
||||
:1006E000590B2091ED023091EE02CA01821B930B4F
|
||||
:1006F0008617970780F0AB014E5F5F4F8417950711
|
||||
:1007000050F0420F531F5093EE024093ED02F90157
|
||||
:100710006193719302C0E0E0F0E0CF01DF91CF91EF
|
||||
:100720000895CF93DF93009709F450C0EC0122970E
|
||||
:100730001B821A82A091EF02B091F002109709F18A
|
||||
:1007400040E050E0AC17BD0708F1BB83AA83FE016F
|
||||
:1007500021913191E20FF31FAE17BF0779F48D910C
|
||||
:100760009C911197280F391F2E5F3F4F39832883A3
|
||||
:1007700012968D919C9113979B838A834115510505
|
||||
:1007800071F4D093F002C093EF0220C012968D91C5
|
||||
:100790009C911397AD01009711F0DC01D3CFFA01C2
|
||||
:1007A000D383C28321913191E20FF31FCE17DF076C
|
||||
:1007B00069F488819981280F391F2E5F3F4FFA0114
|
||||
:1007C000318320838A819B8193838283DF91CF91C0
|
||||
:1007D0000895FC010590615070400110D8F7809594
|
||||
:1007E00090958E0F9F1F0895DC0101C06D934150BD
|
||||
:1007F0005040E0F70895FC016150704001900110F5
|
||||
:10080000D8F7809590958E0F9F1F08950F931F9393
|
||||
:10081000CF93DF938C01EB018B8181FF1BC082FFA3
|
||||
:100820000DC02E813F818C819D812817390764F48A
|
||||
:10083000E881F9810193F983E88306C0E885F985A9
|
||||
:10084000802F0995892B31F48E819F8101969F839A
|
||||
:100850008E8302C00FEF1FEFC801DF91CF911F9170
|
||||
:100860000F910895FA01AA27283051F1203181F122
|
||||
:10087000E8946F936E7F6E5F7F4F8F4F9F4FAF4FA8
|
||||
:10088000B1E03ED0B4E03CD0670F781F891F9A1FBB
|
||||
:10089000A11D680F791F8A1F911DA11D6A0F711D6F
|
||||
:1008A000811D911DA11D20D009F468943F912AE07B
|
||||
:1008B000269F11243019305D3193DEF6CF01089563
|
||||
:1008C000462F4770405D4193B3E00FD0C9F7F6CF94
|
||||
:1008D000462F4F70405D4A3318F0495D31FD40525C
|
||||
:1008E000419302D0A9F7EACFB4E0A69597958795F2
|
||||
:1008F00077956795BA95C9F70097610571050895D1
|
||||
:100900009B01AC010A2E069457954795379527957C
|
||||
:10091000BA95C9F7620F731F841F951FA01D089514
|
||||
:100920008AE391E068E049E00E9475070895FF922C
|
||||
:100930000F931F93CF93DF9380E8E7E4F1E0DF01AB
|
||||
:100940001D928A95E9F704E610E021C08AE391E060
|
||||
:100950006F2D0E94F2078AE391E00E94840880E8EC
|
||||
:1009600090E00E94D7058AE391E00E947C078AE329
|
||||
:1009700091E00E944608882329F088819981019698
|
||||
:10098000998388832297FA94BFEFFB16F9F60150FA
|
||||
:100990001040EFEF0F3F1E0729F0C5E4D2E08FE7CC
|
||||
:1009A000F82ED4CFC7E4D1E000E011E000D000D0B1
|
||||
:1009B000ADB7BEB712961C930E931197899199917A
|
||||
:1009C0008F70907014969C938E9313970E94D90009
|
||||
:1009D0000F900F900F900F90B2E0C734DB0731F704
|
||||
:1009E00000D083E091E0EDB7FEB7928381830E944F
|
||||
:1009F000D9000F900F90DF91CF911F910F91FF9031
|
||||
:100A0000089580E895E060E070E00E948D00089510
|
||||
:100A10000F931F93CF93DF9384ED92E040E051EE6C
|
||||
:100A200060E070E00E9454060E94010500D086E05C
|
||||
:100A300091E0EDB7FEB7928381830E94D9000F90B9
|
||||
:100A40000F908AE391E00E944B088AE391E060E016
|
||||
:100A50000E94E8078AE391E00E9484088AE391E01B
|
||||
:100A60000E947C07C0E0D0E000E011E000D000D0A0
|
||||
:100A7000EDB7FEB712830183CE0124E095958795EB
|
||||
:100A80002A95E1F7948383830E94D90021960F90E1
|
||||
:100A90000F900F900F90C038D10541F700D083E040
|
||||
:100AA00091E0EDB7FEB7928381830E94D900C0E048
|
||||
:100AB000D0E00F900F9000D000D0EDB7FEB70183CB
|
||||
:100AC0001283CE018F709070948383830E94D9002B
|
||||
:100AD00021960F900F900F900F90C038D10559F7C5
|
||||
:100AE00000D083E091E0EDB7FEB7928381830E944E
|
||||
:100AF000D9000F900F90DF91CF911F910F91089522
|
||||
:100B00000F931F93082F84ED92E0602F0E94280717
|
||||
:100B1000112707FD1095C8011F910F9108951F928D
|
||||
:100B20000F920FB60F9211242F933F938F939F93A1
|
||||
:100B3000AF93BF9380914B0290914C02A0914D02D4
|
||||
:100B4000B0914E0230914F020196A11DB11D232F8D
|
||||
:100B50002D5F2D3720F02D570196A11DB11D20933B
|
||||
:100B60004F0280934B0290934C02A0934D02B0939E
|
||||
:100B70004E028091470290914802A0914902B091A3
|
||||
:100B80004A020196A11DB11D80934702909348022D
|
||||
:100B9000A0934902B0934A02BF91AF919F918F9168
|
||||
:100BA0003F912F910F900FBE0F901F9018950197B6
|
||||
:100BB00039F0880F991F880F991F02970197F1F755
|
||||
:100BC0000895789484B5826084BD84B5816084BDC5
|
||||
:100BD00085B5826085BD85B5816085BDEEE6F0E0B6
|
||||
:100BE000808181608083E1E8F0E010828081826012
|
||||
:100BF0008083808181608083E0E8F0E08081816093
|
||||
:100C00008083E1EBF0E0808184608083E0EBF0E0C2
|
||||
:100C1000808181608083EAE7F0E080818460808366
|
||||
:100C20008081826080838081816080838081806810
|
||||
:100C300080831092C10008950E94E1050E9408057A
|
||||
:100C40000E949704FDCF1F920F920FB60F921124AE
|
||||
:100C50002F933F934F938F939F93EF93FF934091E5
|
||||
:100C6000C600E091D002F091D10231969F012F771A
|
||||
:100C7000307031978091D2029091D30228173907B2
|
||||
:100C800039F0E05BFD4F40833093D1022093D002D6
|
||||
:100C9000FF91EF919F918F914F913F912F910F90E5
|
||||
:100CA0000FBE0F901F901895AF92BF92DF92EF92F8
|
||||
:100CB000FF920F931F93CF93DF93EC017A018B0187
|
||||
:100CC000DD24403081EE580780E0680780E0780737
|
||||
:100CD00011F0DD24D39491E0A92EB12CE885F9859B
|
||||
:100CE000DD2069F0C5010A8802C0880F991F0A94A7
|
||||
:100CF000E2F7808360E079E08DE390E005C0108248
|
||||
:100D000060E874E88EE190E0A80197010E949A09DA
|
||||
:100D10002150304040405040569547953795279593
|
||||
:100D200080E12030380720F0DD2011F0DD24D6CF1F
|
||||
:100D3000EC81FD813083EE81FF812083EA85FB8594
|
||||
:100D4000208141E050E0CA010E8402C0880F991F43
|
||||
:100D50000A94E2F7282B2083EA85FB852081CA01CB
|
||||
:100D60000F8402C0880F991F0A94E2F7282B208372
|
||||
:100D7000EA85FB858081088802C0440F551F0A94CC
|
||||
:100D8000E2F7842B8083DF91CF911F910F91FF9029
|
||||
:100D9000EF90DF90BF90AF900895DC011296ED9137
|
||||
:100DA000FC911397E058FF4F2191319180819181FF
|
||||
:100DB000281B390B2F773070C9010895DC0112967A
|
||||
:100DC000ED91FC911397EE57FF4F20813181929165
|
||||
:100DD0008291E058F0408217930719F42FEF3FEF0C
|
||||
:100DE00005C0E20FF31F8081282F30E0C90108956C
|
||||
:100DF000DC011296ED91FC911397DF01AE57BF4FC6
|
||||
:100E00002D913C911197E058FF4F80819181E058DE
|
||||
:100E1000F0408217930719F42FEF3FEF0BC0E20F5A
|
||||
:100E2000F31F80812F5F3F4F2F7730702D933C93BE
|
||||
:100E3000282F30E0C9010895DC011296ED91FC9154
|
||||
:100E40001397EE57FF4F808191819293829308957B
|
||||
:100E5000FC01A085B18521898C9190E0022E02C011
|
||||
:100E6000959587950A94E2F780FFF6CF0484F5857F
|
||||
:100E7000E02D608308958BE291E09093D5028093FA
|
||||
:100E8000D40280E592E09093D7028093D60285EC5D
|
||||
:100E900090E09093D9028093D80284EC90E09093F4
|
||||
:100EA000DB028093DA0280EC90E09093DD02809385
|
||||
:100EB000DC0281EC90E09093DF028093DE0286EC0E
|
||||
:100EC00090E09093E1028093E00284E08093E2025C
|
||||
:100ED00083E08093E30287E08093E40285E08093DF
|
||||
:100EE000E50281E08093E6020895FC01608341837E
|
||||
:100EF00080E2828313820895FC01808160E00E9479
|
||||
:100F0000CD080895FF920F931F938C01F62E80E079
|
||||
:100F10000E94650985E00E946A09F80181816F2DB0
|
||||
:100F20000E94CD081F910F91FF9008951F93CF93BA
|
||||
:100F3000DF93EC0160E070E00E94820781EE8EBDDD
|
||||
:100F40000DB407FEFDCF1EB5CE0161E070E00E943A
|
||||
:100F50008207812FDF91CF911F9108951F93CF9327
|
||||
:100F6000DF93EC0160E070E00E94820782EE8EBDAC
|
||||
:100F70000DB407FEFDCF1EB5CE0161E070E00E940A
|
||||
:100F80008207812FDF91CF911F9108950F931F93B7
|
||||
:100F9000CF93DF93EC01162F042F60E070E00E94E6
|
||||
:100FA00082071F7110621EBD0DB407FEFDCF1EB576
|
||||
:100FB0000EBD0DB407FEFDCF8EB5CE0161E070E031
|
||||
:100FC0000E948207812FDF91CF911F910F91089589
|
||||
:100FD000662319F061E04FE302C061E040E00E9447
|
||||
:100FE000C6070895462F603808F04FE765E00E9475
|
||||
:100FF000C6070895EF92FF920F931F93CF93DF934D
|
||||
:101000007C01162FEA01022F60E070E00E94820747
|
||||
:101010001F7110621EBD0DB407FEFDCF1EB508C0C6
|
||||
:1010200088818EBD0DB407FEFDCF21968EB501508F
|
||||
:101030000023B1F7C70161E070E00E948207812FB1
|
||||
:10104000DF91CF911F910F91FF90EF9008951F9323
|
||||
:10105000CF93DF93EC01162F60E070E00E948207CF
|
||||
:101060001F711EBD0DB407FEFDCF8EB58FEF8EBD77
|
||||
:101070000DB407FEFDCF1EB5CE0161E070E00E9409
|
||||
:101080008207812FDF91CF911F91089569E00E941F
|
||||
:101090002708817008950F931F938C01FC018081B4
|
||||
:1010A00061E00E94A708F801818161E00E94A70821
|
||||
:1010B000F801808160E00E94CD08C80161E070E025
|
||||
:1010C0000E9482070E947B0981E00E945C0980E007
|
||||
:1010D0000E94650985E00E946A09C80164E04FEF3B
|
||||
:1010E0000E94C607C80167E040E70E94C607C80122
|
||||
:1010F0000E94AE07C8010E949607C80161E00E94E5
|
||||
:10110000F2071F910F9108950F931F938C0160E0D8
|
||||
:101110004BE00E94C607C80167E040E70E94C6078F
|
||||
:10112000A8014B5F5F4FC8016AE025E00E94FA0703
|
||||
:10113000C8010E94AE07F801808161E00E94CD08DD
|
||||
:1011400082E890E00E94D7051F910F910895482FE3
|
||||
:1011500050E0CA0186569F4FFC0124914A575F4FC9
|
||||
:10116000FA0184918823C1F0E82FF0E0EE0FFF1F11
|
||||
:10117000E859FF4FA591B491662341F49FB7F894C5
|
||||
:101180008C91209582238C939FBF08959FB7F894EC
|
||||
:101190008C91822B8C939FBF0895482F50E0CA01F9
|
||||
:1011A00082559F4FFC012491CA0186569F4FFC0136
|
||||
:1011B00034914A575F4FFA019491992309F444C03E
|
||||
:1011C000222351F1233071F0243028F42130A1F092
|
||||
:1011D000223011F514C02630B1F02730C1F0243090
|
||||
:1011E000D9F404C0809180008F7703C08091800083
|
||||
:1011F0008F7D8093800010C084B58F7702C084B546
|
||||
:101200008F7D84BD09C08091B0008F7703C080912D
|
||||
:10121000B0008F7D8093B000E92FF0E0EE0FFF1F4C
|
||||
:10122000EE58FF4FA591B491662341F49FB7F8940F
|
||||
:101230008C91309583238C939FBF08959FB7F8942A
|
||||
:101240008C91832B8C939FBF08950F931F93CF9303
|
||||
:10125000DF938C01EB0109C02196D801ED91FC913F
|
||||
:101260000190F081E02DC801099568816623A1F7FE
|
||||
:10127000DF91CF911F910F910895EF92FF920F93FD
|
||||
:101280001F93CF93DF938C017B01EA010CC0D70140
|
||||
:101290006D917D01D801ED91FC910190F081E02DDF
|
||||
:1012A000C80109952197209791F7DF91CF911F9160
|
||||
:1012B0000F91FF90EF900895882319F48CB5806208
|
||||
:1012C00002C08CB58F7D8CBD08959CB5937F982B03
|
||||
:1012D0009CBD08952CB5382F33702C7F322B3CBD2C
|
||||
:1012E0002DB590E0959587959595879581702E7F82
|
||||
:1012F000822B8DBD08958DE061E00E94A7088BE0F0
|
||||
:1013000061E00E94A7088AE061E00E94A7088DE0E2
|
||||
:1013100060E00E94CD088BE060E00E94CD088AE08A
|
||||
:1013200061E00E94CD088CB580618CBD8CB5806475
|
||||
:101330008CBD0895A1E21A2EAA1BBB1BFD010DC096
|
||||
:10134000AA1FBB1FEE1FFF1FA217B307E407F50775
|
||||
:1013500020F0A21BB30BE40BF50B661F771F881F51
|
||||
:10136000991F1A9469F760957095809590959B01E7
|
||||
:10137000AC01BD01CF0108952F923F924F925F9231
|
||||
:101380006F927F928F929F92AF92BF92CF92DF9295
|
||||
:10139000EF92FF920F931F93CF93DF93CDB7DEB7FA
|
||||
:1013A000CA1BDB0B0FB6F894DEBF0FBECDBF09948E
|
||||
:1013B0002A88398848885F846E847D848C849B84E5
|
||||
:1013C000AA84B984C884DF80EE80FD800C811B81F3
|
||||
:1013D000AA81B981CE0FD11D0FB6F894DEBF0FBE22
|
||||
:1013E000CDBFED010895EE0FFF1F0590F491E02DA4
|
||||
:0613F0000994F894FFCF00
|
||||
:1013F6002578000A0D000A0D524632342F657861B1
|
||||
:101406006D706C65732F7363616E6E65722F0A0D56
|
||||
:10141600002000F102000000000000280725093D19
|
||||
:0A14260009CD06F806DE061C0700DB
|
||||
:00000001FF
|
||||
154
arduino-cli/libraries/RF24/examples/scanner/scanner.ino
Normal file
154
arduino-cli/libraries/RF24/examples/scanner/scanner.ino
Normal file
@@ -0,0 +1,154 @@
|
||||
/*
|
||||
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
|
||||
Updated 2020 TMRh20
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Channel scanner and Continuous Carrier Wave Output
|
||||
*
|
||||
* Example to detect interference on the various channels available.
|
||||
* This is a good diagnostic tool to check whether you're picking a
|
||||
* good channel for your application.
|
||||
*
|
||||
* Run this sketch on two devices. On one device, start CCW output by sending a 'g'
|
||||
* character over Serial. The other device scanning should detect the output of the sending
|
||||
* device on the given channel. Adjust channel and output power of CCW below.
|
||||
*
|
||||
* Inspired by cpixip.
|
||||
* See http://arduino.cc/forum/index.php/topic,54795.0.html
|
||||
*/
|
||||
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
|
||||
RF24 radio(7,8);
|
||||
|
||||
//
|
||||
// Channel info
|
||||
//
|
||||
|
||||
const uint8_t num_channels = 126;
|
||||
uint8_t values[num_channels];
|
||||
|
||||
//
|
||||
// Setup
|
||||
//
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
Serial.println(F("\n\rRF24/examples/scanner/"));
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
|
||||
radio.begin();
|
||||
radio.setAutoAck(false);
|
||||
|
||||
// Get into standby mode
|
||||
radio.startListening();
|
||||
radio.stopListening();
|
||||
radio.printDetails();
|
||||
|
||||
//delay(1000);
|
||||
// Print out header, high then low digit
|
||||
int i = 0;
|
||||
while ( i < num_channels )
|
||||
{
|
||||
Serial.print(i>>4,HEX);
|
||||
++i;
|
||||
}
|
||||
Serial.println();
|
||||
i = 0;
|
||||
while ( i < num_channels )
|
||||
{
|
||||
Serial.print(i&0xf,HEX);
|
||||
++i;
|
||||
}
|
||||
Serial.println();
|
||||
//delay(1000);
|
||||
}
|
||||
|
||||
//
|
||||
// Loop
|
||||
//
|
||||
|
||||
const int num_reps = 100;
|
||||
bool constCarrierMode = 0;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
/****************************************/
|
||||
// Send g over Serial to begin CCW output
|
||||
// Configure the channel and power level below
|
||||
if(Serial.available()){
|
||||
char c = Serial.read();
|
||||
if(c == 'g'){
|
||||
constCarrierMode = 1;
|
||||
radio.stopListening();
|
||||
delay(2);
|
||||
Serial.println("Starting Carrier Out");
|
||||
radio.startConstCarrier(RF24_PA_LOW,40);
|
||||
}else
|
||||
if(c == 'e'){
|
||||
constCarrierMode = 0;
|
||||
radio.stopConstCarrier();
|
||||
Serial.println("Stopping Carrier Out");
|
||||
}
|
||||
}
|
||||
/****************************************/
|
||||
|
||||
if(constCarrierMode == 0){
|
||||
// Clear measurement values
|
||||
memset(values,0,sizeof(values));
|
||||
|
||||
// Scan all channels num_reps times
|
||||
int rep_counter = num_reps;
|
||||
while (rep_counter--)
|
||||
{
|
||||
int i = num_channels;
|
||||
while (i--)
|
||||
{
|
||||
// Select this channel
|
||||
radio.setChannel(i);
|
||||
|
||||
// Listen for a little
|
||||
radio.startListening();
|
||||
delayMicroseconds(128);
|
||||
radio.stopListening();
|
||||
|
||||
// Did we get a carrier?
|
||||
if ( radio.testCarrier() ){
|
||||
++values[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Print out channel measurements, clamped to a single hex digit
|
||||
int i = 0;
|
||||
while ( i < num_channels )
|
||||
{
|
||||
Serial.print(min(0xf,values[i]),HEX);
|
||||
++i;
|
||||
}
|
||||
Serial.println();
|
||||
|
||||
}//If constCarrierMode == 0
|
||||
}
|
||||
293
arduino-cli/libraries/RF24/examples/starping/starping.pde
Normal file
293
arduino-cli/libraries/RF24/examples/starping/starping.pde
Normal file
@@ -0,0 +1,293 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example RF Radio Ping Star Group
|
||||
*
|
||||
* This sketch is a more complex example of using the RF24 library for Arduino.
|
||||
* Deploy this on up to six nodes. Set one as the 'pong receiver' by tying the
|
||||
* role_pin low, and the others will be 'ping transmit' units. The ping units
|
||||
* unit will send out the value of millis() once a second. The pong unit will
|
||||
* respond back with a copy of the value. Each ping unit can get that response
|
||||
* back, and determine how long the whole cycle took.
|
||||
*
|
||||
* This example requires a bit more complexity to determine which unit is which.
|
||||
* The pong receiver is identified by having its role_pin tied to ground.
|
||||
* The ping senders are further differentiated by a byte in eeprom.
|
||||
*/
|
||||
|
||||
#include <SPI.h>
|
||||
#include <EEPROM.h>
|
||||
#include "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
//
|
||||
// Hardware configuration
|
||||
//
|
||||
|
||||
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10
|
||||
|
||||
RF24 radio(9,10);
|
||||
|
||||
// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
|
||||
// Leave open to be the 'pong' receiver.
|
||||
const int role_pin = 7;
|
||||
|
||||
//
|
||||
// Topology
|
||||
//
|
||||
|
||||
// Radio pipe addresses for the nodes to communicate. Only ping nodes need
|
||||
// dedicated pipes in this topology. Each ping node has a talking pipe
|
||||
// that it will ping into, and a listening pipe that it will listen for
|
||||
// the pong. The pong node listens on all the ping node talking pipes
|
||||
// and sends the pong back on the sending node's specific listening pipe.
|
||||
|
||||
const uint64_t talking_pipes[5] = { 0xF0F0F0F0D2LL, 0xF0F0F0F0C3LL, 0xF0F0F0F0B4LL, 0xF0F0F0F0A5LL, 0xF0F0F0F096LL };
|
||||
const uint64_t listening_pipes[5] = { 0x3A3A3A3AD2LL, 0x3A3A3A3AC3LL, 0x3A3A3A3AB4LL, 0x3A3A3A3AA5LL, 0x3A3A3A3A96LL };
|
||||
|
||||
//
|
||||
// Role management
|
||||
//
|
||||
// Set up role. This sketch uses the same software for all the nodes
|
||||
// in this system. Doing so greatly simplifies testing. The hardware itself specifies
|
||||
// which node it is.
|
||||
//
|
||||
// This is done through the role_pin
|
||||
//
|
||||
|
||||
// The various roles supported by this sketch
|
||||
typedef enum { role_invalid = 0, role_ping_out, role_pong_back } role_e;
|
||||
|
||||
// The debug-friendly names of those roles
|
||||
const char* role_friendly_name[] = { "invalid", "Ping out", "Pong back"};
|
||||
|
||||
// The role of the current running sketch
|
||||
role_e role;
|
||||
|
||||
//
|
||||
// Address management
|
||||
//
|
||||
|
||||
// Where in EEPROM is the address stored?
|
||||
const uint8_t address_at_eeprom_location = 0;
|
||||
|
||||
// What is our address (SRAM cache of the address from EEPROM)
|
||||
// Note that zero is an INVALID address. The pong back unit takes address
|
||||
// 1, and the rest are 2-6
|
||||
uint8_t node_address;
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Role
|
||||
//
|
||||
|
||||
// set up the role pin
|
||||
pinMode(role_pin, INPUT);
|
||||
digitalWrite(role_pin,HIGH);
|
||||
delay(20); // Just to get a solid reading on the role pin
|
||||
|
||||
// read the address pin, establish our role
|
||||
if ( digitalRead(role_pin) )
|
||||
role = role_ping_out;
|
||||
else
|
||||
role = role_pong_back;
|
||||
|
||||
//
|
||||
// Address
|
||||
//
|
||||
|
||||
if ( role == role_pong_back )
|
||||
node_address = 1;
|
||||
else
|
||||
{
|
||||
// Read the address from EEPROM
|
||||
uint8_t reading = EEPROM.read(address_at_eeprom_location);
|
||||
|
||||
// If it is in a valid range for node addresses, it is our
|
||||
// address.
|
||||
if ( reading >= 2 && reading <= 6 )
|
||||
node_address = reading;
|
||||
|
||||
// Otherwise, it is invalid, so set our address AND ROLE to 'invalid'
|
||||
else
|
||||
{
|
||||
node_address = 0;
|
||||
role = role_invalid;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
Serial.begin(115200);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/starping/\n\r");
|
||||
printf("ROLE: %s\n\r",role_friendly_name[role]);
|
||||
printf("ADDRESS: %i\n\r",node_address);
|
||||
|
||||
//
|
||||
// Setup and configure rf radio
|
||||
//
|
||||
|
||||
radio.begin();
|
||||
|
||||
//
|
||||
// Open pipes to other nodes for communication
|
||||
//
|
||||
|
||||
// The pong node listens on all the ping node talking pipes
|
||||
// and sends the pong back on the sending node's specific listening pipe.
|
||||
if ( role == role_pong_back )
|
||||
{
|
||||
radio.openReadingPipe(1,talking_pipes[0]);
|
||||
radio.openReadingPipe(2,talking_pipes[1]);
|
||||
radio.openReadingPipe(3,talking_pipes[2]);
|
||||
radio.openReadingPipe(4,talking_pipes[3]);
|
||||
radio.openReadingPipe(5,talking_pipes[4]);
|
||||
}
|
||||
|
||||
// Each ping node has a talking pipe that it will ping into, and a listening
|
||||
// pipe that it will listen for the pong.
|
||||
if ( role == role_ping_out )
|
||||
{
|
||||
// Write on our talking pipe
|
||||
radio.openWritingPipe(talking_pipes[node_address-2]);
|
||||
// Listen on our listening pipe
|
||||
radio.openReadingPipe(1,listening_pipes[node_address-2]);
|
||||
}
|
||||
|
||||
//
|
||||
// Start listening
|
||||
//
|
||||
|
||||
radio.startListening();
|
||||
|
||||
//
|
||||
// Dump the configuration of the rf unit for debugging
|
||||
//
|
||||
|
||||
radio.printDetails();
|
||||
|
||||
//
|
||||
// Prompt the user to assign a node address if we don't have one
|
||||
//
|
||||
|
||||
if ( role == role_invalid )
|
||||
{
|
||||
printf("\n\r*** NO NODE ADDRESS ASSIGNED *** Send 1 through 6 to assign an address\n\r");
|
||||
}
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
//
|
||||
// Ping out role. Repeatedly send the current time
|
||||
//
|
||||
|
||||
if (role == role_ping_out)
|
||||
{
|
||||
// First, stop listening so we can talk.
|
||||
radio.stopListening();
|
||||
|
||||
// Take the time, and send it. This will block until complete
|
||||
unsigned long time = millis();
|
||||
printf("Now sending %lu...",time);
|
||||
radio.write( &time, sizeof(unsigned long) );
|
||||
|
||||
// Now, continue listening
|
||||
radio.startListening();
|
||||
|
||||
// Wait here until we get a response, or timeout (250ms)
|
||||
unsigned long started_waiting_at = millis();
|
||||
bool timeout = false;
|
||||
while ( ! radio.available() && ! timeout )
|
||||
if (millis() - started_waiting_at > 250 )
|
||||
timeout = true;
|
||||
|
||||
// Describe the results
|
||||
if ( timeout )
|
||||
{
|
||||
printf("Failed, response timed out.\n\r");
|
||||
}
|
||||
else
|
||||
{
|
||||
// Grab the response, compare, and send to debugging spew
|
||||
unsigned long got_time;
|
||||
radio.read( &got_time, sizeof(unsigned long) );
|
||||
|
||||
// Spew it
|
||||
printf("Got response %lu, round-trip delay: %lu\n\r",got_time,millis()-got_time);
|
||||
}
|
||||
|
||||
// Try again 1s later
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
//
|
||||
// Pong back role. Receive each packet, dump it out, and send it back
|
||||
//
|
||||
|
||||
if ( role == role_pong_back )
|
||||
{
|
||||
// if there is data ready
|
||||
uint8_t pipe_num;
|
||||
if ( radio.available(&pipe_num) )
|
||||
{
|
||||
// Dump the payloads until we've gotten everything
|
||||
unsigned long got_time;
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Fetch the payload, and see if this was the last one.
|
||||
done = radio.read( &got_time, sizeof(unsigned long) );
|
||||
|
||||
// Spew it
|
||||
printf("Got payload %lu from node %i...",got_time,pipe_num+1);
|
||||
}
|
||||
|
||||
// First, stop listening so we can talk
|
||||
radio.stopListening();
|
||||
|
||||
// Open the correct pipe for writing
|
||||
radio.openWritingPipe(listening_pipes[pipe_num-1]);
|
||||
|
||||
// Retain the low 2 bytes to identify the pipe for the spew
|
||||
uint16_t pipe_id = listening_pipes[pipe_num-1] & 0xffff;
|
||||
|
||||
// Send the final one back.
|
||||
radio.write( &got_time, sizeof(unsigned long) );
|
||||
printf("Sent response to %04x.\n\r",pipe_id);
|
||||
|
||||
// Now, resume listening so we catch the next packets.
|
||||
radio.startListening();
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Listen for serial input, which is how we set the address
|
||||
//
|
||||
if (Serial.available())
|
||||
{
|
||||
// If the character on serial input is in a valid range...
|
||||
char c = Serial.read();
|
||||
if ( c >= '1' && c <= '6' )
|
||||
{
|
||||
// It is our address
|
||||
EEPROM.write(address_at_eeprom_location,c-'0');
|
||||
|
||||
// And we are done right now (no easy way to soft reset)
|
||||
printf("\n\rManually reset address to: %c\n\rPress RESET to continue!",c);
|
||||
while(1) ;
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim:ai:ci sts=2 sw=2 ft=cpp
|
||||
Reference in New Issue
Block a user