From d1653e8cad74daf6fa4fa60a5646804592ee8290 Mon Sep 17 00:00:00 2001 From: maniacbug Date: Wed, 4 Jan 2012 21:00:15 -0800 Subject: [PATCH] nordic_fob example fully working. --- examples/nordic_fob/nordic_fob.pde | 215 +++++++++-------------------- 1 file changed, 68 insertions(+), 147 deletions(-) diff --git a/examples/nordic_fob/nordic_fob.pde b/examples/nordic_fob/nordic_fob.pde index 3a57a67..353013b 100644 --- a/examples/nordic_fob/nordic_fob.pde +++ b/examples/nordic_fob/nordic_fob.pde @@ -1,5 +1,5 @@ /* - Copyright (C) 2011 J. Coliz + Copyright (C) 2012 J. Coliz This program is free software; you can redistribute it and/or 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, - * 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. + * This is an example of how to use the RF24 class to receive signals from the + * Sparkfun Nordic FOB. See http://www.sparkfun.com/products/8602 . + * Thanks to Kirk Mower for providing test hardware. */ #include +#include #include "nRF24L01.h" -#include "RF24.h" #include "printf.h" // @@ -26,96 +25,53 @@ // 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 'ping' transmitter -const int role_pin = 7; +RF24 radio(8,9); // -// Topology +// Payload // -// Radio pipe addresses for the 2 nodes to communicate. -const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL }; +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; // -// 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 +// Forward declarations // -// The various roles supported by this sketch -typedef enum { role_ping_out = 1, role_pong_back } role_e; +uint16_t flip_endian(uint16_t in); -// 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; +// +// 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_ping_out; - else - role = role_pong_back; - // // Print preamble // Serial.begin(57600); printf_begin(); - printf("\n\rRF24/examples/pingpair/\n\r"); - printf("ROLE: %s\n\r",role_friendly_name[role]); + printf("\r\nRF24/examples/nordic_fob/\r\n"); // - // Setup and configure rf radio + // Setup and configure rf radio according to the built-in parameters + // of the FOB. // 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]); - } + radio.setChannel(2); + radio.setPayloadSize(4); + radio.setAutoAck(false); + radio.setCRCLength(RF24_CRC_8); + radio.openReadingPipe(1,0xE7E7E7E7E7LL); // // Start listening @@ -130,91 +86,56 @@ void setup(void) radio.printDetails(); } +// +// Loop +// + 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 ( radio.available() ) { - // Dump the payloads until we've gotten everything - unsigned long got_time; - bool done = false; - while (!done) + // 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--) { - // 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); + if ( ! ( payload.buttons & _BV(i) ) ) + { + printf("%s ",button_names[i]); + } } - // First, stop listening so we can talk - radio.stopListening(); + // If no buttons, print None + if ( payload.buttons == _BV(num_buttons) - 1 ) + printf("None"); - // Send the final one back. - radio.write( &got_time, sizeof(unsigned long) ); - printf("Sent response.\n\r"); - - // Now, resume listening so we catch the next packets. - radio.startListening(); + 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