0

For my home-automation project I'm using several arduino nano's with each a NRF24L01+ module. Each module is able to both receive and transmit with one another. Everything seemed to be flawless for a couple of hours, but after a couple of hours it either stops transmission (completely frozen) of receives the last data repeatedly. In my design I'm using the RF24 and RF24Network libraries, I was wondering whether someone managed to automatically reset the NRF24L01 module using code, when one of these errors occured, and could share his/her code?

I already found this form, but this is only using the standard RF24 library, whereas I'm also using the RF24Network library. Furthermore, in this form it is having a seperate TX and RX side, whereas I like to have each module to be able to both send and receive.

Some extra side information, I use a stable power supply with a capacitor connected to the module, also the wires are soldered to the module.

I hope somebody can help me with this,

Guido

  • Are you sure the problem isn't on the Nano? It might be better to reset the Nano. Resetting the Nano would also reinitialize the NRF24. – Gerben Jun 16 at 13:23
  • @Gerben It is a known problem, and is especially prevalent with Chinese clones. One make even has the entire ACK bit inverted ... such quality... – Majenko Jun 16 at 15:22
2

This is a known problem with those chips (especially Chinese clones). It is caused when a chip gets stuck in TX mode waiting for an ACK that never arrives back.

The chips don't have a "reset", but switching them into low power mode and then back on again, which doesn't affect any register settings, aborts the current TX operation.

RF24Network is merely a protocol layer on top of the RF24 library. That RF24 library has powerDown() and powerUp() methods. Simply call powerDown followed by powerUp on your RF24 driver object.

  • I have tried your suggestion. However, I didn't get it to work. I indeed use these so called Chinese clones. I gave an explanation of my code used in next answer. I hope you could give me some useful advise on improving it. – Guido Jun 18 at 13:45
0

@Majenko thank you for your suggestion, I have been playing around a little bit with the powerDown() and powerUp() functions but unfortunately I haven't got it to work yet. Again, it seemed to work for a couple of hours and then again seem to get stuck. Therefore, I also included my code to see if I maybe made some major mistakes. Furthermore, I assume that I'm having such Chinese clones of the NRF24L01+, as I have bought mine on Aliexpress.

I have included several parts of my code, the following part resets the NRF24L01+ module once a failure is detected. In here I also included the suggested powerDown and powerUp functions.

void NetworkReconnect()
{
  pinMode(CE_PIN, OUTPUT); digitalWrite(CE_PIN, HIGH);
  pinMode(CS_PIN, OUTPUT); digitalWrite(CS_PIN, HIGH);

  radio.powerDown();

  radio.begin();

  radio.powerDown();

  Network.begin(90, thisNode);

  delay(100);

  radio.setPALevel(RF24_PA_MAX);
  radio.setDataRate(RF24_1MBPS);

  radio.powerUp();
}

The following code I have in my void.loop(), every 5 seconds I check the network connection, by calling NetworkCheckConnection() (see last part of included code). Which tries to figure out whether the module has crashed, I found this failure detection as a suggestion at a discussion form on the RF24 library on GitHub Discussion. Furthermore, the while loop is limited to only 500ms to avoid being in an infinite loop, if this is exceed, the function NetworkReconnect() is called again.

void loop() 
{

  Network.update();

  if (millis() - Timer > 5000)
  {
    NetworkCheckConnection();
    Timer = millis();
  }

  if(radio.failureDetected){
    radio.failureDetected = false;
    delay(250);
    Serial.println("Radio failure detected, restarting radio");
    NetworkReconnect();        
  }

  if (Network.available())
  {
    uint32_t failTimer = millis();
    while (Network.available())
    {
      if(millis() - failTimer > 500)
      {
        radio.failureDetected = true;
        Serial.println("Radio available failure detected");
        break;
      }

      ... The usual Network.read stuff ...

    }   
  }

  ... Remainder of code ...

}

And lastly the NetworkCheckConnection() code, this code is based on the RF24 Failure handling example and the principles used for checking connectivity of the RF24Mesh network link (see line 140).

void NetworkCheckConnection()
{
  if (radio.getDataRate() != RF24_1MBPS)
  {
    radio.failureDetected = true;
    Serial.println("CheckConnection FailureDetected");
    return;
  }
  // see line 140 of: https://github.com/nRF24/RF24Mesh/blob/master/RF24Mesh.cpp
  bool ok = 0;
  if(radio.rxFifoFull() || (Network.networkFlags & 1))
  {
    return;
  }
  RF24NetworkHeader header(otherNode, NETWORK_PING);
  ok = Network.write(header,0,0);
  if(ok) { Serial.println("Network Connected");       return;}
  if(!ok){ radio.stopListening(); NetworkReconnect(); return;}
}

Lastly, I also call the NetworkReconnect() function if any of my Network.write functions fails.

I hope that you can give me some suggestions on how to get this module to work more reliable, any suggestion is welcome!

Thanks in advance :)

  • If you encounter a radio failure, what do you get as the output of printDetails()? – Avamander Aug 23 at 4:04

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.