Radio modules - nRF24L01+

I am trying to get two arduino to talk using radio modules. I bought several nRF24L01+ kits from Addicore and have been unable to get them to work. I am using the RF24 library from github. I am using the example code named “GettingStarted” because it is designed such that you load the same code on both Arduino then you run them and on the one you want to be the transmitter, you send a “T” via the serial monitor and it starts transmitting. Unfortunately it does not seem to work. Everything compiles just fine.

I am using IDE 1.6.5. The following code is un-edited by me. The attached PDF shows my hookups between the arduino and the nRF24L01+. There is a breakout board that came with these radios and I am using them.

/*
 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(9,10);

//
// 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

arduino hookup info.pdf (472 KB)

Your code says using pin 10.
Picture says pin 10 empty in one spot.
Are the pictures of what you actually have or are they examples?

Frostline:
Your code says using pin 10.
Picture says pin 10 empty in one spot.
Are the pictures of what you actually have or are they examples?

Yeah, those are actual pictures of my setup and I forgot to indicate that I am using pins 8 and 9 instead of 9 and 10. So the code I uploaded has actually been modified where it calls the constructor and my copy of the code has been changed to use 8 and 9. I will add however, that I ruled that out as a potential problem by using 9 and 10 and still got nothing.

Some other things I tried is, I ordered an genuine Arduino and replaced one of the two knockoffs with it and still did not work. After that, I thought maybe I was getting interference from the RV parks WiFi so I took my stuff for a ride in my truck to a park a few miles away where there should be no Wifi and got the same results. So then I ordered one of the 433mhz radio sets and tried that using the VirtualWire library. That does not work either so I have all but given up but I figured I would reach out here and see if anyone might have some thoughts. These things work for others quite well from what I've seen.

Might try the library GitHub - nRF24/RF24: OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
and power the radios on a different power supply than the Arduinos.
What are you getting on serial monitor when you try to switch one to transmit?

It goes into transmit mode, the serial monitor shows "Now sending 9999....Failed" where the 9999 is digits from the time. the call to radio.write never returns true. What is weird is that when I watched the receiver at one point it appeared to be getting something but when I turned off the transmitter, the receiver continued to think it was receiving something. That is what made me think there was a problem with interference in the rv park from the parks WiFi but I ruled that out by taking a ride in my truck and testing in an area where there was unlikely to be any WiFi to interfere.

Frostline:
Might try the library https://github.com/tmrh20/RF24
and power the radios on a different power supply than the Arduinos.
What are you getting on serial monitor when you try to switch one to transmit?

I tried powering it off a seperate 3.3V power as suggested, no joy. When I turn on the serial monitor I get the following (See attachment). Seems to me that the radio has not been initialized based on what I am seeing but why is a mystery since I am using the RF24 library’s example.

But you didn’t try the alternative library as suggested?
Oh and Wifi should not matter. I did all my testing with these radios in a room with two wifi routers within 20 feet of the devices.

One problem I've had with nRF24L01s is they may "overpower" each other when close together, I fixed it by reducing RF power a step at a time, like this with RF24 library.

radio.setPALevel(RF24_PA_MIN);

fwiw I tried using thes on an Arduino mega. and no matter what I tried, including following the advice on the forums.... never got it to work. I ended up using some superheterodyne 433mhz rx and tx units and have been very happy.

good luck.

I tried powering it off a seperate 3.3V power as suggested, no joy.

Make sure the two grounds are connected together.

It is probably a hardware/wiring problem but you should give this library a try:

http://www.airspayce.com/mikem/arduino/RadioHead/

Its a good, well supported library that works well with a range of modules.

Hi,
I have been experimenting with NRF24L01 units this afternoon, using the RF24Network library and have not had many problems, mainly setting an example up to send some numbers from one to either of two other units.
I'm only doing 1Tx to 2Rx , not two way.

If you like I can post them for you to try.

Tom... :slight_smile:

Frostline:
But you didn't try the alternative library as suggested?
Oh and Wifi should not matter. I did all my testing with these radios in a room with two wifi routers within 20 feet of the devices.

Actually, yes I did try the alternative library and when I bring up the serial monitor, all I get is the 2 lines, the second one of which says enter T to begin transmitting but when I do that, nothing happens.

lemming:
Make sure the two grounds are connected together.

It is probably a hardware/wiring problem but you should give this library a try:

RadioHead: RadioHead Packet Radio library for embedded microprocessors

Its a good, well supported library that works well with a range of modules.

I powered it off a breadboard with it's own power source (3.3V) and I ran a lead from the negative rail on the breadboard to the GND pin on the Arduino UNO. I assume that takes care of the common ground you talked about? Oh and I also have a 10uF capacitor on the breadboard between the positive rail and the ground rail as well to take care of the power issue that many say is a problem with the nRF24L01+

I've also tried using a 433mhz recvr/trans pair and unable to get those working either.

Take a picture of how you have it all wired

steve62557:
Actually, yes I did try the alternative library and when I bring up the serial monitor, all I get is the 2 lines, the second one of which says enter T to begin transmitting but when I do that, nothing happens.

You got these two lines?

RF24/examples/GettingStarted
*** PRESS ‘T’ to begin transmitting to the other node

But when you press t the serial monitor does not change?
You are making sure the cursor prompt is in the serial monitor text input box at the top of the serial monitor window and pressing after pressing t? And serial monitor is setup to NEWLINE in the little pull down menu at the bottom next to where you set the baud rate?
I ask all that because at one time or another I have messed up on all of them.

You don’t start getting this?

*** CHANGING TO TRANSMIT ROLE – PRESS ‘R’ TO SWITCH BACK
Now sending
failed
Failed, response timed out.

Mine is showing failure because I am only using one radio so nothing can be sent back. But the example should at least switch the state of the one radio from receiver to transmitter which it seems that your’s is not doing.

I would question correct wiring and proper modification of the sketch for the pins you are using and proper baud rate set in serial monitor.

Based on using the Getting Started sketch in the TMRh20 library.
I suggest doing pins as follows…
RF24L01+ Arduino Uno/Nano
GND GND
VCC 3v3
CE D9
CSN D10
SCK D13
MOSI D11
MISO D12
IRQ not necessary in Getting Started sketch.

Also make sure you alter line 16 in the sketch to RF24 radio(9,10);
And try using a serial connection of 9600.
So modify line #25 to Serial.begin(9600);
Make sure serial monitor is set to 9600.
Then see if radio will at least allow switching of roles.

Yes, I did all that and it never changes modes.

That said, I’m trying to go simple here using the following code. It gets to the radio.write line and never gets beyond that line. I’m really getting frustrated. I have attached pictures of my setup.

/* YourDuinoStarter Example: nRF24L01 Transmit Joystick values
 - WHAT IT DOES: Reads Analog values on A0, A1 and transmits
   them over a nRF24L01 Radio Link to another transceiver.
 - SEE the comments after "//" on each line below
 - CONNECTIONS: nRF24L01 Modules See:
 http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo
   1 - GND
   2 - VCC 3.3V !!! NOT 5V
   3 - CE to Arduino pin 9
   4 - CSN to Arduino pin 10
   5 - SCK to Arduino pin 13
   6 - MOSI to Arduino pin 11
   7 - MISO to Arduino pin 12
   8 - UNUSED
   - 
   Analog Joystick or two 10K potentiometers:
   GND to Arduino GND
   VCC to Arduino +5V
   X Pot to Arduino A0
   Y Pot to Arduino A1
   
 - V1.00 11/26/13
   Based on examples at http://www.bajdi.com/
   Questions: terry@yourduino.com */

/*-----( Import needed libraries )-----*/
#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
/*-----( Declare Constants and Pin Numbers )-----*/
#define CE_PIN   9
#define CSN_PIN 10
#define JOYSTICK_X A0
#define JOYSTICK_Y A1

// NOTE: the "LL" at the end of the constant is "LongLong" type
const uint64_t pipe = 0xE8E8F0F0E1LL; // Define the transmit pipe


/*-----( Declare objects )-----*/
RF24 radio(CE_PIN, CSN_PIN); // Create a Radio
/*-----( Declare Variables )-----*/
int joystick[2];  // 2 element array holding Joystick readings

void setup()   /****** SETUP: RUNS ONCE ******/
{
  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(pipe);
}//--(end setup )---


void loop()   /****** LOOP: RUNS CONSTANTLY ******/
{
  joystick[0] = analogRead(JOYSTICK_X);
  joystick[1] = analogRead(JOYSTICK_Y);
  Serial.println(joystick[0]);
  Serial.println(joystick[1]);
  radio.write( joystick, sizeof(joystick) );
  Serial.println("write exectured");

}//--(end main loop )---

/*-----( Declare User-written Functions )-----*/

//NONE
//*********( THE END )***********

IMG_20150802_150458949_HDR.jpg

IMG_20150802_150528604_HDR.jpg

where is the code for the reciever? can you take a top down picture of both arduinos.

Your wiring looks correct.

I loaded the code you posted into one Uno with a radio hooked up the same way. Code runs. Serial monitor shows random floating values for the analog pins(without joystick hooked up it is what I expected) and prints the "write exectured" line.

I assume you have tried swapping radios?
Have you checked your wires for possible breaks, or used different wires?
Never accidentally hooked radio VCC to 5v?

I can sympathize with the frustration feeling.

Qdeathstar:
where is the code for the reciever? can you take a top down picture of both arduinos.

The receive code can be found on the following page just after the transmit code at the following location ==> http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo

I did not set up the other UNO as a receiver yet because I wanted to see if the transmit code would work. I inserted a few debug lines to print serial messages so I could see what points the code was at and my test showed it ran as far as the radio.write but never gets beyond that point.

Frostline:
Your wiring looks correct.

I loaded the code you posted into one Uno with a radio hooked up the same way. Code runs. Serial monitor shows random floating values for the analog pins(without joystick hooked up it is what I expected) and prints the "write exectured" line.

I assume you have tried swapping radios?
Have you checked your wires for possible breaks, or used different wires?
Never accidentally hooked radio VCC to 5v?

I can sympathize with the frustration feeling.

I will do a continuity check on my leads first chance I get. I will also swap out the radio with another one that I have yet to open.

As much trouble as I am having I am afraid to use these in a production run for fear I won't be able to trust them to work consistently. These video's make it look so easy but so far my results have been dismal. :confused:

If a capacitor is required I'm really surprised they haven't modified these units to already have said capacitor on them so they work right out of the box. I've tried using a capacitor on the breadboard instead of soldering one right onto the radio module but it does not appear to make any difference that I can see.