Debounce delay on a radio.read msg (nRF24L01)

Hi! Working a project where a radio msg from a nRF24L01 will open a relay on a secound arduino with a nRF24L01.
everything works as i want, But i want some better safety feature on the relay.

I have searched and tried to implement a millis.debounce delay, on the incoming data msg but with no luck, seams to only work with a buttonState.

Why i want a timedelay on the receiver is if the nRF24L01 picks up a fast signal from a outside source it wont open the relay. I want it the check if the data msg is constant for about 0.2sec before opening the relay, if it get a signal for less then that it wont open the relay.

I saw that it is possible to have a “data validation” between the two arduino with nRF24L01 and maybe that is the way to go.

See in the code on the Receiver where i want the timedelay.

(im not to good of a programmer i understand some basics)

hope someone can help me with this or guide me in the right direction.
Kind regards// Melker S

Receiver:

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

int DataMgs[1];
RF24 radio(9,10);                               //Radio Input pins for nRF24L01
const uint64_t pipe = 0xE14BC8F482LL;           //Transmitting Adress
int Relay1 = 5;                                 //Relay to solinoid valve Connected to Digital pin 5
int Redled = 4;                                 //Ledlight
int Greenled = 3;                               //LedLight

void setup()
{
  pinMode(Redled, OUTPUT);
  pinMode(Greenled, OUTPUT);
  
  digitalWrite(Redled, HIGH);                   //Red light system booting
  digitalWrite(Greenled, LOW);
  
  Serial.begin(57600);                          //Loading text
  Serial.println("Wireless system on");
  
  pinMode(Relay1, OUTPUT);
  
  radio.begin();                                //Start Radio
  radio.openReadingPipe(1,pipe);                //Open Address
  radio.startListening();                       //Listening after Transmitters
 
  Serial.println("Receiver Running");

  delay(500);
  digitalWrite(Redled, LOW);                    //System booted and running
  digitalWrite(Greenled, HIGH);
}

void loop()
{
  
  if (radio.available())
  {
    bool done = false;    
    while (!done)
    {
    
      done = radio.read(DataMgs, 1);                          //Reading Signal from Transmitter
      Serial.print("NRF24L01 Fertilizing unit Receiveing: ");    
      Serial.println(DataMgs[0]);
     
      
        if (DataMgs[0] == 111)                                  //||||| HERE I WANT A DELAY||||||\\\
         {
        digitalWrite(Relay1, HIGH);                           //Relay ON
        digitalWrite(Redled, HIGH);
      }

     else
      {
        digitalWrite(Relay1, LOW);                            //Relay OFF
        digitalWrite(Redled, LOW);
        Serial.println("waiting for input");
        }
      delay(10);
     }
    }
 }

TX:

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


RF24 radio(9,10);                               //Radio Input pins to nRF24L01
const uint64_t pipe = 0xE14BC8F482LL;           //Transmitting Address
int IOinput = 2;                                //IO input signal to unit
int DataMsg[1];                                 //Data
int Redled = 4;                                 //Ledlight
int Greenled = 5;                               //LedLight
int sensorPinA0 = A0;
    
void setup()
{
  pinMode(Redled, OUTPUT);
  pinMode(Greenled, OUTPUT);
  
  digitalWrite(Redled, HIGH);                   //Red light system booting
  digitalWrite(Greenled, LOW);
  
  Serial.begin(57600);                          //Loading text
  Serial.println("Wireless Fertilizing System KallaxFlygAB");
  
  pinMode(2, INPUT);                            //IO input signal pinout on Arduino
  digitalWrite(2,LOW);                          //Set low state on pin 2

  radio.begin();                                //Start Radio
  radio.openWritingPipe(pipe);                  //Open Address
  radio.setPALevel(RF24_PA_MAX);                //Signal output power
  radio.stopListening();                        //Stop listning for other Transmitters
                        
  Serial.println("Transmitter Running");    //System Booted and running

  delay(500);
  digitalWrite(Redled, LOW);
  digitalWrite(Greenled, HIGH);
  
}

void loop() {
  // read the input on analog pin 0:
  int sensorValue = analogRead(sensorPinA0);
  // Convert the analog reading (which goes from 0 - 1023) to a voltage (0 - 5V):
  float voltage = sensorValue * (5.0 / 1023.0);
  // print out the value you read:
  Serial.println(voltage);

{
  if (sensorValue > 990){
  
    digitalWrite(Redled, HIGH);
    Serial.println("IO signal Sent");
    DataMsg[0] = 111;
    radio.write(DataMsg, 1);
  }
  else                        
  {
    digitalWrite(Redled, LOW);                 
    Serial.println("Ready");
    DataMsg[0] = 0;
    radio.write(DataMsg, 1);   
     }
   }

 }

If what you want is to make sure that the receiver / relay is not hacked, then the sender should send an encoded message which can only be understood by the receiver. Repeating the message for 200ms makes no sense unless there are some interference causing messages to be lost.

hmm okey, there is most likely a neater way of writing the code, How it works is that the RX relay should only be open as long as the TX has 5V on the input pin, when the 5V input gets disconnected from the TX the RX should close the relay.

I just want to have a small delay so if the TX input gets a 5V signal for a really short time (0.1sec or lower) the RX will not open the relay.

But i rather want to have the delay function on the RX as it will then protect it from a external source giving a fast signal.

Hope you understand :slight_smile:

not clear how long your activation msg, 111, is repeated for for how long. looks like any msg other than 111 is to deactivate your fertilizer

it would make sense to separate handle receiving a msg and determining some action and then processing that action. some state processing can keep track of each.

receiving an activation msg could increment a cnt, up to some limit. similarly receiving a deactivation msg could decrement a count

the action can be taken when the count reaches an extreme. a state tracks which action was taken last. if the last state is OFF, need on check if the count has reached a max to perform that action and change the state

not sure there is any need to have "done"

here’s one approach the separates all the pieces (uses button presses to simulate msgs)

byte pinsInp [] = { A1, A2 };
byte pinsOut [] = { 10, 11 };

#define N_INP   sizeof(pinsInp)

#define CNT_MAX   3
#define CNT_MIN   0

enum { Off = HIGH, On = LOW };

int cnt   = 0;
int state = Off;

// -----------------------------------------------------------------------------
void setup ()
{
    Serial.begin (115200);

    for (unsigned n = 0; n < N_INP; n++)  {
        pinMode (pinsInp [n], INPUT_PULLUP);
        pinMode (pinsOut [n], OUTPUT);
    }

    action (0);
}

// -----------------------------------------------------------------------------
int
chkInp ()
{
    static byte butLst [N_INP] = {};

    for (unsigned n = 0; n < N_INP; n++)  {
        byte but = digitalRead (pinsInp [n]);
        if (butLst [n] != but)  {
            butLst [n] = but;

            if (On == but)
                return pinsInp [n];
        }
    }

    return 0;
}

// -------------------------------------
void
action (
    int val )
{
    if (val)  {
        digitalWrite (pinsOut [0], Off);
        digitalWrite (pinsOut [1], On);
    }
    else {
        digitalWrite (pinsOut [0], On);
        digitalWrite (pinsOut [1], Off);
    }
}

// -------------------------------------
void loop ()
{
    // check inputs
    byte  inp = chkInp ();
    switch (inp)  {
    case A1:
        cnt = CNT_MAX <= ++cnt ? CNT_MAX : cnt;
        break;

    case A2:
        cnt = CNT_MIN >= --cnt ? CNT_MIN : cnt;
        break;
    }

    // separately handle actions
    if (Off == state)  {
        if (CNT_MAX == cnt)  {
            state = On;
            action (state);
        }
    }
    else {
        if (CNT_MIN == cnt)  {
            state = Off;
            action (state);
        }
    }
}

thanks for the reply. I will take a look into that! :slight_smile:

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