Communication problem with nRF24L01. Do not send "sent response"

Hi,

I installed the nRF24L01 modules. I use the library RF24, 2 modules nRF24L01 with base and 2 Uno R3. I started with the example of the library GetStarted. The instructions are on http://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-HowTo#lib and here is the code:

/*
* Getting Started example sketch for nRF24L01+ radios
* This is a very basic example of how to send data from one node to another
* Updated: Dec 2014 by TMRh20
*/

#include <SPI.h>
#include "RF24.h"

/****************** User Config ***************************/
/***      Set this radio as radio number 0 or 1         ***/
bool radioNumber = 1;

/* Hardware configuration: Set up nRF24L01 radio on SPI bus plus pins 7 & 8 */
RF24 radio(7,8);
/**********************************************************/

byte addresses[][6] = {"1Node","2Node"};

// Used to control whether this node is sending or receiving
bool role = 0;

void setup() {
  Serial.begin(115200);
  Serial.println(F("RF24/examples/GettingStarted"));
  Serial.println(F("*** PRESS 'T' to begin transmitting to the other node"));
  
  radio.begin();

  // Set the PA Level low to prevent power supply related issues since this is a
 // getting_started sketch, and the likelihood of close proximity of the devices. RF24_PA_MAX is default.
  radio.setPALevel(RF24_PA_LOW);
  
  // Open a writing and reading pipe on each radio, with opposite addresses
  if(radioNumber){
    radio.openWritingPipe(addresses[1]);
    radio.openReadingPipe(1,addresses[0]);
  }else{
    radio.openWritingPipe(addresses[0]);
    radio.openReadingPipe(1,addresses[1]);
  }
  
  // Start the radio listening for data
  radio.startListening();
}

void loop() {
  
  
/****************** Ping Out Role ***************************/  
if (role == 1)  {
    
    radio.stopListening();                                    // First, stop listening so we can talk.
    
    
    Serial.println(F("Now sending"));

    unsigned long start_time = micros();                             // Take the time, and send it.  This will block until complete
     if (!radio.write( &start_time, sizeof(unsigned long) )){
       Serial.println(F("failed"));
     }
        
    radio.startListening();                                    // Now, continue listening
    
    unsigned long started_waiting_at = micros();               // Set up a timeout period, get the current microseconds
    boolean timeout = false;                                   // Set up a variable to indicate if a response was received or not
    
    while ( ! radio.available() ){                             // While nothing is received
      if (micros() - started_waiting_at > 200000 ){            // If waited longer than 200ms, indicate timeout and exit while loop
          timeout = true;
          break;
      }      
    }
        
    if ( timeout ){                                             // Describe the results
        Serial.println(F("Failed, response timed out."));
    }else{
        unsigned long got_time;                                 // Grab the response, compare, and send to debugging spew
        radio.read( &got_time, sizeof(unsigned long) );
        unsigned long end_time = micros();
        
        // Spew it
        Serial.print(F("Sent "));
        Serial.print(start_time);
        Serial.print(F(", Got response "));
        Serial.print(got_time);
        Serial.print(F(", Round-trip delay "));
        Serial.print(end_time-start_time);
        Serial.println(F(" microseconds"));
    }

    // Try again 1s later
    delay(1000);
  }



/****************** Pong Back Role ***************************/

  if ( role == 0 )
  {
    unsigned long got_time;
    
    if( radio.available()){
                                                                    // Variable for the received timestamp
      while (radio.available()) {                                   // While there is data ready
        radio.read( &got_time, sizeof(unsigned long) );             // Get the payload
      }
     
      radio.stopListening();                                        // First, stop listening so we can talk   
      radio.write( &got_time, sizeof(unsigned long) );              // Send the final one back.      
      radio.startListening();                                       // Now, resume listening so we catch the next packets.     
      Serial.print(F("Sent response "));
      Serial.println(got_time);  
   }
 }




/****************** Change Roles via Serial Commands ***************************/

  if ( Serial.available() )
  {
    char c = toupper(Serial.read());
    if ( c == 'T' && role == 0 ){      
      Serial.println(F("*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK"));
      role = 1;                  // Become the primary transmitter (ping out)
    
   }else
    if ( c == 'R' && role == 1 ){
      Serial.println(F("*** CHANGING TO RECEIVE ROLE -- PRESS 'T' TO SWITCH BACK"));      
       role = 0;                // Become the primary receiver (pong back)
       radio.startListening();
       
    }
  }


} // Loop

I habe some communication problem. When card Nr 1 is set as transmitter and card Nr 0 as receiver
the card Nr 0 don’t send any response:
Card Nr1
F24/examples/GettingStarted
*** PRESS ‘T’ to begin transmitting to the other node
*** CHANGING TO TRANSMIT ROLE – PRESS ‘R’ TO SWITCH BACK
Now sending
failed
Failed, response timed out.
Now sending

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

When I switch (NR 1 as receiver, Nr 0 as transmitter), I get:
Card Nr1
*** CHANGING TO RECEIVE ROLE – PRESS ‘T’ TO SWITCH BACK
Sent response 8
Sent response 9472
Sent response 9472
Sent response 19202048

Card Nr0
RF24/examples/GettingStarted
*** PRESS ‘T’ to begin transmitting to the other node
*** CHANGING TO TRANSMIT ROLE – PRESS ‘R’ TO SWITCH BACK
Now sending
failed
Failed, response timed out.
Now sending

Any guess?

Pictures / detail on how things are wired and powered would help

The modules are wired this way:
Base Uno
GND GND *
VCC 3.3V *
CE 9
CSN 10
SCK 13
MOSI 11
MISO 12
IRQ 2

Hi,

I now get
Card 1
ow sending
Failed, response timed out.
Now sending
Sent 137212992, Got response 0, Round-trip delay 21628 microseconds
Now sending
Failed, response timed out.

Card Nr0
RF24/examples/GettingStarted
*** PRESS 'T' to begin transmitting to the other node

I habe a problem a wire for Card 1, but card 0 didn#t sent any response at all, which is weird as well.

Anyone? :slight_smile:

just for trying out change

      if (micros() - started_waiting_at > [color=red]200000[/color] ){            // If waited longer than 200ms, indicate timeout and exit while loop

into

      if (micros() - started_waiting_at > [color=green]1000000ul[/color] ){            // If waited longer than 1s, indicate timeout and exit while loop

see if you get a different result

also are you using a Socket Adapter Board For 8PIN NRF24L01

it offers a 3.3V regulator.

you might need otherwise a cap across pins 1 and 2 for a juice boost otherwise

This Simple nRF24L01+ Tutorial may be helpful.

...R

Hi,

@J-M-L: I use the base you showed. The problem of power supply can be set aside.

I changed the code, but I still get for both cards (alternatively):
RF24/examples/GettingStarted
*** PRESS 'T' to begin transmitting to the other node
*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK
Now sending
failed
Failed, response timed out.

did you use one of Robin’s example code?

medeslip:
I changed the code, but I still get for both cards (alternatively):
RF24/examples/GettingStarted
*** PRESS 'T' to begin transmitting to the other node
*** CHANGING TO TRANSMIT ROLE -- PRESS 'R' TO SWITCH BACK
Now sending
failed
Failed, response timed out.

I deliberately kept my examples simpler to avoid that sort of confusion.

...R

Hi,

I tried your tutorial. I think this is much simpliers indeed. I got data received on one hand and data sent on the other hand, but I wonder why I still get data received when I just plug one card in?

M.

Not sure I understand your question.. you might have a module with a poor antenna or GND insulation and with which your reception ability will vary - do you have more than 2 modules?

Hi,

I have two modules and the transmitter successgully sends messages to the receiver according to the simple script of the tutorial. Then I tested the error message. I just used the receiver module. It shouldn t receive any message because the transmitter is not used. But the serial tab shows message received! I think this is not possible. Why do I see this?

medeslip:
I have two modules and the transmitter successgully sends messages to the receiver according to the simple script of the tutorial. Then I tested the error message. I just used the receiver module. It shouldn t receive any message because the transmitter is not used. But the serial tab shows message received! I think this is not possible. Why do I see this?

Please post the exact programs that YOU uploaded to your Arduinos and post the output that you get when the transmitter Arduino is not powered up.

...R

Hi,

I uploaded this code:

// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
int ackData[2] = {109, -4000}; // the two values to be sent to the master
bool newData = false;

//==============

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRxAckPayload Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);

    radio.enableAckPayload();
    radio.writeAckPayload(1, &ackData, sizeof(ackData)); // pre-load data

    radio.startListening();
}

//==========

void loop() {
    getData();
    showData();
}

//============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        updateReplyData();
        newData = true;
    }
}

//================

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        Serial.print(" ackPayload sent ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.println(ackData[1]);
        newData = false;
    }
}

//================

void updateReplyData() {
    ackData[0] -= 1;
    ackData[1] -= 1;
    if (ackData[0] < 100) {
        ackData[0] = 109;
    }
    if (ackData[1] < -4009) {
        ackData[1] = -4000;
    }
    radio.writeAckPayload(0, &ackData, sizeof(ackData)); // load the payload for the next time
}

And I received this:
þSimpleRx Starting
Data received
Data received

An now the tricky part: without plugging in the master card. One card-> data received :slight_smile:

Hi,

I also have communication problems with two cards.
Here the code on the transmitter:

// SimpleTxAckPayload - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>


#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';
int ackData[2] = {-1, -1}; // to hold the two values coming from the slave
bool newData = false;

unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second

//===============

void setup() {

    Serial.begin(9600);
    Serial.println(F("Source File /mnt/sdb1/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/SimpleTxAckPayload.ino"));
    Serial.println("SimpleTxAckPayload Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );

    radio.enableAckPayload();

    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//=============

void loop() {

    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
    }
    showData();
}

//================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        if ( radio.isAckPayloadAvailable() ) {
            radio.read(&ackData, sizeof(ackData));
            newData = true;
        }
        else {
            Serial.println("  Acknowledge but no data ");
        }
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }

    prevMillis = millis();
 }


//=================

void showData() {
    if (newData == true) {
        Serial.print("  Acknowledge data ");
        Serial.print(ackData[0]);
        Serial.print(", ");
        Serial.println(ackData[1]);
        Serial.println();
        newData = false;
    }
}

//================

void updateMessage() {
        // so you can see that ew data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

And I get:
Source File /mnt/sdb1/SGT-Prog/Arduino/ForumDemos/nRF24Tutorial/SimpleTxAckPayload.ino
SimpleTxAckPayload Starting

It works fine until the loop actually.
Actually I must upload the code to be able to open the Serial tab. If the card was flashed earlier and I open the IDE, I can’t open the serial tab.

The code of the receiver is:

// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

And I get:
`åSimpleRx Starting
Data received

My understanding is that the radio link works, but no date is sent. What could it be?

Referring to Reply #15....
My tutorial examples are designed to work in pairs. So SimpleTxAckPayload should be tried only with SimpleRxAckPayload.

Referring to Reply #14...
If you are getting the response you say with only one nRF24 powered up I strongly suspect there is something wrong either your connections or (more likely) with the nRF24 itself.

When I tried your code on my Uno it printed "SimpleRxAckPayload Starting" and nothing else - which is the expected behaviour.

Do you get the same result when you try that code with your other nRF24?

...R

Hi,

#15 was a bad copy paste. The codes matches with each other.

For the transmiter I used:

// SimpleTx - the master or the transmitter

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>


#define CE_PIN   9
#define CSN_PIN 10

const byte slaveAddress[5] = {'R','x','A','A','A'};


RF24 radio(CE_PIN, CSN_PIN); // Create a Radio

char dataToSend[10] = "Message 0";
char txNum = '0';


unsigned long currentMillis;
unsigned long prevMillis;
unsigned long txIntervalMillis = 1000; // send once per second


void setup() {

    Serial.begin(9600);

    Serial.println("SimpleTx Starting");

    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.setRetries(3,5); // delay, count
    radio.openWritingPipe(slaveAddress);
}

//====================

void loop() {
    currentMillis = millis();
    if (currentMillis - prevMillis >= txIntervalMillis) {
        send();
        prevMillis = millis();
    }
}

//====================

void send() {

    bool rslt;
    rslt = radio.write( &dataToSend, sizeof(dataToSend) );
        // Always use sizeof() as it gives the size as the number of bytes.
        // For example if dataToSend was an int sizeof() would correctly return 2

    Serial.print("Data Sent ");
    Serial.print(dataToSend);
    if (rslt) {
        Serial.println("  Acknowledge received");
        updateMessage();
    }
    else {
        Serial.println("  Tx failed");
    }
}

//================

void updateMessage() {
        // so you can see that new data is being sent
    txNum += 1;
    if (txNum > '9') {
        txNum = '0';
    }
    dataToSend[8] = txNum;
}

and I get:
SimpleTx Starting

For the receiver I used:

// SimpleRx - the slave or the receiver

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>

#define CE_PIN   9
#define CSN_PIN 10

const byte thisSlaveAddress[5] = {'R','x','A','A','A'};

RF24 radio(CE_PIN, CSN_PIN);

char dataReceived[10]; // this must match dataToSend in the TX
bool newData = false;

//===========

void setup() {

    Serial.begin(9600);

    Serial.println("SimpleRx Starting");
    radio.begin();
    radio.setDataRate( RF24_250KBPS );
    radio.openReadingPipe(1, thisSlaveAddress);
    radio.startListening();
}

//=============

void loop() {
    getData();
    showData();
}

//==============

void getData() {
    if ( radio.available() ) {
        radio.read( &dataReceived, sizeof(dataReceived) );
        newData = true;
    }
}

void showData() {
    if (newData == true) {
        Serial.print("Data received ");
        Serial.println(dataReceived);
        newData = false;
    }
}

And I get
0SimpleRx Starting
Data received
Data received
Data received

If I take the NRF24L01 off the module base, I get:
SimpleTx Starting
Data Sent Message 0 Acknowledge received
Data Sent Message 1 Acknowledge received
Data Sent Message 2 Acknowledge received

How can I test the connection? Why is there any message sent by the transmitter?

Hi,

I did this tutorial:
https://arduino-info.wikispaces.com/Nrf24L01-2.4GHz-ExampleSketches#js1

I applied this wiring:
1 - GND
2 - VCC 3.3V !!! NOT 5V
3 - CE to Arduino pin 7
4 - CSN to Arduino pin 8
5 - SCK to Arduino pin 13
6 - MOSI to Arduino pin 11
7 - MISO to Arduino pin 12

For the code, see the tuto.

I get :
YourDuino.com Example: Send joystick data by nRF24L01 radio to another Arduino
Now sending - Response timed out - no Acknowledge

and
and YourDuino.com Example: Receive joystick data by nRF24L01 radio from another Arduino
and control servos if attached (Check 'hasHardware' variable

But it works when I take out and back in the wire MISO:
first card:
Now sending - Sent 337664560, Got response 2048, Round-trip delay 337662512 microseconds

second card:
Packet Received - Sent response 0uS X= 0 Y= 0 Switch OFF

When the wire is set, it doesn#t work, when it is not, it works for some seconds. Why?

Can you please post the problem code here.