nRF24 / RF24

OSI Layer 2 driver for nRF24L01 on Arduino & Raspberry Pi/Linux Devices
https://nrf24.github.io/RF24
GNU General Public License v2.0
2.21k stars 1.02k forks source link

Transmission stops after X seconds/transmissions #429

Closed ran2me closed 4 years ago

ran2me commented 6 years ago

Hi I searched all over for a solution for this and tried many setups. I have two nano's, two nrf24l01+ and two socket adapters. My set up is two nano's connected to a PC, the power for socket adapters and nrf24l01+ is coming from 5v power bank (5v to 3.3v is on the socket adapter)

In all setups, codes and libraries, all works OK for a while, and then the receiver gets nothing, until resetting transmitter board. it can work for 10 seconds or 5 minutes. but it stops.

I tried:

  1. Switching nrf modules
  2. Many rf24 libraries (maniacbug, nRF24, TMRh20, gcopeland)
  3. Ping code, message code, servo operating code, in liberality examples, all works for few seconds.
  4. Changing delay or adding millis()
  5. Debugging with serial messages

HELP :-)

Avamander commented 6 years ago

Picture of your setup would be really appreciated.

ran2me commented 6 years ago

I can only add that later today since I'm not at home. But in general, it is two nano's on a breadboard with wire connectors to the nrf modules, modules connected to legs 2,3 ce csn and 11 12 13 for mo mi and sck.

ran2me commented 6 years ago

Hello again I use the standard rf24 (nrf24\rf24) library, with minor changes (ce and csn leg numbers changed to 2,3)

untitled

wmarkow commented 6 years ago

Maybe there is something in your source code? Could you post your code for transmitter and receiver?

ran2me commented 6 years ago

Thanks, I'm using the example from the library:

/*
* 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 = 0;

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

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
TMRh20 commented 6 years ago

What are you powering it with? Maybe try adding some large-ish capacitors to the power rail.

On Apr 26, 2018, at 08:12, ran2me notifications@github.com wrote:

Thanks, I'm using the example from the library: `/*

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

include "RF24.h"

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

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

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 `

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub, or mute the thread.

ran2me commented 6 years ago

Powered with a power bank, it is now working, but for how long :-( I now wait for it to stop, and if it does not, it may be related to the servo code or data being sent...

I'm now running this One gets radioNumber = 0 and the other gets 1

/*
* 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 = 0;

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

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

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

untitled

UPDATE!

Now it stopped!

untitled1

ran2me commented 6 years ago

Anyone?.. :-(

wmarkow commented 5 years ago

Do I see correctly that the receiver constantly sents the response and the transmitter shows that it has failed? In general the round trip is around 1800us but the last entry shows 57804us.

It looks like the transmitter doesn't want go into listening mode after transmitting each packet.

 if (!radio.write( &start_time, sizeof(unsigned long) )){
   Serial.println(F("failed"));
 }

radio.startListening();                                    // Now, continue listening

It seems to sending data correctly (because there is no failed message in the serial console). Also the receiver seems to send its response back. Or the receiver receives the packet correctly, prints that it sends response back, but it never sends it back.

ran2me commented 5 years ago

Wow That was over a year ago, I really don’t remembre..

wmarkow commented 5 years ago

Eh, sorry - I thought that your last comment was in May 2019 - but obviously it was a year before.