NRF24L01 failsafe function

Hello friends,

I am working on a project for control a hydraulic lifting platform. I am using Arduino mega with 2 joysticks to control 10 solenoids proportionally. I want to use two pairs of joysticks - first one will be wired directly to the arduino and the second one will be wireless connected with nrf2401. I managed to run the controller and everythihg works fine, but I have one little problem - when the radio connection fail the analog read value remains the last readed from the controller and when I restart the receiver without powering the transmitter, all values are 0, which sets half of the movements at maximum. I need some code for failsafe function - when radio fails to terminate the program or set all analog read values to 512, which is the center of the joysticks. My code is very long, but I can post it if needed. I was thinking about using two different arduinos - one for the wired joysticks and one for the wireless joysticks, however I need failsafe on the receiver.

Can someone help me with this problem?
Thank you!

How do you know the transmission fails ?

do you have some sort of heartbeat ?

It likely depend on the code You didn't post but can also depend on the schematics.

1 Like

Here is the code for the transmitter

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

RF24 radio(9, 10); // CE, CSN
const byte address[6] = "00001";

char xy1Data[32] = "";
String averageX1t, averageY1t;

char xy2Data[32] = "";
String averageX2t, averageY2t;

char xy3Data[32] = "";
String averageX3t, averageY3t;

const int numReadingsX1 = 5;

int readingsX1[numReadingsX1];  
int readIndexX1 = 0;          
int totalX1 = 0;              
            



int x1Axis = A0;

const int numReadingsY1 = 5;



int readingsY1[numReadingsY1];  
int readIndexY1 = 0;          
int totalY1 = 0;             
  

int y1Axis = A1;



const int numReadingsX2 = 5;

int readingsX2[numReadingsX2];  
int readIndexX2 = 0;          
int totalX2 = 0;              

int x2Axis = A2;


const int numReadingsY2 = 5;

int readingsY2[numReadingsY2];  
int readIndexY2 = 0;         
int totalY2 = 0;             

int y2Axis = A3;

const int numReadingsX3 = 5;

int readingsX3[numReadingsX3];  
int readIndexX3 = 0;         
int totalX3 = 0;           

int x3Axis = A4;

const int numReadingsY3 = 5;

int readingsY3[numReadingsY3]; 
int readIndexY3 = 0;          
int totalY3 = 0;              

int y3Axis = A5;




void setup() {


  Serial.begin(9600);
  radio.begin();
  radio.openWritingPipe(address);
  radio.setRetries(15, 15);
  radio.setPALevel(RF24_PA_MIN);
  radio.stopListening();


   for (int thisReadingX1 = 0; thisReadingX1 < numReadingsX1; thisReadingX1++) {
    readingsX1[thisReadingX1] = 0;
  
  }

for (int thisReadingY1 = 0; thisReadingY1 < numReadingsY1; thisReadingY1++) {
    readingsY1[thisReadingY1] = 0;
  }

  for (int thisReadingX2 = 0; thisReadingX2 < numReadingsX2; thisReadingX2++) {
    readingsX2[thisReadingX2] = 0;
  
  }

for (int thisReadingY2 = 0; thisReadingY2 < numReadingsY2; thisReadingY2++) {
    readingsY2[thisReadingY2] = 0;

}

for (int thisReadingX3 = 0; thisReadingX3 < numReadingsX3; thisReadingX3++) {
    readingsX3[thisReadingX3] = 0;
  
  }

for (int thisReadingY3 = 0; thisReadingY3 < numReadingsY3; thisReadingY3++) {
    readingsY3[thisReadingY3] = 0;

}

}

void loop() {

  totalX1 = totalX1 - readingsX1[readIndexX1];
  readingsX1[readIndexX1] = analogRead(x1Axis);
  totalX1 = totalX1 + readingsX1[readIndexX1];
  readIndexX1 = readIndexX1 + 1;


  if (readIndexX1 >= numReadingsX1) {
    readIndexX1 = 0;
  }


  averageX1t = totalX1 / numReadingsX1;

  delay(10);  



  totalY1 = totalY1 - readingsY1[readIndexY1];
  readingsY1[readIndexY1] = analogRead(y1Axis);
  totalY1 = totalY1 + readingsY1[readIndexY1];
  readIndexY1 = readIndexY1 + 1;

  if (readIndexY1 >= numReadingsY1) {
    readIndexY1 = 0;
  }

  averageY1t = totalY1 / numReadingsY1;
  delay(10); 


   totalX2 = totalX2 - readingsX2[readIndexX2];
  readingsX2[readIndexX2] = analogRead(x2Axis);
  totalX2 = totalX2 + readingsX2[readIndexX2];
  readIndexX2 = readIndexX2 + 1;

  if (readIndexX2 >= numReadingsX2) {
    readIndexX2 = 0;
  }

  averageX2t = totalX2 / numReadingsX2;
  delay(10);  // delay in between reads for stability

  

totalY2 = totalY2 - readingsY2[readIndexY2];
  readingsY2[readIndexY2] = analogRead(y2Axis);
  totalY2 = totalY2 + readingsY2[readIndexY2];
  readIndexY2 = readIndexY2 + 1;

  if (readIndexY2 >= numReadingsY2) {
    readIndexY2 = 0;
  }


  averageY2t = totalY2 / numReadingsY2;
  delay(10); 

 totalX3 = totalX3 - readingsX3[readIndexX3];
  readingsX3[readIndexX3] = analogRead(x3Axis);
  totalX3 = totalX3 + readingsX3[readIndexX3];
  readIndexX3 = readIndexX3 + 1;

  if (readIndexX3 >= numReadingsX3) {
    readIndexX3 = 0;
  }

  averageX3t = totalX3 / numReadingsX3;
  delay(10);  // delay in between reads for stability

  
totalY3 = totalY3 - readingsY3[readIndexY3];
  readingsY3[readIndexY3] = analogRead(y3Axis);
  totalY3 = totalY3 + readingsY3[readIndexY3];
  readIndexY3 = readIndexY3 + 1;

  if (readIndexY3 >= numReadingsY3) {
    readIndexY3 = 0;
  }

  averageY3t = totalY3 / numReadingsY3;
  delay(10);  
  

  Serial.print("X1-T: ");
  Serial.print(averageX1t);
  Serial.print("   | Y1-T: ");
  Serial.print(averageY1t);
  Serial.print("   | X2-T: ");
  Serial.print(averageX2t);
  Serial.print("   | Y2-T: ");
  Serial.print(averageY2t);
  Serial.print("   | X3-T: ");
  Serial.print(averageX3t);
  Serial.print("   | Y3-T: ");
  Serial.println(averageY3t);



  averageX1t.toCharArray(xy1Data, 5); 
  radio.write(&xy1Data, sizeof(xy1Data)); 

  averageY1t.toCharArray(xy1Data, 5);
  radio.write(&xy1Data, sizeof(xy1Data));
  delay(10);


  averageX2t.toCharArray(xy2Data, 5); 
  radio.write(&xy2Data, sizeof(xy2Data)); 

  averageY2t.toCharArray(xy2Data, 5);
  radio.write(&xy2Data, sizeof(xy2Data));
  delay(10);


  averageX3t.toCharArray(xy3Data, 5); // Put the String (X Value) into a character array
  radio.write(&xy3Data, sizeof(xy3Data)); // Send the array data (X value) to the other NRF24L01 modile
  
  averageY3t.toCharArray(xy3Data, 5);
  radio.write(&xy3Data, sizeof(xy3Data));
  delay(10);
 
}

and here is the code for the receiver

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

#define enA1 13

#define in11 22

#define in21 23

#define enB1 12

#define in31 24

#define in41 25



#define enA2 11

#define in12 26

#define in22 27

#define enB2 7

#define in32 28

#define in42 29



#define enA3 6

#define in13 30

#define in23 31

#define enB3 8

#define in33 32

#define in43 33




RF24 radio(9, 10); 
const byte address[6] = "00001";


char receivedData[32] = "";
int averageX1t, averageY1t, averageX2t, averageY2t, averageX3t, averageY3t;



int motorSpeedA = 0;

int motorSpeedB = 0;

int motorSpeedC = 0;

int motorSpeedD = 0;

int motorSpeedE = 0;

int motorSpeedF = 0;





void setup() {

  pinMode(enA1, OUTPUT);

  pinMode(enB1, OUTPUT);

  pinMode(in11, OUTPUT);

  pinMode(in21, OUTPUT);

  pinMode(in31, OUTPUT);

  pinMode(in41, OUTPUT);



  pinMode(enA2, OUTPUT);

  pinMode(enB2, OUTPUT);

  pinMode(in12, OUTPUT);

  pinMode(in22, OUTPUT);

  pinMode(in32, OUTPUT);

  pinMode(in42, OUTPUT);


  pinMode(enA3, OUTPUT);

  pinMode(enB3, OUTPUT);

  pinMode(in13, OUTPUT);

  pinMode(in23, OUTPUT);

  pinMode(in33, OUTPUT);

  pinMode(in43, OUTPUT);


  Serial.begin(9600);
  radio.begin();
  radio.openReadingPipe(0, address);
  radio.setRetries(15, 15);
  radio.setPALevel(RF24_PA_MIN);
  radio.startListening();


}


void loop() {



  if (radio.available()) {                            
    radio.read(&receivedData, sizeof(receivedData));  
    averageX1t = atoi(&receivedData[0]);              
    delay(10);
    radio.read(&receivedData, sizeof(receivedData));
    averageY1t = atoi(&receivedData[0]);
    delay(10);

    radio.read(&receivedData, sizeof(receivedData));  
    averageX2t = atoi(&receivedData[0]);              
    delay(1);
    radio.read(&receivedData, sizeof(receivedData));
    averageY2t = atoi(&receivedData[0]);
    delay(10);

    radio.read(&receivedData, sizeof(receivedData));  
    averageX3t = atoi(&receivedData[0]);              
    delay(1);
    radio.read(&receivedData, sizeof(receivedData));
    averageY3t = atoi(&receivedData[0]);
    delay(10);


  }
 
  


  Serial.print("X1: ");
  Serial.print(averageX1t);
  Serial.print("   | Y1: ");
  Serial.print(averageY1t);
  Serial.print("   | X2: ");
  Serial.print(averageX2t);
  Serial.print("   | Y2: ");
  Serial.print(averageY2t);
  Serial.print("   | X3: ");
  Serial.print(averageX3t);
  Serial.print("   | Y3: ");
  Serial.println(averageY3t);



  
 if (averageX1t < 400) {

    


    digitalWrite(in11, HIGH);

    digitalWrite(in21, LOW);

    
    

    motorSpeedA = map(averageX1t, 400, 0, 0, 100);


  }


  else if (averageX1t > 600) {


    digitalWrite(in11, LOW);

    digitalWrite(in21, HIGH);

  motorSpeedA = map(averageX1t, 600, 1023, 0, 100);

 
  
   
  }

 
 
  else {
    motorSpeedA = 0;
  }

  analogWrite(enA1, motorSpeedA);  // Send PWM signal to motor A


  
  if (averageY1t < 400) {

 

    digitalWrite(in31, HIGH);

    digitalWrite(in41, LOW);


    motorSpeedB = map(averageY1t, 400, 1, 0, 100);


  }

  else if (averageY1t > 600) {


    digitalWrite(in31, LOW);

    digitalWrite(in41, HIGH);



    motorSpeedB = map(averageY1t, 600, 1023, 0, 100);

  }



  else {
    motorSpeedB = 0;
  }

  analogWrite(enB1, motorSpeedB);  // Send PWM signal to motor A


  if (averageX2t < 400) {



    digitalWrite(in12, HIGH);

    digitalWrite(in22, LOW);


    motorSpeedC = map(averageX2t, 400, 1, 0, 100);


  }

  else if (averageX2t > 600) {

  

    digitalWrite(in12, LOW);

    digitalWrite(in22, HIGH);


    motorSpeedC = map(averageX2t, 600, 1023, 0, 100);

  }


  else {
    motorSpeedC = 0;
  }

  analogWrite(enA2, motorSpeedC);  // Send PWM signal to motor A


  if (averageY2t < 400) {



    digitalWrite(in32, HIGH);

    digitalWrite(in42, LOW);


    motorSpeedD = map(averageY2t, 400, 1, 0, 100);


  }

  else if (averageY2t > 600) {


    digitalWrite(in32, LOW);

    digitalWrite(in42, HIGH);



    motorSpeedD = map(averageY2t, 600, 1023, 0, 100);

  }


  else {
    motorSpeedD = 0;
  }

  analogWrite(enB2, motorSpeedD);  // Send PWM signal to motor A



  if (averageX3t < 400) {



    digitalWrite(in13, HIGH);

    digitalWrite(in23, LOW);


    motorSpeedE = map(averageX3t, 400, 0, 0, 100);


  }

  else if (averageX3t > 600) {


    digitalWrite(in13, LOW);

    digitalWrite(in23, HIGH);


    motorSpeedE = map(averageX3t, 600, 1023, 0, 100);

  }


  else {
    motorSpeedE = 0;
  }

  analogWrite(enA3, motorSpeedE);  // Send PWM signal to motor A


  if (averageY3t < 400) {


    digitalWrite(in33, HIGH);

    digitalWrite(in43, LOW);


    motorSpeedF = map(averageY3t, 400, 0, 0, 100);


  }

  else if (averageY3t > 600) {

    // Set Motor A forward

    digitalWrite(in33, LOW);

    digitalWrite(in43, HIGH);


    motorSpeedF = map(averageY3t, 600, 1023, 0, 100);

  }



  else {
    motorSpeedF = 0;
  }

  analogWrite(enB3, motorSpeedF);  // Send PWM signal to motor A


}

I use a code for smooth readings from the joysticks in the transmitter part, and a code for controlling the 12 volt solenoids proportionally with three L298N drivers. I have to control 12 solenoids with two 3-axis joysticks. I just want to program the receiver when it loses signal from the transmitter, to set all analog read values to 512, which is the center of joysticks. Is this possible?

Thank you!

Thanks. Checking Your post again..

nothing will be received in the receiver if there's no connection.

Posting schematics showing especially the powering of both the transmitter side and the receiver side would be nice to see.

1 Like

Except for the program starting, you need to include a time-out function that detects when nothing has been received for that time period. What will you do after there is a timeout? Will you have to reset the receiving Arduino?

1 Like

The power of the receiver will be from the 12V battery of the truck through a dc-dc converter set to 5V. The transmitter will be powered with battery maybe. I want to be sure that if there is a problem with the radio connection - for example low battery, fault in the nrf module or the controller to set safe values of the analog readings, which are 512 - the center of the joysticks, or to shut down the program.

As I said, I want if the radio connection fails to put safe joystick values, in my case the center of the joysticks is 512, or to shut down the program or controller. Can you give me some example of code - how can I check the radio connection periodically and if there is no answer from the transmitter to put these safe values in the receiver?

Thank you all for the attention!

You writewill be several times. Do You have a set up and ongoing tries that fail? Please supply datasheet links to things like dc - dc converter.

Examples? No examples. But I wrote that you must include a time the code is waiting for a message with no message in that time period. That is the ONLY indication you will ever get that there is no message being received!

Me again ….

Is this a real platform ? If so you probably can’t do this as the fail safety implications are outside of the scope of Arduino .
Also there will be regulations and approvals you need to meet before anyone can climb aboard .

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.