nRF24L01 won't transmit, printDetails output looks ok

HI,

I have looked over many of the nRF24L01 threads and haven’t been able to suss out what my issue is. I have spent the last 2 weeks trying to get it to work using the ping pair example code but am getting a transmit failed message in the Serial Monitor.

Some of the things I have tried are: bought a second pair of transceivers and switched them out, tried 3 different unos bought from 2 different sources, replaced all of the jumper wires with brand new ones and I get the same results each time using the unmodified pingpair sketch.

Here is the serial monitor output from the TX unit:

RF24/examples/pingpair/

ROLE: Ping out

STATUS		 = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1	 = 0xf0f0f0f0e1 0xf0f0f0f0d2
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR		 = 0xf0f0f0f0e1
RX_PW_P0-6	 = 0x08 0x08 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_MAX

Now sending 87...failed.
Failed, response timed out.
Now sending 1351...failed.
Failed, response timed out.
Now sending 2614...failed.
Failed, response timed out.
Now sending 3875...failed.
Failed, response timed out.

Output from the RX unit

RF24/examples/pingpair/
ROLE: Pong back

STATUS		 = 0x0e RX_DR=0 TX_DS=0 MAX_RT=0 RX_P_NO=7 TX_FULL=0
RX_ADDR_P0-1	 = 0xf0f0f0f0e1 0xf0f0f0f0d2
RX_ADDR_P2-5     = 0xc3 0xc4 0xc5 0xc6
TX_ADDR		 = 0xf0f0f0f0d2
RX_PW_P0-6	 = 0x08 0x08 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_MAX

I believe it is connected correctly or it wouldn’t initialize? But for the record:
Vcc → 3.3 with a smoothing cap, (also tested without the cap).
Gnd–>Gnd
CE–> 9
CSN–>10
MOSI–>11
MISO–>12
SCK–>13

Here is a copy of the code running on both boards even though it is the standard pingpair 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 RF Radio Ping Pair
 *
 * This is an example of how to use the RF24 class.  Write this sketch to two different nodes,
 * connect the role_pin to ground on one.  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);

// sets the role of this unit in hardware.  Connect to GND to be the 'pong' receiver
// Leave open to be the 'ping' transmitter
const int role_pin = 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 hardware itself specifies
// which node it is.
//
// This is done through the role_pin
//

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

void setup(void)
{
  //
  // Role
  //

  // set up the role pin
  pinMode(role_pin, INPUT);
  digitalWrite(role_pin,HIGH);
  delay(20); // Just to get a solid reading on the role pin

  // read the address pin, establish our role
  if ( ! digitalRead(role_pin) )
    role = role_ping_out;
  else
    role = role_pong_back;

  //
  // Print preamble
  //

  Serial.begin(57600);
  printf_begin();
  printf("\n\rRF24/examples/pingpair/\n\r");
  printf("ROLE: %s\n\r",role_friendly_name[role]);

  //
  // 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();
    }
  }
}
// vim:cin:ai:sts=2 sw=2 ft=cpp

Any ideas or suggestion appreciated. I am a newb to arduino as I just started at the end of Feb though I do have a weather station home base running with humidity, temp, baro pressure, and a lightning detector chip running and a remote with a DHT22 humidity and temp sensor. In fact the 2.4 Ghz radio is to connect the remote with the base units for this weather station project. I guess I should also mention that I have a DHT22 temp/humid sensor plugged into the TX board though it obviously isn’t being initialized or read in this sketch. I have tried unplugging it from the board as well just in case it was eating power in a significant way (though it is on the 5v rail).

The output you are getting shows that the connections between the arduino and the nrf24l01 are working ok. The ..failed shows that you are not receiving an ack back for your transmission so I believe the subject of your message is not correct .. you are transmitting but it is either not being received or you are not hearing the response. Have you tried using a different channel? Maybe there is something close to your units that is interfering with channel 4C. You have 125 to try so plenty of choice. You could run the scanning sketch to see what the interference levels look like across all channels.

Thanks Crofter! changed the channel to 5C and got it working :)

egil222: I had the same problem and ended up fixing it by connecting a 33 uF cap between 3.3V and GND on the arduino. Just make sure everything is unplugged when connecting the capacitor as to not blow out any components.

Hello,

// sets the role of this unit in hardware.  Connect to GND to be the 'pong' receiver
// Leave open to be the 'ping' transmitter
const int role_pin = 7;

Does it mean to connect the digital pin 7 of arduino to the GND pin??? If is it so, then...

// set up the role pin
  pinMode(role_pin, INPUT);
  digitalWrite(role_pin,HIGH);
  delay(20); // Just to get a solid reading on the role pin

Won't it make a short circuit when the role pin is HIGH? (as it is already connected to the GND in the receiver end) Kindly clarify.

No, the pin is set to input so this just turns on an internal pull up resistor.

Another way to do it is: pinMode(pin, INPUT_PULLUP);

If you set the pin to input without the pullup the pin is very high impedance and give you random values from local electrical fields. You should actually try it, just set a pin for input and print the results in loop(). Put a short wire in that pin and wave your hands around and see what happens.

Thank you for the clarification. the short wire tweak in amazing. Need to know a few more things.

In the ping pair example the pipe address is

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

2 different addresses. BUT in some other example the transmitter & receiver address is SAME. http://forum.arduino.cc/index.php?topic=233387.msg1680856#msg1680856 Receiver:

RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

Transmitter:

RF24 radio(9,10);
const uint64_t pipe = 0xE8E8F0F0E1LL;

I found it little bit confusing. In this wiki page, they used same address for each pipeline (each pair of address is same) http://www.elecfreaks.com/wiki/index.php?title=2.4G_Wireless_nRF24L01p#Usage

Any clue?

If there is only 1 address in the transmitter and the receiver you can only have one way communication between the systems. The address will be the TX address at the transmitter and the RX address given to one of the pipes in the receiver. The nRF24L01 will only receive data from a transmitter that matches one of the 6 addresses given to its receive pipes. The term pipe is very confusing as they are only one way pipes apart from sending auto-acknowledgements.
If you want two way communication each unit needs its own tx address which is given to a receive pipe in the other unit.

Thanks crofter for your answer. Now I understand that why the address are so. One more thing, the nRF modules have 126 channels & each channel can communicate with 6 different TX addresses. So, can we connect 126 x 6 number of devices with each nRF module??? Is it practically correct?

nightcrawler218: So, can we connect 126 x 6 number of devices with each nRF module??? Is it practically correct?

Each nRf24L01 will listen for 6 specified transmitters on 1 frequency at any instance in time. You should consider the number of channels available as a method to operate multiple "nets" (of 1 RX + 6 TX) in the same area without affecting each other. If you want a 1 to n system where n > 6 you need to cascade nets using software such as RF24Network.

Thank you crofter for the overview. :)