nordic_fob example fully working.

This commit is contained in:
maniacbug 2012-01-04 21:00:15 -08:00
parent 36167a9e02
commit d1653e8cad
1 changed files with 68 additions and 147 deletions

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2011 J. Coliz <maniacbug@ymail.com> Copyright (C) 2012 J. Coliz <maniacbug@ymail.com>
This program is free software; you can redistribute it and/or This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License modify it under the terms of the GNU General Public License
@ -7,17 +7,16 @@
*/ */
/** /**
* Example RF Radio Ping Pair * Example Nordic FOB Receiver
* *
* This is an example of how to use the RF24 class. Write this sketch to two different nodes, * This is an example of how to use the RF24 class to receive signals from the
* connect the role_pin to ground on one. The ping node sends the current time to the pong node, * Sparkfun Nordic FOB. See http://www.sparkfun.com/products/8602 .
* which responds by sending the value back. The ping node can then see how long the whole cycle * Thanks to Kirk Mower for providing test hardware.
* took.
*/ */
#include <SPI.h> #include <SPI.h>
#include <RF24.h>
#include "nRF24L01.h" #include "nRF24L01.h"
#include "RF24.h"
#include "printf.h" #include "printf.h"
// //
@ -26,96 +25,53 @@
// Set up nRF24L01 radio on SPI bus plus pins 9 & 10 // Set up nRF24L01 radio on SPI bus plus pins 9 & 10
RF24 radio(9,10); RF24 radio(8,9);
// sets the role of this unit in hardware. Connect to GND to be the 'pong' receiver
// Leave open to be the 'ping' transmitter
const int role_pin = 7;
// //
// Topology // Payload
// //
// Radio pipe addresses for the 2 nodes to communicate. struct payload_t
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; {
uint8_t buttons;
uint16_t id;
uint8_t empty;
};
const char* button_names[] = { "Up", "Down", "Left", "Right", "Center" };
const int num_buttons = 5;
// //
// Role management // Forward declarations
//
// 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 uint16_t flip_endian(uint16_t in);
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"}; // Setup
//
// The role of the current running sketch
role_e role;
void setup(void) 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 // Print preamble
// //
Serial.begin(57600); Serial.begin(57600);
printf_begin(); printf_begin();
printf("\n\rRF24/examples/pingpair/\n\r"); printf("\r\nRF24/examples/nordic_fob/\r\n");
printf("ROLE: %s\n\r",role_friendly_name[role]);
// //
// Setup and configure rf radio // Setup and configure rf radio according to the built-in parameters
// of the FOB.
// //
radio.begin(); radio.begin();
radio.setChannel(2);
// optionally, increase the delay between retries & # of retries radio.setPayloadSize(4);
radio.setRetries(15,15); radio.setAutoAck(false);
radio.setCRCLength(RF24_CRC_8);
// optionally, reduce the payload size. seems to radio.openReadingPipe(1,0xE7E7E7E7E7LL);
// 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 // Start listening
@ -130,91 +86,56 @@ void setup(void)
radio.printDetails(); radio.printDetails();
} }
//
// Loop
//
void loop(void) void loop(void)
{ {
// //
// Ping out role. Repeatedly send the current time // Receive each packet, dump it out
// //
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);
bool ok = radio.write( &time, sizeof(unsigned long) );
if (ok)
printf("ok...");
else
printf("failed.\n\r");
// 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.\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 // if there is data ready
if ( radio.available() ) if ( radio.available() )
{ {
// Dump the payloads until we've gotten everything // Get the packet from the radio
unsigned long got_time; payload_t payload;
bool done = false; radio.read( &payload, sizeof(payload) );
while (!done)
// 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--)
{ {
// Fetch the payload, and see if this was the last one. if ( ! ( payload.buttons & _BV(i) ) )
done = radio.read( &got_time, sizeof(unsigned long) ); {
printf("%s ",button_names[i]);
// 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 // If no buttons, print None
radio.stopListening(); if ( payload.buttons == _BV(num_buttons) - 1 )
printf("None");
// Send the final one back. printf("\r\n");
radio.write( &got_time, sizeof(unsigned long) );
printf("Sent response.\n\r");
// Now, resume listening so we catch the next packets.
radio.startListening();
} }
}
} }
//
// 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 // vim:cin:ai:sts=2 sw=2 ft=cpp