Convert blinking signal input to a on state

Hi, i would like to have your help... im not good at programming im better with electronics.

So i want to convert a blinking signal to a always on state IF not blinking then i want it off

the frequency comes from a blinking relay so its not a square wave but i can say every second it goes 1 time off and 1 time on but it isnt perfect every time like 500ms signal.

as soon as the arduino would recive 5v signal to the input pin it should put the output pin on HIGH if the signal dosent change after 1 second the output pin should be on LOW

the other thing i need to do this with 2 blinking relays and 2 different outputs and i dont want to use 2 arduinos so it would be nice if you could make them work independently.

Thanks in advance

You need a retriggering timer.
Each time the relay goes from Off to ON, or visa versa, start/set the timer.
if the timer times out, the blinking has stopped.

This page on Debouncing Switches in Arduino has a library to debounce the input.

The important point from your point of view is that it has an isChanged() method that return true on ON/OFF or OFF/ON, you can use that to reset you timer.

For timers see this tutorial
How to write Timers and Delays in Arduino

I use the millisDelay class, but the tutorial also covers using millis() directly
The code would be something like

#include "millisDelay.h"
#include "DebouncedSwitch.h"

millisDelay missingPulse;
unsigned long MISSING_PULSE_MS = 750; // > the longest on or off pulse

DebouncedSwitch sw(D4); // monitor a switch on input D4

void setup() {
   // ... 
}
void loop() {
  sw.update(); // call this every loop to update switch state
  
  if (sw.isChanged()) { // on to off or off to on
    missingPulse.start(MISSING_PULSE_MS); // start the timer again
  }
  if (missingPulse.justFinished()) { // timer timed out  no more pulses
     // do something here
  }

}
1 Like

This should do the trick:

const int inputOne  = 2;                // Define input & output pins
const int inputTwo  = 3;
const int outputOne = 12;
const int outputTwo = 13;

long stopTimeOne    = 0;                // Turn off time for each channel
long stopTimeTwo    = 0;


void setup() 
{
  pinMode(inputOne, INPUT);             // Set correct pin modes
  pinMode(inputTwo, INPUT);
  pinMode(outputOne, OUTPUT);
  pinMode(outputTwo, OUTPUT);

  digitalWrite(outputOne, LOW);         // Start with everything off
  digitalWrite(outputTwo, LOW);         //
  
}

void loop() 
{
  if (digitalRead(inputOne) == HIGH)    // Pulse being received for input 1?
  {
    stopTimeOne = millis() + 1000;      // If yes then set new stop time
  }

  if (digitalRead(inputTwo) == HIGH)    // Pulse being received for input 2?
  {
    stopTimeTwo = millis() + 1000;      // If yes then set new stop time
  }

  if (millis() < stopTimeOne)           // Time to turn off channel 1?
  {
    digitalWrite(outputOne, HIGH);      // If not then turn it on
  }

  else
  {
    digitalWrite(outputOne, LOW);       // If so then turn it off
  }
  
  if (millis() < stopTimeTwo)           // Time to turn off channel 2?
  {
    digitalWrite(outputTwo, HIGH);      // If not then turn it on
  }

  else
  {
    digitalWrite(outputTwo, LOW);       // If so then turn it off
  }
}
1 Like

consider

// enable output if input changes < 1 second

const unsigned long Timeout = 1000;

byte butPin = A1;
byte ledPin = 10;
byte butLst;
unsigned long msec;

void loop (void)
{
    byte but = digitalRead (butPin);

    if (butLst != but)  {
        butLst = but;

        digitalWrite (ledPin, HIGH);
        msec = millis ();
    }

    if ( (millis() - msec) > Timeout)
        digitalWrite (ledPin, LOW);
}

void setup (void)
{
    digitalWrite (ledPin, LOW);
    pinMode      (ledPin, OUTPUT);

    pinMode      (butPin, INPUT_PULLUP);
    butLst      = digitalRead (butPin);
}

or for multiple pins

// enable output if input changes < 1 second

const unsigned long Timeout = 1000;

byte ledPins [] = { 10, 13 };
byte butPins [] = { A1, A2 };
#define N_PINS  sizeof(butPins)

byte butLst [N_PINS];
unsigned long msec [N_PINS];

void loop (void)
{
    for (unsigned n = 0; n < N_PINS; n++)  {
        byte but = digitalRead (butPins [n]);

        if (butLst [n] != but)  {
            butLst [n] = but;

            digitalWrite (ledPins [n], HIGH);
            msec [n] = millis ();
        }

        if ( (millis() - msec [n]) > Timeout)
            digitalWrite (ledPins [n], LOW);
    }
}

void setup (void)
{
    for (unsigned n = 0; n < N_PINS; n++)  {
        digitalWrite (ledPins [n], LOW);
        pinMode      (ledPins [n], OUTPUT);

        pinMode      (butPins [n], INPUT_PULLUP);
        butLst [n]  = digitalRead (butPins [n]);
    }
}

1 Like

Another option:

// Runs on an UNO

// A retriggerable one-shot timer that runs when pulsed.
// As long as pulses arrive at a rate faster than the timer
// cycle the boolean isTimer1Active will remain true.  If
// pulses arrive slowly enough to allow the timer to complete
// isTimer1Active will go false.

// Demonstrates:
// millis() timer operation
// state change detection
// sensing/indicating timer completion
// doing more than one thing at a time


uint32_t const timer1Preset = 1500; // 1.5 seconds
uint32_t timer1PreviousMillis;
uint32_t timer1CurrentMillis;
bool isTimer1Active;
bool isFirstPass;

const byte enablePin = A3; // A0-A5 can be used as digital inputs
const byte externalLED = A0;
//
//-----------------------------
//
void setup() {
  Serial.begin(115200);
  pinMode(enablePin, INPUT_PULLUP); // INPUT_PULLUP avoids the need for a discrete resistor.
  pinMode(LED_BUILTIN, OUTPUT);
  pinMode(externalLED, OUTPUT);
  isFirstPass = true;
}

void loop() {
  bool newTriggerPulse;
  static bool buttonWasPressedLastTime;

  if (isFirstPass) {
    Serial.print("\n\nTimer  Timer\n");
    Serial.println(" Acc   Done");
    displayFunction(timer1CurrentMillis - timer1PreviousMillis, isTimer1Active);
    delay(1000); // Pause for user to see column headings
    isFirstPass = false;
  }
  bool isButtonPressed = (bool) !digitalRead(enablePin); // check button state before proceeding
  timer1CurrentMillis = millis(); // Take a snapshot of millis() to use for processing.
  //
  // The one-shot section
  //
  if (isButtonPressed and not buttonWasPressedLastTime) { // <- These two lines
    // if (isButtonPressed && !buttonWasPressedLastTime) // <- are equivalent
    newTriggerPulse = true;
  }
  else {
    newTriggerPulse = false;
  }

  buttonWasPressedLastTime = isButtonPressed;
  //
  // End one-shot
  //
  //
  // Begin timer update activities
  //
 
  if (newTriggerPulse) // Imagine a pulse like ____͞____
  {
    timer1PreviousMillis = timer1CurrentMillis; // Reset the timer.
    isTimer1Active = true;
  }
  else {  // If newTriggerPulse is false, timing cycle runs
    if (timer1CurrentMillis - timer1PreviousMillis >= timer1Preset) { // If time elapsed set isTimer1Active
      isTimer1Active = false;
    }
  }
  //
  // End of timer1 update activities
  //
  digitalWrite(LED_BUILTIN, isTimer1Active);  // Send timer1's completion status to the onboard LED
  digitalWrite(externalLED, isTimer1Active);

  displayFunction(timer1CurrentMillis - timer1PreviousMillis, isTimer1Active);
} // end of loop

//--------------------------------------------

void displayFunction(unsigned long timer1, bool timedOut) {

  // Display runtime values passed from caller
  Serial.print(timer1);
  Serial.print("\t");
  Serial.print(timedOut);
  Serial.println();
}

Whichever route you take you'll have to make separate independent variables for each timer.

arrays

Or separate class instances like millisDelays

millisDelay timer1;
millisDelay timer2; // etc

which hold the timer variables internally.

Just for fun I thought I'd see how compact I could make my code if normal conventions were "thrown out the window". Obviously an extreme example, but in future I might start putting a few extra things on one line to make the program a bit "shorter but fatter".

#define dw digitalWrite 
#define dr digitalRead
#define pm pinMode
#define m millis()
int i1=2; int i2=3; int o1=12; int o2=13; long s1=0; long s2=0;
void setup(){pm(i1,INPUT); pm(i2,INPUT); pm(o1,OUTPUT); pm(o2,OUTPUT); dw(o1,0); dw(o2,0);}
void loop() {if(dr(i1)==1){s1=m+1000;}if(dr(i2)==1){s2=m+1000;}if(m<s1){dw(o1,1);}else{dw(o1,0);}if(m<s2){dw(o2,1);}else{dw(o2,0);}}

Whatever the mechanism my point is that those unfamiliar with the subject

will sometimes proceed assuming that a variable named, for example, timerLastMillis can be reused for as many timers as needed.

Hello and good morning brunofresco
Do you have a ready sketch already?
I could take a view into my sketch box to find a sketch with a "retriggered timer" function to help you.
What do you think?

Hi guys thanks a lot for all the responses!!!! :smiley: i will test each one out and i will tell you what code does work the best! Give me a week please.

You make this comunnity great!

1 Like

You're welcome!

Just be aware that my version uses the millis() function (essentially just a timestamp) that rolls around to 0 every 49.7 days. The sketch I wrote doesn't take that into account and thus every 49.7 days the output will shut off for 1 cycle even though there's been a valid input pulse.

I also wrote it in such a way that it'll turn off the output exactly 1 second after the pulse goes low (so the timers start when the pulse stops aka "trailing edge activation").