nRF24L01 and UNO R3 Tutorial

I have been struggling for a few days how to get the nRF24L01 module to work with my Arduino Uno and an standalone ATMega328. Here is how I eventually did it. I use the IDE 1.0.1.

This sketch simply turns on a LED on the receiver when a button on the transmitter is pressed. The transmitter transmits the code "111." The receiver receives the code "111" and turns on the LED. This is the way I did it, let me know if it works for you or if you have any improvements.

  1. Go to GitHub - maniacbug/RF24: Arduino driver for nRF24L01.
  2. Download the ZIP file (button is located near the top).
  3. Unpack the ZIP file.
  4. Go to the folder /Users/YourUserName/Documents/Arduino/libraries.
  5. Create the following folders in the "libraries" folder:
  6. nFR24L01
  7. RF24
  8. Open the "nFR24L01" folder, and drag the following file from the ZIP folder into it:
  • nRF24L01.h
  1. Open the "RF24L01" folder, and drag the following files from the ZIP folder into it:
  • RF24_config.h
  • RF24.ccp
  • RF24.h
  1. Connect the following pins to your Arduino:
  • Pin 9 - CE
  • Pin 10 - CS(N)
  • Pin 11 - MOSI
  • Pin 12 - MISO
  • Pin 13 - SCK
    On the Receiver:
  • Pin 3 - LED
    On the Transmitter:
  • Pin 7 - Button
  1. Copy the following sketch to your TX arduino:
    (Adapted from http://www.bajdi.com/rf24-library-revisited/)
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int SW1 = 7;
 
void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);}
 
void loop(void){
  if (digitalRead(SW1) == HIGH){
  msg[0] = 111;
  radio.write(msg, 1);}}
  1. Copy the following sketch to your RX arduino:
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int LED1 = 3;
 
void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(1,pipe);
  radio.startListening();
  pinMode(LED1, OUTPUT);}
 
void loop(void){
  if (radio.available()){
    bool done = false;    
    while (!done){
      done = radio.read(msg, 1);      
      Serial.println(msg[0]);
      if (msg[0] == 111){delay(10);digitalWrite(LED1, HIGH);}
      else {digitalWrite(LED1, LOW);}
      delay(10);}}
  else{Serial.println("No radio available");}}

If you just want to share your success, this would be better under the Exhibition / Gallery section of the forum. The Project Guidance section is really for people who are seeking project guidance.

can you give some more information regarding changing the pipe and on which channel data is transmitter it might be useful for debuggin NRF24L01+ on some other hardware plateforms..

Thanks

Hello,

I just saw your Tutorial but since I bought a arduino micro I haven't got

  • Pin 11 - Pin 12 - Pin 13
    witch I resume is necessary for the MOSI,MISO, SCK connections.
    I would like to know if there is any possibility to change them to different pins?

Thanks,

If your Arduino's SPI is connected to different pins then just wire it to the equivalent pins on your Arduino. For the Arduino Micro, you'd need to use the relevant pins on the ICSP header.

Hey there!

I followed your instructions, and I when I used the serial monitor on the RX adrduino(I am using two Nanos) I keep getting the "Radio Not Available" message. I have checked my wires and connections to make sure that there are no opens, but I don't know what else to try. Does anyone have any suggestions or you ran into the same issue? Thanks!

farmkid:
Does anyone have any suggestions

Post a drawing / picture showing your hardware connections, and your sketches, and link to the source for any non-standard libraries you're using, and details of what it's doing (or not doing) wrong. For example if it's printing an error message on the serial port then give a copy of the serial output.

Hi, how can I add more leds this sketch? Thx.

I have my nano setup just like in the image above, (without the lamp connection). I have tested all my connections, and they're all good, bit I constantly get the "No radio available" message. Any ideas?

The only thing I can think is that I don't have the libraries set up right, but I don't get any errors about them. I wondered what the instructions meant when it said to create these two folders:

  1. nFR24L01
  2. RF24

But then only move the following files into the nFR24L01 folder. Does the RF24 folder need anything?

  1. Open the "nFR24L01" folder, and drag the following file from the ZIP folder into it:
  • nRF24L01.h
  1. Open the "RF24L01" folder, and drag the following files from the ZIP folder into it:
  • RF24_config.h
  • RF24.ccp
  • RF24.h

Ok, I can't believe I did this, but as soon as I posted I realized I don't have a problem.

I connected my transmitter up and and when I send a message I get the 111 message up on my receiver. When it's not receiving any messages is when the no radio message comes up... Unless I have something setup wrong that is... Anyway, I thought I'd leave my original message up as that diagram I posted helped me get this set up and running.

Thanks! :slight_smile:

How to pass a string using exempor?

#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
int msg[1];
RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;
int SW1 = 7;
 
void setup(void){
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);}
 
void loop(void){
  if (digitalRead(SW1) == HIGH){
  msg[0] = 111;
  radio.write(msg, 1);}}

Hi, I upload the following code to atMega2560 and an Uno Board...

Uno as sender...

/*        
        ####UPLOAD TO UNO####
        #    MOSI==>11      #
        #    MISO==>12      #
        #    SCK===>13      #
        # # # # # # # # # # #
        #CE_pin 7&CSN_pin 8 #
        #####################
*/


//====# header files #====
#include<SPI.h>
#include<nRF24l01.h>
#include<RF24.h>

//====# define #====
#define CE_pin 7
#define CSN_pin 8

//====# pre initializing #====
RF24 radio(CE_pin,CSN_pin);
const uint64_t mega_to_uno_pipe=0x0f0f0f0f01LL; //40 bit add, differs in lsb
const uint64_t uno_to_mega_pipe=0x0f0f0f0f02LL; // LL means long-long
int A=0xaaaa;
bool done;
//====# SetUp part #====
void setup(){
  Serial.begin(9600);
  radio.begin();
  radio.setPayloadSize(sizeof(A));
  radio.openReadingPipe(1,mega_to_uno_pipe);
  radio.openWritingPipe(uno_to_mega_pipe);
  radio.setRetries(0,0);
  radio.setDataRate(RF24_1MBPS);
	

  

}

//====# The main program #====
void loop(){
 done=radio.write( &A, 1 );
 Serial.print(done);
 delay(100);
}

And for Mega2560...

 /*       
        ####UPLOAD TO MEGA####
        #     MOSI==>51      #
        #     MISO==>50      #
        #     SCK===>52      #
        # # # # # # # # # # ##
        # CE_pin 7&CSN_pin 8 #
        ######################
*/


//====# header files #====
#include<SPI.h>
#include<nRF24l01.h>
#include<RF24.h>

//====# define #====
#define CE_pin 7
#define CSN_pin 8

//====# pre initializing #====
RF24 radio(CE_pin,CSN_pin);
const uint64_t mega_to_uno_pipe=0x0f0f0f0f01LL; //40 bit add, differs in lsb
const uint64_t uno_to_mega_pipe=0x0f0f0f0f02LL; // LL means long-long
int A;
bool done=false;
//====# SetUp part #====
void setup(){
  Serial.begin(9600);
  radio.begin();
  radio.setPayloadSize(sizeof(A));
  radio.openReadingPipe(1,uno_to_mega_pipe);
  radio.openWritingPipe(mega_to_uno_pipe);
  radio.setRetries(0,0);.
  radio.setDataRate(RF24_1MBPS);
  pinMode(13,OUTPUT);

}

//====# The main program #====
void loop(){
  radio.startListening();
  if(A==0xaaaa){
    done=true;
  }
  radio.read(&A,sizeof(A));
  radio.stopListening();
  digitalWrite(13,done);
  Serial.print(done);
  Serial.println(A);
  delay(100);
}

but I just received lots of 0 on my Serial Monitoring ...
please help me to connect my NRF it is very important 4 me...

Ok... You need a 10uF capacitor across the power of the NRF24L01 board.

Then try the pingpair example (Under file->examples-RF24.

Wire up as per instructions in the sketch, noting where your SPI pins actually are.

Thanks a lots
looks like it's time for soldering :slight_smile:
Ok I'll add ...
But do you mean my code is correct??

but still did not worked :frowning:

Try the pingpair example and post a picture of your code.

Also, you don't actually need to solder the capacitor on the board, I connect using a Dupont female to male into a breadboard and have the capacitor on the bread board.

Once you have the ping pair example working then you can move on.

I agree with the shannon member

Dear Forum users!

Greetings. I have some problem with nrf24L01+ (Ver A0).

I have two Nano V3s and two nrf24l01+ modules.

I'm using the following getting started code:

/*
 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 for Getting Started with nRF24L01+ radios. 
 *
 * This is an example of how to use the RF24 class.  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.
 */

#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(8,7);

//
// 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 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 = role_pong_back;

void setup(void)
{
  //
  // Print preamble
  //

  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();

  // 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)
  {
    // 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)
      {
        // 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.\n\r");

      // Now, resume listening so we catch the next packets.
      radio.startListening();
    }
  }

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

      // Become the primary transmitter (ping out)
      role = role_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");
      
      // Become the primary receiver (pong back)
      role = role_pong_back;
      radio.openWritingPipe(pipes[1]);
      radio.openReadingPipe(1,pipes[0]);
    }
  }
}
// vim:cin:ai:sts=2 sw=2 ft=cpp

I get the following serial output (attached as images)

When I enter into Transmit mode, I get: Now sending xxxx......failed.
Failed, response timed out.

I'm starting to feel that the modules are faulty.

Anyone has suggestions, how to proceed?

I've already tested the Nanos, they work just fine.

Thank you,

Gergő

How were your modules packed? I'm finding that many sellers on Amazon, and Sainsmart in particular, are shipping in nonstatic pink foam and a regular clear plastic bag, neither of which protects from outside static discharge. Sainsmart shipped me several things in regular staticky white foam, and even packing peanuts! With staticky clear packing tape holding the foam to the pins! I struggled for months trying to get some Sainsmart 2.4GHz modules and some 3.2 inch color TFT displays to work. I thought it was me. I got an experience programmer friend of mine to try them out, they are all either nonworking or damaged.

Who here has -not- seen how much static cling packing peanuts have? Have you ever been zapped getting out of your car? Imagine one postal vehicle doing that through your box.

I fear that many newbies get discouraged because they think they cannot program, when in fact some of their boards and shields have been damaged by static discharge.

FYI, I've been repairing and designing electronics for a very long time. I know proper ESD protection and handling.

Dave Jones of EEVBlog does some actual testing of the pink plastic versus silvery static shielding bags.

You may have the point.

The 5 nRF24L01s were packed in a simple zip-bag. And covered with some bubble wrap, no ESD protection.

I've ordered from ebay, not sainsmart brand, much cheaper than that.

I have a sainsmart uno, mega, 3.2" LCD, lcd shield, relay boards, 1602 LCD, and a couple of other stuff ordered from sainsmart, they were all very-well and properly packed in welded anti-ESD bags separately, and they all work flawlessly.

I have the feeling that Sainsmart is getting "copied", I mean, fake products may have appeared. Actually they are the "best quality" clones if I can say such thing, some may have seen the potential in it. Or they have bad QC and I was lucky so far.

I have some other clones, like Funduino and others, they have mixed quality, with mixed forms of packing.

And of course I have genuine UNO for a critical application.

Hello,
I use two arduino uno and two nRF24L01 module, and i have tested all my connection. But I constantly get the "NO radio available". Is there has any wrong i could not find out?

Thanks!