Go Down

Topic: [SOLVED] -~- nRF24L01(+) and Turning Point Clickers question (Read 1 time) previous topic - next topic

May 27, 2012, 09:10 am Last Edit: May 28, 2012, 01:08 am by kquinsland Reason: 1
this post will be a long one

I'll spare you the why and how until i can invest more time in a more through writeup.  For now, the technical question:

Why can't i get *data* from my radio?  I can clearly see that *something* is being picked up, but i can't get data.

I've spent the past few hours trying to get my TurningPoint Clicker working with a 24L01+ radio as inspired by this post  here: http://hackaday.com/2010/07/05/reverse-engineering-an-rf-clicker/

Now, using RF24 library and the scanner example, i have put together a a very botched bit of code

Code: [Select]

/*
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);


struct payload_t
{
 uint8_t b1;
 uint8_t b2;
 uint8_t b3;
 uint8_t b4;
};

//
// 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.setAutoAck(false);
 radio.setChannel(10);
 radio.setPayloadSize(4);

 radio.setCRCLength(RF24_CRC_16);
 radio.openReadingPipe(6,0xF0F0F0F0AALL);
 radio.openReadingPipe(5,0xF0F0F0F0BBLL);
 radio.openReadingPipe(4,0xF0F0F0F0CCLL);
 radio.openReadingPipe(3,0xF0F0F0F0DDLL);
 radio.openReadingPipe(2,0xF0F0F0F0EELL);
 radio.openReadingPipe(1,0xF0F0F0F0FFLL);
 radio.openReadingPipe(0,0xF0F0F0F011LL);

 //
 // Start listening
 //
 radio.startListening();

 //
 // Dump the configuration of the rf unit for debugging
 //

 Serial.println("DETAILS");
 radio.printDetails();
}

//
// Loop
//
int tmp = 0;


void loop(void)
{
 //
 // Receive each packet, dump it out
 //


if ( radio.testCarrier() ){
 Serial.print(tmp);
 Serial.print(" : ");
 Serial.println("Carrier!");
 tmp++;
 

 
   // if there is data ready
   if ( radio.available() )
   {
     Serial.println("Payload 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));

     Serial.println("payload len:");
     Serial.println(sizeof(payload));

     //printf("\r\n");
   }
}
}



// vim:cin:ai:sts=2 sw=2 ft=cpp




that generates this output:

Quote

RF24/examples/nordic_fob/
DETAILS
STATUS       = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1   = 0xf0f0f0f011 0xf0f0f0f0ff
RX_ADDR_P2-5   = 0xee 0xdd 0xcc 0xbb
TX_ADDR       = 0xe7e7e7e7e7
RX_PW_P0-6    = 0x07 0x07 0x07 0x07 0x07 0x07
EN_AA = 0x00
EN_RXADDR = 0x3f
RF_CH    = 0x0a
RF_SETUP= 0x07
CONFIG    = 0x07
DYNPD/FEATURE = 0x00 0x00
Data Rate= 1MBPS
Model       = nRF24L01+
CRC Length    = Disabled
PA Power    = PA_HIGH
0 : Carrier!
1 : Carrier!
2 : Carrier!
3 : Carrier!
4 : Carrier!
5 : Carrier!
6 : Carrier!
7 : Carrier!
8 : Carrier!
9 : Carrier!
10 : Carrier!
11 : Carrier!
12 : Carrier!
13 : Carrier!
14 : Carrier!
15 : Carrier!
-- < SNIP >--
700 : Carrier!
701 : Carrier!
702 : Carrier!
703 : Carrier!
   



Now, it took a while, but i know that my clicker is on channel 10.
Notice how i can check for a carrier signal when the radio is on channel 10, and i get ~ 700 'samples'.  This is how i know that the radio is on the correct channel and that it does see something.

so.  HOW DO I GET THE PACKET PAYLOAD?

If you look at the blog post i linked to at the beginning, you can see that the author does a few things to get his radio working:


  • disable shockburst

  • set 4 byte packet length

  • set a 16 bit checksum



and looking at the status registers EG:
Quote
EN_AA = 0x00
EN_RXADDR = 0x3f
RF_CH    = 0x0a
RF_SETUP= 0x07
CONFIG    = 0x07


i know that i have this radio set up properly (at least i **think** i do).


It's late, and i am tired / have other thing to get to, so i think this is a decent place to wrap this up.

I'll get back to you asap with replies

THANKS FOR YOUR TIME / READING THIS FAR!

P18F4550

#1
May 27, 2012, 11:15 pm Last Edit: May 27, 2012, 11:17 pm by P18F4550 Reason: 1
Hello, this reply is a bit patchy as it's been a while since i've used these radio's, and then i only used the radio modules, i've never used the keyfob.

This is my test TX code, it gets a reading from AN0 and sends it with 24L01 radio
Code: [Select]
#include <Spi.h>
#include <mirf.h>
#include <nRF24L01.h>

int l=65;
int ledPin =  8;
void setup()
{
//  Serial.begin(9600);
   pinMode(ledPin, OUTPUT);

 Mirf.init();
 Mirf.setRADDR((byte *)"clie1");
 Mirf.payload = sizeof(int);
 Mirf.config();

}

void loop()
{
// byte data[Mirf.payload];
 Mirf.setTADDR((byte *)"serv1");

 int temp = analogRead(0);
 Mirf.send((byte *) &temp);
 
 while(Mirf.isSending())
 {
 }

 digitalWrite(ledPin, HIGH);  
 delay(50);              
 digitalWrite(ledPin, LOW);  
 delay(950);      

}


This my test RX code it listens for a packet then displays it
Code: [Select]
#include <LiquidCrystal.h>
#include <Spi.h>
#include <mirf.h>
#include <nRF24L01.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

void setup()
{
 //Serial.begin(9600);
 lcd.begin(16, 2);
 Mirf.cePin = 49;
 Mirf.csnPin = 53;
 Mirf.init();
 Mirf.setRADDR((byte *)"serv1");
 Mirf.payload = sizeof(int);
 Mirf.config();

}

void loop(){
 int data;
 if(Mirf.dataReady())
 {
   //Serial.println("Got packet");
   lcd.setCursor(0, 0);
   lcd.print("Got Packet");
   
   Mirf.getData((byte *) &data);
   //Serial.println(data);
   lcd.setCursor(0, 1);
   lcd.print(data);
 }
}


in both cases i have used mirf.h & nRF24L01.h which are in the playground i think.
I think your right in saying your getting something but the something your getting is not addressed to the RX so it's not processing the packet

My TX is called serv1
Code: [Select]
Mirf.setTADDR((byte *)"serv1");

My RX recieves from serv1
Code: [Select]
Mirf.setRADDR((byte *)"serv1");

Sorry i haven't explained it very well but the above code does work on IDE_0018 with Spi.h not SPI.h

Thanks for taking the time/effort to post that.  I figured out what my mistake was a few hours ago and I've been hacking away ever since. Here's the working code.

My mistake was not using the correct address for the data pipe.  Travis Goodpseed noted that by default the clickers seek out a dadapipe with address 123456.  I neglected to use this address initially.   (working) code posted below:

---
Code: [Select]
  /**
   * Example Turning Point Clicker Sniffer
   *
   * This is an example of how to use the RF24 class to receive signals from the
   * TurningPoint ResponceInnovations ResponceCardRF
   *
   *
   * I want to make it VERY CLEAR that I am standing on the shoulders of GIANTS
   *
   * The author of this class - maniacbug - deserves a lot of credit for the work put into this
   * amazingly comprehensive library.
   *
   * http://maniacbug.github.com/RF24/
   *
   * and so does  Travis  Goodspeed for his work in reverse engineering the original clicker firmware
   * http://travisgoodspeed.blogspot.com/2010/07/reversing-rf-clicker.html
   *
   */
 
  #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);
 
 
  struct payload_t
  {
    byte sender[3];
    uint8_t button;
  };
 
  // the address that clickers will try to send to
  // also the address that basestation should reply from
  const uint64_t BASE_STATION_ADDRESS = 0x123456;
 
  //
  // Setup
  //
 
  void setup(void)
  {
    //
    // Print preamble
    //
 
    Serial.begin(57600);
    printf_begin();
   
    //
    // Setup and configure rf radio according to the built-in parameters
    // of the FOB.
    //
 
    radio.begin();
 
    // Disables Shockburst?
    radio.setAutoAck(false);
 
    // GO,1,0,GO
    radio.setChannel(10);
 
    // 3 bytes for remote addr, 1 byte for button
    radio.setPayloadSize(4);
 
    // CRC is 16 bits
    radio.setCRCLength(RF24_CRC_16);
 
    // we need to READ here
    radio.openReadingPipe(1,BASE_STATION_ADDRESS);
 
    //
    // Start listening
    //
    radio.startListening();
 
    //
    // Dump the configuration of the rf unit for debugging
    //
 
    radio.printDetails();
  }
 
 
 
  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) );

 
       printf("SENDER: %02X:%02X:%02X. BUTTON: %02X \n", payload.sender[0], payload.sender[1], payload.sender[2], payload.button);
       
      }
   
    delay(1000);
  }

Go Up