git tree messed up
This commit is contained in:
@@ -0,0 +1,136 @@
|
||||
/*
|
||||
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com>
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU General Public License
|
||||
version 2 as published by the Free Software Foundation.
|
||||
//2014 - TMRh20 - Updated along with Optimized RF24 Library fork
|
||||
*/
|
||||
|
||||
/**
|
||||
* Example for Getting Started with nRF24L01+ radios.
|
||||
*
|
||||
* This is an example of how to use the RF24 class to communicate on a basic level. Write this sketch to two
|
||||
* different nodes. Put one of the nodes into 'transmit' mode by connecting with the serial monitor and
|
||||
* sending a 'T'. The ping node sends the current time to the pong node, which responds by sending the value
|
||||
* back. The ping node can then see how long the whole cycle took.
|
||||
* Note: For a more efficient call-response scenario see the GettingStarted_CallResponse.ino example.
|
||||
* Note: When switching between sketches, the radio may need to be powered down to clear settings that are not "un-set" otherwise
|
||||
*/
|
||||
|
||||
|
||||
#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
|
||||
RF24 radio(7,8);
|
||||
|
||||
const uint64_t addresses[2] = { 0xABCDABCD71LL, 0x544d52687CLL }; // Radio pipe addresses for the 2 nodes to communicate.
|
||||
|
||||
// Set up roles to simplify testing
|
||||
boolean role; // The main role variable, holds the current role identifier
|
||||
boolean role_ping_out = 1, role_pong_back = 0; // The two different roles.
|
||||
|
||||
void setup() {
|
||||
|
||||
|
||||
Serial.begin(57600);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/GettingStarted/\n\r");
|
||||
printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
|
||||
|
||||
// Setup and configure rf radio
|
||||
radio.begin(); // Start up the radio
|
||||
radio.setAutoAck(1); // Ensure autoACK is enabled
|
||||
radio.setRetries(15,15); // Max delay between retries & number of retries
|
||||
|
||||
radio.openWritingPipe(addresses[1]); // Open a writing pipe on pipe 0, with address 1
|
||||
radio.openReadingPipe(1,addresses[0]); // Open a reading pipe on pipe 1, with address 0
|
||||
|
||||
radio.startListening(); // Start listening
|
||||
radio.printDetails(); // Dump the configuration of the rf unit for debugging
|
||||
}
|
||||
|
||||
void loop(void){
|
||||
|
||||
|
||||
/****************** Ping Out Role ***************************/
|
||||
if (role == role_ping_out) {
|
||||
|
||||
radio.stopListening(); // First, stop listening so we can talk.
|
||||
|
||||
|
||||
printf("Now sending \n\r");
|
||||
|
||||
unsigned long time = micros(); // Take the time, and send it. This will block until complete
|
||||
if (!radio.write( &time, sizeof(unsigned long) )){ printf("failed.\n\r"); }
|
||||
|
||||
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
|
||||
printf("Failed, response timed out.\n\r");
|
||||
}else{
|
||||
unsigned long got_time; // Grab the response, compare, and send to debugging spew
|
||||
radio.read( &got_time, sizeof(unsigned long) );
|
||||
|
||||
// Spew it
|
||||
printf("Sent %lu, Got response %lu, round-trip delay: %lu microseconds\n\r",time,got_time,micros()-got_time);
|
||||
}
|
||||
|
||||
// Try again 1s later
|
||||
delay(1000);
|
||||
}
|
||||
|
||||
/****************** Pong Back Role ***************************/
|
||||
|
||||
if ( role == role_pong_back )
|
||||
{
|
||||
if( radio.available()){
|
||||
unsigned long got_time; // Variable for the received timestamp
|
||||
while (radio.available()) { // While there is data ready
|
||||
radio.read( &got_time, sizeof(unsigned long) ); // Get the payload
|
||||
}
|
||||
|
||||
radio.stopListening(); // First, stop listening so we can talk
|
||||
radio.write( &got_time, sizeof(unsigned long) ); // Send the final one back.
|
||||
radio.startListening(); // Now, resume listening so we catch the next packets.
|
||||
printf("Sent response %lu \n\r", got_time);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/****************** Change Roles via Serial Commands ***************************/
|
||||
|
||||
if ( Serial.available() )
|
||||
{
|
||||
char c = toupper(Serial.read());
|
||||
if ( c == 'T' && role == role_pong_back )
|
||||
{
|
||||
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
|
||||
|
||||
role = role_ping_out; // Become the primary transmitter (ping out)
|
||||
radio.openWritingPipe(addresses[0]);
|
||||
radio.openReadingPipe(1,addresses[1]);
|
||||
}
|
||||
else if ( c == 'R' && role == role_ping_out )
|
||||
{
|
||||
printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
|
||||
|
||||
role = role_pong_back; // Become the primary receiver (pong back)
|
||||
radio.openWritingPipe(addresses[1]);
|
||||
radio.openReadingPipe(1,addresses[0]);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -0,0 +1,124 @@
|
||||
/*
|
||||
March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork
|
||||
Parts 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 "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
// Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 9 & 10
|
||||
RF24 radio(7,8);
|
||||
// Topology
|
||||
const uint64_t addresses[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
|
||||
|
||||
byte counter = 1; // A single byte to keep track of the data being sent back and forth
|
||||
|
||||
|
||||
void setup(){
|
||||
|
||||
Serial.begin(57600);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/GettingStarted/\n\r");
|
||||
printf("ROLE: %s\n\r",role_friendly_name[role]);
|
||||
printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
|
||||
|
||||
// Setup and configure radio
|
||||
|
||||
radio.begin();
|
||||
radio.setAutoAck(1); // Ensure autoACK is enabled
|
||||
radio.enableAckPayload(); // Allow optional ack payloads
|
||||
radio.setRetries(0,15); // Smallest time between retries, max no. of retries
|
||||
radio.setPayloadSize(1); // Here we are sending 1-byte payloads to test the call-response speed
|
||||
radio.openWritingPipe(addresses[1]); // Both radios listen on the same pipes by default, and switch when writing
|
||||
radio.openReadingPipe(1,addresses[0]); // Open a reading pipe on address 0, pipe 1
|
||||
radio.startListening(); // Start listening
|
||||
radio.powerUp();
|
||||
radio.printDetails(); // Dump the configuration of the rf unit for debugging
|
||||
}
|
||||
|
||||
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.
|
||||
printf("Now sending %d as payload. ",counter); // Use a simple byte counter as payload
|
||||
unsigned long time = micros(); // Record the current microsecond count
|
||||
|
||||
if ( radio.write(&counter,1) ){ // Send the counter variable to the other radio
|
||||
if(!radio.available()){ // If nothing in the buffer, we got an ack but it is blank
|
||||
printf("Got blank response. round-trip delay: %lu microseconds\n\r",micros()-time);
|
||||
}else{
|
||||
while(radio.available() ){ // If an ack with payload was received
|
||||
radio.read( &gotByte, 1 ); // Read it, and display the response time
|
||||
printf("Got response %d, round-trip delay: %lu microseconds\n\r",gotByte,micros()-time);
|
||||
counter++; // Increment the counter variable
|
||||
}
|
||||
}
|
||||
|
||||
}else{ printf("Sending failed.\n\r"); } // 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.
|
||||
// Ack payloads are much more efficient than switching to transmit mode to respond to a call
|
||||
radio.writeAckPayload(pipeNo,&gotByte, 1 ); // This can be commented out to send empty payloads.
|
||||
printf("Sent response %d \n\r", gotByte);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
/****************** Change Roles via Serial Commands ***************************/
|
||||
|
||||
if ( Serial.available() )
|
||||
{
|
||||
char c = toupper(Serial.read());
|
||||
if ( c == 'T' && role == role_pong_back )
|
||||
{
|
||||
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
|
||||
|
||||
role = role_ping_out; // Change roles (ping out)
|
||||
radio.openWritingPipe(addresses[0]); // Open different pipes when writing. Write on pipe 0, address 0
|
||||
radio.openReadingPipe(1,addresses[1]); // Read on pipe 1, as address 1
|
||||
}
|
||||
else if ( c == 'R' && role == role_ping_out )
|
||||
{
|
||||
printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
|
||||
|
||||
role = role_pong_back; // Become the primary receiver (pong back)
|
||||
radio.openWritingPipe(addresses[1]); // Since only two radios involved, both listen on the same addresses and pipe numbers in RX mode
|
||||
radio.openReadingPipe(1,addresses[0]); // then switch pipes & addresses to transmit.
|
||||
radio.startListening(); // Need to start listening after opening new reading pipes
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
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 "nRF24L01.h"
|
||||
#include "RF24.h"
|
||||
#include "printf.h"
|
||||
|
||||
/************* USER Configuration *****************************/
|
||||
// Hardware configuration
|
||||
RF24 radio(48,49); // Set up nRF24L01 radio on SPI bus plus pins 7 & 8
|
||||
boolean RADIO_NO = 0; //SET THIS TO 0 or 1 for 1st or 2nd radio
|
||||
|
||||
/***************************************************************/
|
||||
|
||||
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(57600);
|
||||
printf_begin();
|
||||
|
||||
radio.begin(); // Setup and configure rf radio
|
||||
radio.setChannel(1);
|
||||
radio.setPALevel(RF24_PA_MAX);
|
||||
radio.setDataRate(RF24_1MBPS);
|
||||
radio.setAutoAck(1); // Ensure autoACK is enabled
|
||||
radio.setRetries(2,15); // Optionally, increase the delay between retries & # of retries
|
||||
radio.setCRCLength(RF24_CRC_8);
|
||||
//radio.disableCRC();
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
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);
|
||||
|
||||
printf("Initiating Basic Data Transfer\n\r");
|
||||
|
||||
|
||||
unsigned long cycles = 10000; //Change this to a higher or lower number.
|
||||
|
||||
startTime = 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
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
printf("Transfer complete at "); Serial.print(rate); printf(" KB/s \n\r");
|
||||
printf("%d of ",counter); Serial.print(cycles); printf(" Packets Failed to Send\n\r");
|
||||
counter = 0;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
if(role == RX){
|
||||
while(radio.available()){
|
||||
radio.read(&data,32);
|
||||
counter++;
|
||||
}
|
||||
if(millis() - rxTimer > 1000){
|
||||
rxTimer = millis();
|
||||
printf("Rate: ");
|
||||
float numBytes = counter*32;
|
||||
Serial.print(numBytes/1000);
|
||||
printf(" KB/s\n\r");
|
||||
printf("Payload Count: %d \n\r", counter);
|
||||
counter = 0;
|
||||
}
|
||||
}
|
||||
//
|
||||
// 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)
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim:cin:ai:sts=2 sw=2 ft=cpp
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -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(48,49); // 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(57600);
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -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,255 @@
|
||||
/*
|
||||
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
|
||||
|
||||
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(57600);
|
||||
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
|
||||
bool done = false;
|
||||
while (!done)
|
||||
{
|
||||
// Fetch the payload, and see if this was the last one.
|
||||
done = 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
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -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(57600);
|
||||
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
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -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
|
||||
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
// March 2014 - TMRh20 - Updated along with High Speed RF24 Library fork
|
||||
// Parts 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 if wanting
|
||||
* to initiate communication instead of respond to a commmunication.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#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
|
||||
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(57600);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/GettingStarted/\n\r");
|
||||
printf("ROLE: %s\n\r",role_friendly_name[role]);
|
||||
printf("*** PRESS 'T' to begin transmitting to the other node\n\r");
|
||||
|
||||
// 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 )){
|
||||
printf("failed.\n\r");
|
||||
}else{
|
||||
|
||||
if(!radio.available()){
|
||||
printf("Blank Payload Received\n\r");
|
||||
}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 );
|
||||
}
|
||||
}
|
||||
|
||||
// Change roles
|
||||
|
||||
if ( Serial.available() )
|
||||
{
|
||||
char c = toupper(Serial.read());
|
||||
if ( c == 'T' && role == role_pong_back )
|
||||
{
|
||||
printf("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK\n\r");
|
||||
|
||||
role = role_ping_out; // Become the primary transmitter (ping out)
|
||||
radio.openWritingPipe(pipes[0]);
|
||||
radio.openReadingPipe(1,pipes[1]);
|
||||
}
|
||||
else if ( c == 'R' && role == role_ping_out )
|
||||
{
|
||||
printf("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK\n\r");
|
||||
|
||||
role = role_pong_back; // Become the primary receiver (pong back)
|
||||
radio.openWritingPipe(pipes[1]);
|
||||
radio.openReadingPipe(1,pipes[0]);
|
||||
radio.startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -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,232 @@
|
||||
/*
|
||||
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 9 & 10
|
||||
|
||||
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(57600);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/pingpair_dyn/\n\r");
|
||||
printf("ROLE: %s\n\r",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
|
||||
printf("Now sending length %i...",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 )
|
||||
{
|
||||
printf("Failed, response timed out.\n\r");
|
||||
}
|
||||
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
|
||||
printf("Got response size=%i value=%s\n\r",len,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
|
||||
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
|
||||
printf("Got payload size=%i value=%s\n\r",len,receive_payload);
|
||||
}
|
||||
|
||||
// First, stop listening so we can talk
|
||||
radio.stopListening();
|
||||
|
||||
// Send the final one back.
|
||||
radio.write( receive_payload, len );
|
||||
printf("Sent response.\n\r");
|
||||
|
||||
// Now, resume listening so we catch the next packets.
|
||||
radio.startListening();
|
||||
}
|
||||
}
|
||||
}
|
||||
// vim:cin:ai:sts=2 sw=2 ft=cpp
|
||||
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -0,0 +1,137 @@
|
||||
/*
|
||||
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"
|
||||
#include <avr/sleep.h>
|
||||
#include <avr/power.h>
|
||||
|
||||
// Hardware configuration
|
||||
RF24 radio(7,8); // Set up nRF24L01 radio on SPI bus plus pins 9 & 10
|
||||
|
||||
const short role_pin = 5; // sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
|
||||
// Leave open to be the 'ping' transmitter
|
||||
|
||||
const uint64_t address[2] = {0xABCDABCD71LL, 0x544d52687CLL}; // Radio pipe addresses for the 2 nodes to communicate.
|
||||
|
||||
// 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
|
||||
|
||||
boolean gotMsg = 0; // So we know when to go to sleep
|
||||
|
||||
/********************** 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();
|
||||
printf("\n\rRF24/examples/pingpair_irq/\n\r");
|
||||
printf("ROLE: %s\n\r",role_friendly_name[role]);
|
||||
|
||||
// Setup and configure rf radio
|
||||
radio.begin();
|
||||
radio.enableAckPayload(); // We will be using the Ack Payload feature, so please enable it
|
||||
// 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.printDetails(); // Dump the configuration of the rf unit for debugging
|
||||
delay(50);
|
||||
attachInterrupt(0, check_radio, FALLING); // Attach interrupt handler to interrupt #0 (using pin 2) on BOTH the sender and receiver
|
||||
}
|
||||
|
||||
static uint32_t message_count = 0;
|
||||
|
||||
|
||||
/********************** 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.
|
||||
printf("Now sending %lu\n\r",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 ){ printf("Send:OK\n\r"); }
|
||||
if ( role == role_receiver ){ printf("Ack Payload:Sent\n\r"); }
|
||||
}
|
||||
|
||||
if ( fail ) { // Have we failed to transmit?
|
||||
if ( role == role_sender ){ printf("Send:Failed\n\r"); }
|
||||
if ( role == role_receiver ){ printf("Ack Payload:Failed\n\r"); }
|
||||
}
|
||||
|
||||
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));
|
||||
printf("Ack:%lu\n\r",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) );
|
||||
printf("Got payload %lu\n\r",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,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -0,0 +1,225 @@
|
||||
/*
|
||||
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 9 & 10
|
||||
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(57600);
|
||||
printf_begin();
|
||||
printf("\n\rRF24/examples/pingpair_sleepy/\n\r");
|
||||
printf("ROLE: %s\n\r",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.
|
||||
printf("Now sending... %lu \n\r",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
|
||||
printf("Failed, response timed out.\n\r");
|
||||
}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.
|
||||
printf("Sent response.\n\r");
|
||||
radio.startListening(); // Now, resume listening so we catch the next packets.
|
||||
}else{
|
||||
Serial.println("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("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,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -0,0 +1,210 @@
|
||||
# (1) Project Information
|
||||
|
||||
PROJECT_LIBS = SPI RF24 ;
|
||||
|
||||
# (2) Board Information
|
||||
|
||||
UPLOAD_PROTOCOL ?= stk500v1 ;
|
||||
UPLOAD_SPEED ?= 57600 ;
|
||||
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 ;
|
||||
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 -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 = $(PWD) $(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 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
|
||||
}
|
||||
|
||||
#
|
||||
# Targets
|
||||
#
|
||||
|
||||
# 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) $(ARDUINO_LIB)/$(PROJECT_LIBS)/utility $(SKETCH_LIB)/$(PROJECT_LIBS) : *.cpp *.c ] ;
|
||||
|
||||
# Grab everything from the current dir
|
||||
PROJECT_MODULES += [ GLOB $(PWD) : *.c *.cpp *.pde *.ino ] ;
|
||||
|
||||
# Main output executable
|
||||
MAIN = $(PWD:B).elf ;
|
||||
|
||||
Main $(MAIN) : $(CORE_MODULES) $(LIB_MODULES) $(PROJECT_MODULES) ;
|
||||
Hex $(MAIN:B).hex : $(MAIN) ;
|
||||
|
||||
# Upload targets
|
||||
for _p in $(PORTS)
|
||||
{
|
||||
Upload $(_p) : $(PORT_$(_p)) : $(MAIN:B).hex ;
|
||||
}
|
||||
Binary file not shown.
@@ -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(57600);
|
||||
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
|
||||
Executable
BIN
Binary file not shown.
@@ -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
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 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 9 & 10
|
||||
|
||||
RF24 radio(9,10);
|
||||
|
||||
//
|
||||
// Channel info
|
||||
//
|
||||
|
||||
const uint8_t num_channels = 128;
|
||||
uint8_t values[num_channels];
|
||||
|
||||
//
|
||||
// Setup
|
||||
//
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
//
|
||||
// Print preamble
|
||||
//
|
||||
|
||||
Serial.begin(57600);
|
||||
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 int num_reps = 100;
|
||||
|
||||
void loop(void)
|
||||
{
|
||||
// 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(225);
|
||||
|
||||
|
||||
// Did we get a carrier?
|
||||
if ( radio.testCarrier() ){
|
||||
++values[i];
|
||||
}
|
||||
radio.stopListening();
|
||||
}
|
||||
}
|
||||
|
||||
// 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
|
||||
@@ -0,0 +1,206 @@
|
||||
PROJECT_NAME = $(PWD:B) ;
|
||||
PROJECT_DIR = . ;
|
||||
PROJECT_LIBS = EEPROM 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,37 @@
|
||||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file printf.h
|
||||
*
|
||||
* Setup necessary to direct stdout to the Arduino Serial library, which
|
||||
* enables 'printf'
|
||||
*/
|
||||
|
||||
#ifndef __PRINTF_H__
|
||||
#define __PRINTF_H__
|
||||
|
||||
#ifdef ARDUINO
|
||||
|
||||
int serial_putc( char c, FILE * )
|
||||
{
|
||||
Serial.write( c );
|
||||
|
||||
return c;
|
||||
}
|
||||
|
||||
void printf_begin(void)
|
||||
{
|
||||
fdevopen( &serial_putc, 0 );
|
||||
}
|
||||
|
||||
#else
|
||||
#error This example is only for use on Arduino.
|
||||
#endif // ARDUINO
|
||||
|
||||
#endif // __PRINTF_H__
|
||||
@@ -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(57600);
|
||||
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