Go Down

Topic: RF24 Library: Driver for nRF24L01(+) 2.4GHz Wireless Transceiver (Read 106 times) previous topic - next topic

maniacbug


First off. Thanks for this great library and all the good info in this thread.


Thanks!

Quote

Secondly. In the bundled examples with the library many of the comments state that you should use pin 8 & 9 on your arduino for radio communication, while the code directly beneath the comment declares pin 9 & 10 instead. Caused some headache for me and a buddy of mine who tried out the nRF24L01 modules today for the first time. We finally figured it out though :)


Doh!  Thanks for pointing that out, I will fix the comments.  I recently moved to 9/10 to align with the Getting Started tutorial.

fca

i switched to pin 6 &7 because the Ethernet shield use pin 10, so pay attention if you plan to use Ethernet shield...


Maniacbug: why the  radio.printDetails()  won't work in the rf24nework examples ?

like this
Code: [Select]
SPI.begin();
  radio.begin();
  network.begin(/*channel*/ 90, /*node address*/ this_node);
    radio.printDetails();    // Dump the configuration of the rf unit for debugging



Regards-


maniacbug

radio.printDetails() uses printf.  Do you have printf setup?  Requires a call to fdevopen.  All the RF24 examples and many of the RF24Network examples do this.

mirage00

Maniac... What a great job you have done with this library!!!  Donation will be coming your way.  I have a question.  I am working on a project that will require 100's of nodes with different ID's.  Whenever they are within 1 foot of eachother they need to start exchanging information.  How would you handle this since the roles are not defined.  They will need to figure that out at time of contact with each other.

maniacbug


Maniac... What a great job you have done with this library!!! 


Thanks!


I have a question.  I am working on a project that will require 100's of nodes with different ID's.  Whenever they are within 1 foot of each other they need to start exchanging information.  How would  you handle this since the roles are not defined.  They will need to figure that out at time of contact with each other.


Right...  This is not something explicitly covered by any of my code.  You are going to have to dig more into networking protocols.  You can start with CSMA/CD.  The "medium" in this case would be one shared pipe address that all nodes would use for node discovery.  Nodes could periodically send out an announcement frame, "I am node X", and always be listening for other such frames.  From this, they know who is around.  They could then initiate a private conversation on another pipe dedicated for that node when they wanted to talk to it.

You could also use some ideas from Zeroconf.

RF24 is designed purely to interface with the radio.  It really just controls the physical layer, or perhaps you could think of it as a very rudimentary MAC layer.  Anything more complicated is up to the app.  Separately, there is also the RF24Network which implements a very simple network layer that takes some significant shortcuts by assuming a static network structure.  Your network doesn't have such a simple structure, so that library is out.  RF24 will still gladly handle the radio interface, but your app has a bunch of work to do from there.

As far as the "within 1 foot", I don't know if that can be done with these radios.  But why do you need to?  If they are 15 feet away, is that a problem to exchange data?  If so, maybe you need some kind of NFC or RFID solution.

jettie

Thanks maniacbug a lot for your library.
You made learning process less disappointing ) I've tried your examples and they worked great.
I am now trying to figure out one thing but I don't think I'll be able to soon enough without help of gurus. 
So I have this pair of radio triggers (those that trigger a photo flash remotely) which actually use nRF24L01. All I know about them is only channel frequencies.
So my question is is it even possible to configure a receiver so that it would be somehow compatible with those triggers?

mirage00

#81
Dec 24, 2011, 03:26 pm Last Edit: Dec 24, 2011, 03:30 pm by mirage00 Reason: 1

As far as the "within 1 foot", I don't know if that can be done with these radios.  But why do you need to?  If they are 15 feet away, is that a problem to exchange data?  If so, maybe you need some kind of NFC or RFID solution.


Thanks for the quick response..  It's actually closer than 1 foot.  To be exact, the two devices will need to touch for 2 seconds to begin the negotiation sequence with eachother.  I decided on the nRF24L01 because of its extremly low power requirements and cost. This project requires very low power consumption.  

Quote
As far as the "within 1 foot", I don't know if that can be done with these radios

Why?

I need to research NFC.  Do you have any other suggestions for this type of setup?  

maniacbug

#82
Dec 24, 2011, 05:12 pm Last Edit: Dec 24, 2011, 05:15 pm by maniacbug Reason: 1

So I have this pair of radio triggers (those that trigger a photo flash remotely) which actually use nRF24L01. All I know about them is only channel frequencies.
So my question is is it even possible to configure a receiver so that it would be somehow compatible with those triggers?


You'll need detailed specifications for the trigger, preferably a copy of the firmware that runs on the unit.  Dark wizards of wireless can reverse engineer the settings by sniffing, but for your purposes I'd go with the "get more information" route.


Quote
As far as the "within 1 foot", I don't know if that can be done with these radios

Why?
I need to research NFC.  Do you have any other suggestions for this type of setup? 


This radio has no way of knowing the exact physical distance.  It's designed to communicate at medium-short distances.  If you want a tap, NFC is definitely the way to go.

http://www.seeedstudio.com/depot/nfc-shield-p-916.html
http://www.adafruit.com/products/364

mirage00

#83
Dec 24, 2011, 07:59 pm Last Edit: Dec 25, 2011, 08:36 pm by mirage00 Reason: 1
I can handle the tap through a reed switch or contact switch.  I love the power requirements of the NRF24L01 and its cost.  My challenge now is to have them communicate.  What I have working is code that alternates the role of each device until it finds one another and exchanges payload and ack info.  It seems to work but, I sometimes have one unit power down without the other unit finding it.  Here is my code.  It's quick and dirty, so feel free to comment or improve!


Code: [Select]
void setup()
{
  //
  // Create role randomly every time
  //
  Serial.begin(57600);
  //randomSeed(analogRead(0));
  randomSeed(128937827);
  int num_random = int(random(1000));
  if (num_random % 2 == 0)
    role = role_sender;
  else
    role = role_receiver;

  //
  // Print preamble
  //
  printf_begin();
  printf("ROLE: %s\n\r",role_friendly_name[role]);
  printf("RANDOM NUMBER %d\n\r",num_random);

  //
  // Setup and configure rf radio
  //
  radio.begin();
 
  // Set levels for power
  radio.setPALevel(RF24_PA_MIN);
  radio.setDataRate(RF24_2MBPS);

  // We will be using the Ack Payload feature, so please enable it
  radio.enableAckPayload();

  if ( role == role_sender )
  {
    radio.openWritingPipe(pipe);
  }
  else
  {
    radio.openReadingPipe(1,pipe);
    radio.startListening();
  }

  //
  // Dump the configuration of the rf unit for debugging
  //
  radio.printDetails();
 
  pinMode(4, OUTPUT);


};


void loop(void)
{
 
  if (OtherDeviceID==0)
    OtherDeviceID=GetOtherDeviceID();
  else
  {
      digitalWrite(4, HIGH);   // set the LED on
      delay(1000);              // wait for a second
      digitalWrite(4, LOW);    // set the LED off
      delay(1000);              // wait for a second
     
  }
}

// connect to available device
// when connected exchange enough information and then turn off
uint32_t GetOtherDeviceID()
{

  static uint32_t message_count= 0; // use message count for now/ will change to unique ID
  static uint32_t tmpOtherDeviceID= 0;
 
  while (! foundAnother)
  {
    //
    // Sender role.  Repeatedly send the current time
    //
    if (role == role_sender && !foundAnother )
    {
   
      // Take the time, and send it.  This will block until complete
      unsigned long time = millis();
      printf("Sending this device ID: %lu\n\r",ThisDeviceID);
      radio.write( &ThisDeviceID, sizeof(ThisDeviceID) );
 
      if ( radio.isAckPayloadAvailable() )
      {
        radio.read(&tmpOtherDeviceID,sizeof(tmpOtherDeviceID));
        printf("Received other device ID: [%lu]\n\r",tmpOtherDeviceID);
        foundAnother=true;
      }
      //printf("OK\n\r");
     }
 
    //
    // Receiver role.  Receive each packet, dump it out, add ack payload for next time
    //
   
    if ( role == role_receiver  && ! foundAnother )
    {
      // 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( &tmpOtherDeviceID, sizeof(tmpOtherDeviceID) );
 
          // Spew it
          printf("Received other device ID: [%lu]\n\r",tmpOtherDeviceID);
         }
 
        // Add an ack packet for the next time around.  This is a simple
        // packet counter
        radio.writeAckPayload( 1, &ThisDeviceID, sizeof(ThisDeviceID) );
        ++message_count;
        foundAnother=true;
      }
    }
   
   
    if ( ! foundAnother)
    {
       if ( role == role_sender )
        {
          radio.openReadingPipe(1,pipe);
          radio.startListening();
          role=role_receiver;
        }
        else
        {
          radio.stopListening();
          radio.openWritingPipe(pipe);
          role=role_sender;
        }
       
        // randomly delay to give time for other device to connect
        randomSeed(millis());
        delay(int(random(1000,2000)));
        //printf("CHANGING ROLE TO: %s\n\r",role_friendly_name[role]);
    }
  }
 
  return tmpOtherDeviceID;
}

MarkT

I note when you change from listening to sending mode you do a random(1000,2000) delay whilst not transmitting nor listening... The node is useless during this delay - if you always listen during delays to avoid missing a packet from the other end then you'll have a much better chance of success...
[ I won't respond to messages, use the forum please ]

mirage00

#85
Dec 25, 2011, 07:43 pm Last Edit: Dec 25, 2011, 08:36 pm by mirage00 Reason: 1
Thanks... I tried changing the code to remove the stop listening when i switch roles but it caused the devices to have a worse connection rate.  Right now, I can get the devices to exchange the information 8 out of 10 times.  When it doesnt connect, one device received the other devices ID but the other device just continues sending its ID without receiving a ACK confirmation.  It works well execpt for this issue.  I'm sure there is a more clever/graceful way of doing this but I havn't figured it out yet.

maniacbug


What I have working is code that alternates the role of each device until it finds one another and exchanges payload and ack info.  It seems to work but, I sometimes have one unit power down without the other unit finding it.  Here is my code.  It's quick and dirty, so feel free to comment or improve!


Hey, for the sake of the forum readership it would be great if you could edit the post and surround the code there with a 'code' block.  Just select the text and press the '#' button on the web toolbar above the editing area.

Having some kind of delay is good, but implementing it as a 'delay' will get in the way.  Better to use a counter you compare against the current millis(), like the "BlinkWithoutDelay" sketch.    That said, the main thing here is to not delay while the radio not listening.  Only delay after a call to startListening().  That way anything which comes in while you're delaying will get received.

kodde

I was doing some test with two nRF24L01+ and when using my Arduino Uno as transmitter I would get substantially better connection (less failed attempts) when powering the Arduino with the USB cable than when using a 12V barrel power connection.

How is this? Is this normal?

I'm planning on installing a nRF24L01+ through an Arduino Mini Pro 3.3V in my motorcycle. Would altering my input power source to a certain voltage have anything to do with the transmission success rate?

Thanks.

Grag38

Hello everybody,

I'm posting on this thread because it seems more active comparing on the one I posted few days ago (http://arduino.cc/forum/index.php/topic,84526.0.html)

I've got one question. Can we use RF24 to broadcast datas...

I mean, 1 RF24 act as master and send datas through a pipe. I would like to know if I use several RF24 as slave, can they listen to these datas, without asking to get it.

So from, each RF24 slave module listen to the pipe, and if there is data, EVERY one can read it.

Will things can works like that or must I have to proceed in other way ?

Thanks for your lights.

Grag38

maniacbug


I've got one question. Can we use RF24 to broadcast datas...

I mean, 1 RF24 act as master and send datas through a pipe. I would like to know if I use several RF24 as slave, can they listen to these datas, without asking to get it.

So from, each RF24 slave module listen to the pipe, and if there is data, EVERY one can read it.


Hi, so first a quick word on terminology.  nRF24L01(+) is the name of the radio, and RF24 is the library you can used to drive those radios.

You absolutely can, in theory, drive the radios with this driver to 'broadcast' a packet to multiple units who are all listening on the same pipe.  The key is to disable the AutoAck (see RF24::enableAutoAck()), so they don't all try to send an ack back, and so the sender doesn't expect one.  I say 'in theory' because I've not actually heard reports of anyone doing this.  But from the documentation, it would seem to be possible.

Go Up