nRF24L01 wireless communication (Failed, response timed out) (SOLVED-ish)

Hello All,

I recently purchased two nRF24L01+PA+LNA units. I have connected each nRF24L01+PA+LNA to their own separate Arduino Uno (using jumper wire cables), and both Adruino Unos are connected to the same computer. I downloaded Maniacbug's RF24 library, and am now trying to run the "GettingStarted" sketch (see code below).

However, I keep getting the following message "Failed, response timed out" (see "Serial Display" below). I have been reading through the forum, and many people have suggested using smoothing capacitors between Vcc and ground. I have tried this, but I am still not having any success. I would really appreciate any suggestions.

Thanks,

Dustin

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(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[img][/img]

Serial Display:

RF24/examples/GettingStarted/
ROLE: Pong back
*** PRESS 'T' to begin transmitting to the other node
STATUS = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1 = 0xf0f0f0f0d2 0xf0f0f0f0d2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xf0f0f0f0d2
RX_PW_P0-6 = 0x20 0x20 0x00 0x00 0x00 0x00
EN_AA = 0x3f
EN_RXADDR = 0x03
RF_CH = 0x4c
RF_SETUP = 0x07
CONFIG = 0x0f
DYNPD/FEATURE = 0x00 0x00
Data Rate = 1MBPS
Model = nRF24L01+
CRC Length = 16 bits
PA Power = PA_HIGH
*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK
Now sending 3979...failed.
Failed, response timed out.
Now sending 5253...failed.
Failed, response timed out.
Now sending 6525...failed.
Failed, response timed out.
Now sending 7798...failed.
Failed, response timed out.
*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK

TwoChain:

/*

// Radio pipe addresses for the 2 nodes to communicate.
const uint64_t pipes[2] = { 0xF0F0F0F0E1LL, 0xF0F0F0F0D2LL };




RX_ADDR_P0-1 = 0xf0f0f0f0d2 0xf0f0f0f0d2
RX_ADDR_P2-5 = 0xc3 0xc4 0xc5 0xc6
TX_ADDR = 0xf0f0f0f0d2

The response form the module above shows that you are having problems communicating with the module. The output shows the first 2 receiving addresses are the same as the transmit address so this module is only listening to itself and not the other module. The RX_ADDR_P1 should end in E1 as set by the code above. So first you need to make sure that communication with the module is solid before trying to talk to the other unit. In my experience a good test is to repeatedly reset the arduino and look at the module status/response .. it should be the same every time. If it isn't you have some form of interference with the arduino-module connection. You obviously have the pins connected correctly so look for other reasons

  • are the jumper wires good quality or could there be a higher resistance connection somewhere
  • add a capacitor to the power connectors on the module ( you have already done this )
  • are the jumper wires passing over/round a source of interference

Just a few things to try. Don't waste your time trying to communicate with another unit until you have solid communication between the arduino and the module.

1 Like

Hello Crofter,

Thank you for the advice and clear instructions. I didn't realize the nRF24L01 was having trouble communicating with my Arduino, but I am actually relieved to hear that it was. I at least have somewhere to begin trouble shooting.

Again, I appreciate the tips and I will update everyone if I get it working.

Thank you,

Dustin

Well... I have 2 pieces of good news and one piece of bad news.

Good news:

  1. I tried wiggling some wires, and I was able to get the nRF24L01 to properly communicate with the Arduino (thank you for pointing this out Crofter). However even after getting proper communication I was not able to successful send data between the two wireless units for over an hour.
  2. For some reason, out of nowhere, the units started working. They are still a little touchy, but I get nearly 100 % successful data transfer.

Bad news: I have no idea why they suddenly decided to work. I have noticed that if I poke around near my smoothing capacitor, things start to go awry. Also, if I move the Uno at all then I start to get failed transmission . This makes me think that a lot of my issues have to do with poor electronic connections through my ultra cheap jumper cables and my breadboard. I suspect that if I solder this stuff together properly, I will have much more success.

Anyways, thanks again to Crofter for alleviating my frustration. I at least know that my nRF24L01 units are working, and now I can start focusing on isolating the poor connection(s).

Dustin

Alsor ensure the Mcu and nrf share the same ground line ?.

Essef 8)

Dustin,

Did you ever get this to work reliably?
I am having the exact same problem.
However, wiggling or replacing my wires does not appear to be helping :frowning:

also, what size cap did you find works best across the GND & 3.3Vcc?
I have tried all three sizes that come with the arduino starter kit (100uf, 100nf & 100 pf)
As an interesting aside: The 100nf and the 100pf prevent the Arduino from communicating with the Serial Monitor at all

Craig

Hi Craig,

Sorry for the delay. I did get it working nicely. Honestly I don't really know why it started working, but my problem seemed to be due to a loose wire/bad connection. I used a 100 uF cap., but once everything was working, I removed the cap. and it was still working fine, so I don' t think it was that necessary.

I have a few more links that I started during my fight with the NRF. Here is a link to the final version of my project:
http://forum.arduino.cc/index.php?topic=216306.15

Also, here is a link to a youtube video of my project in action (it is 6:45 into the video): Building Flying Crashing RC Plane with Drop Box and Altimeter. - YouTube

Let me know if you get your project working, or if you need any help.

Dustin

i'm having the same problem....though i'm confused why a pipe address shown in the serial monitor is completely different from the one the code previously assigned

TwoChain please can you tell me some things? What camera did you used? Does the camera transmits through nrf24l01? And what setup settings did you do to the nrf modules? Range? Thank you and congrats for the project.

nimeni_altci ....could u help me with my problem if u'v any idea on it? i really need some help..

Hi All,

if you are having questions about this project, I have a significantly updated version of this work located here:

http://forum.arduino.cc/index.php?topic=216306.0

Hopefully this answers your question. If not, please let me know.

Thanks,

Dustin

hey dustin,

thanks a lot for the post man, it was really very helpful,cleared out a lot of my confusions as well, but unfortunately,i've come to face another problem for which i can't seem to figure out the solution. i actualy found this Serial chat code in the forum and it was exactly what i was looking for but one of my transcievers( or could be my arduino) doesn't act as a Receiver. i tried swapping the nrf24's and both nrf's work fine with one arduino but the other arduino doesn't seem to receiver the data. I tried checkin the 12th pin(MISO i guess) on the problematic arduino and the voltage doesn't seem to fluctuate in that pin while the data is sent from the other arduino. I don't know whether the problem is actually with the arduino because i tried hooking up an led to the 12 the pin and just tested it for simple led_blink sketch and it works just fine. Please do help me and the code for the serial chat is below

#include <LiquidCrystal.h>
#include <SPI.h>
#include "nRF24L01.h"
#include "RF24.h"
#include "printf.h"

//LiquidCrystal lcd(10, 7, 3, 4, 5, 6);

RF24 radio(9,10);

const uint64_t pipes[2] = { 0xDEDEDEDEE7LL, 0xDEDEDEDEE9LL };

boolean stringComplete = false;  // whether the string is complete
static int dataBufferIndex = 0;
boolean stringOverflow = false;
char charOverflow = 0;

char SendPayload[31] = "";
char RecvPayload[31] = "";
char serialBuffer[31] = "";

void setup(void) {
 
  Serial.begin(57600);
  /*lcd.begin(16,2);
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print("RF Chat V0.90");
*/
  printf_begin();
  radio.begin();
  
  radio.setDataRate(RF24_250KBPS);
  radio.setPALevel(RF24_PA_MAX);
  radio.setChannel(70);
  
  radio.enableDynamicPayloads();
  //radio.setPayloadSize(16);
  radio.setRetries(15,15);
  radio.setCRCLength(RF24_CRC_16);

  radio.openWritingPipe(pipes[0]);
  radio.openReadingPipe(1,pipes[1]);  
  
  radio.startListening();
  radio.printDetails();

  Serial.println();
  Serial.println("RF Chat V0.90");    
  delay(500);
  //lcd.clear();
}

void loop(void) {
  
  nRF_receive();
  serial_receive();
  
} // end loop()

void serialEvent() {
  while (Serial.available() > 0 ) {
      char incomingByte = Serial.read();
      
      if (stringOverflow) {
         serialBuffer[dataBufferIndex++] = charOverflow;  // Place saved overflow byte into buffer
         serialBuffer[dataBufferIndex++] = incomingByte;  // saved next byte into next buffer
         stringOverflow = false;                          // turn overflow flag off
      } else if (dataBufferIndex > 31) {
         stringComplete = true;        // Send this buffer out to radio
         stringOverflow = true;        // trigger the overflow flag
         charOverflow = incomingByte;  // Saved the overflow byte for next loop
         dataBufferIndex = 0;          // reset the bufferindex
         break; 
      } 
      else if(incomingByte=='\n'){
          serialBuffer[dataBufferIndex] = 0; 
          stringComplete = true;
      } else {
          serialBuffer[dataBufferIndex++] = incomingByte;
          serialBuffer[dataBufferIndex] = 0; 
      }          
  } // end while()
} // end serialEvent()

void nRF_receive(void) {
  int len = 0;
  if ( radio.available() ) {
      bool done = false;
      while ( !done ) {
        len = radio.getDynamicPayloadSize();
        //len = radio.getPayloadSize();
        done = radio.read(&RecvPayload,len);
        delay(5);
      }
  
    RecvPayload[len] = 0; // null terminate string
    
    /*lcd.setCursor(0,0);
    lcd.print("R:");
    Serial.print("R:");
    lcd.setCursor(2,0);
    lcd.print(RecvPayload);
    */
    Serial.print(RecvPayload);
    Serial.println();
    RecvPayload[0] = 0;  // Clear the buffers
  }  

} // end nRF_receive()

void serial_receive(void){
  
  if (stringComplete) { 
        strcat(SendPayload,serialBuffer);      
        // swap TX & Rx addr for writing
        radio.openWritingPipe(pipes[1]);
        radio.openReadingPipe(0,pipes[0]);  
        radio.stopListening();
        bool ok = radio.write(&SendPayload,strlen(SendPayload));
        
       // lcd.setCursor(0,1);
        //lcd.print("S:");
        Serial.print("S:");
       // lcd.setCursor(2,1);
        //lcd.print(SendPayload);
        Serial.print(SendPayload);          
        Serial.println();
        stringComplete = false;

        // restore TX & Rx addr for reading       
        radio.openWritingPipe(pipes[0]);
        radio.openReadingPipe(1,pipes[1]); 
        radio.startListening();  
        SendPayload[0] = 0;
        dataBufferIndex = 0;
  } // endif
} // end serial_receive()

Hi,

I encountered exactly the same problem so I solved it by following this solution, i think its quite helpful.

so have a look at it. The code is also given there along with circuit diagram.

Thanks.

Thanks to theenggprojects. I had the same issue. This is a power related issue. The chinese arduino knockoffs are not able to provide enough current and the chinese nrf24l01+ knockoffs draw more power then the original ones. I gave nrf module power through arduino 5v power supply instead of 3.3v power supply and it worked.