How to simulate a time delay relay

Hello all.

Does any of you know how to implement a time delay function on a Arduino UNO?
I have been using the delay() function in the following statement:

if (A0_Value > 522)
{
  delay(500);   
  if (A0_Value > 522)
{
  digitalWrite(LED1, HIGH);
}
}
else if (A0_Value < 522)
{   
  delay(5);
  digitalWrite(LED1, LOW);
}

This code will provide me with a 500 millisecond delay.
But my problem: The value is not monitored during the 500 milliseconds.
If the value drops below 522 within the 500 millisecond, and is back above 522 at the 500 millisecond point, the LED1 will switch on anyway.
It also delays the rest of the code.
I'm basically looking for an old-fashioned time delay relay function.
Sorry for comparing the Arduino with a PLC.

All suggestions are welcome :slight_smile:
Cheers; nico.

Sorry if I've misunderstood, but you want to turn on an LED if A0 is above 522 for 500ms?

Yes, you understood correctly.
But I only want it to switch on when A0 stays above 522 during the 500 ms.

The way I would do it is:

unsigned long startTime=millis();
char high=1;

while(millis()<startTime+500){
   high &= (analogRead(A0)>522);
}
if(high)
   digitalWrite(outputPin,HIGH);
else
   digitalWrite(outputPin,LOW);

You can also put additional code inside the while loop to avoid blocking the processor

if (value is below threshold)
  set lastTimeBelowThreshold to now

if (now minus lastTimeBelowThreshold  > some time interval)
  do something

Toby and Arch,
Thanks for your replies.
@ Toby, Your code is switching of the LED too fast, and holding up the rest of my code, but it works! :slight_smile:
@ Arrch, how can I put extra code inside to avoid blocking the processor?
I don't completely understand how to translate your code to my script. (I'm pretty new with C++).

Have a look at the blink without delay example in the IDE.
It should give you some ideas.

nicolaas44:
... and holding up the rest of my code...

We can't help you unless we can see it!!! :wink:

OK Toby.

It is quite a long story. (Sorry for being complicated).
The goal is to translate audio signals to optical signals.
The first thing i'm trying is to make a optical heart-beat checker. It is a medical project I'm trying with my brother (who is a doctor). The second step wil be to dedect breathing noise.
I made a amplifier filter to take the low frequency, and move it around the 2,5V on one of the inputs. I was able to display the sound on 8 LED's. However the LED's also display the background noise.
So I try to make them to react on either the positive or negative side of long wave. (Low frequency heart beat).
That is were I need the time delay for. The LED's should only react to a long wave.
Below some messy attempts. I try with "Level_LED1" first.

/*
  TubeChecker software.
  Use anelog inputs to analize hartbeat and breathing sounds, and than dispaying the result usin LED's.
  Writen by nicolaas Hartman, ENINN.
  V0_2 modifications:
  Make heartbeat signal more sensitive.
  V0_3 modifications:
  Time delay to filter out low frequency
  V0_4 modifications:
  New experimental Time delay to filter out low frequency
 */

// These constants won't change.  They're used to give names
// to the pins used:
const int HeartBeat = A0;  // Analog input pin that the low frequency filter is attached to
const int BreathNoise = A1; // Analog input pin that the breath noise filter is attached to
const int Choice = A2; // Analog input pin to choose between heart or breath display
const int Level_LED1 = 2;
const int Level_LED2 = 3;
const int Level_LED3 = 4;
const int Level_LED4 = 5;
const int Level_LED5 = 6;
const int Level_LED6 = 7;
const int Level_LED7 = 9;
const int Level_LED8 = 10;

int HeartValue = 0;        // value read from the low frequency filter
int BreathValue = 0;        // value read from the breath noise filter
int DisplayMode = 0;        // 1st value read from the mode selection input

void setup() {
  // initialize pin modes
  pinMode(Level_LED1, OUTPUT);
  pinMode(Level_LED2, OUTPUT);
  pinMode(Level_LED3, OUTPUT);
  pinMode(Level_LED4, OUTPUT);
  pinMode(Level_LED5, OUTPUT);
  pinMode(Level_LED6, OUTPUT);
  pinMode(Level_LED7, OUTPUT);
  pinMode(Level_LED8, OUTPUT);
  // initialize serial communications at 9600 bps:
  Serial.begin(9600); 
}

void loop() {
  // read the low frequency in value:
  HeartValue = analogRead(HeartBeat);            
  // read the breath filter in value:
  BreathValue = analogRead(BreathNoise);
  // read the mode choice input:
  DisplayMode = analogRead(Choice);
  
  // Map the heartbeat to the level LED's:
  unsigned long startTime=millis();
char high=1;

while(millis()<startTime+20)
{
   high &= (analogRead(HeartValue)>522);
}
if(high)
   digitalWrite(Level_LED1,HIGH);
else if (HeartValue < 522);
   digitalWrite(Level_LED1,LOW);
  
  
  if (HeartValue > 542 || HeartValue < 481)
{   
  digitalWrite(Level_LED2, HIGH);
}
else if (HeartValue < 542 || HeartValue > 481)
{     
  digitalWrite(Level_LED2, LOW);
}
  if (HeartValue > 562 || HeartValue < 461)
{
  digitalWrite(Level_LED3, HIGH);
}
else if (HeartValue < 562 || HeartValue > 461)
{
  digitalWrite(Level_LED3, LOW);
}
  if (HeartValue > 582 || HeartValue < 441)
{
  digitalWrite(Level_LED4, HIGH);
}
else if (HeartValue < 582 || HeartValue > 441)
{
  digitalWrite(Level_LED4, LOW);
}
  if (HeartValue > 602 || HeartValue < 421)
{
  digitalWrite(Level_LED5, HIGH);
}
else if (HeartValue < 602 || HeartValue > 421)
{
  digitalWrite(Level_LED5, LOW);
}
  if (HeartValue > 622 || HeartValue < 401)
{
  digitalWrite(Level_LED6, HIGH);
}
else if (HeartValue < 622 || HeartValue > 401)
{
  digitalWrite(Level_LED6, LOW);
}
  if (HeartValue > 642 || HeartValue < 381)
{
  digitalWrite(Level_LED7, HIGH);
}
else if (HeartValue < 642 || HeartValue > 381)
{
  digitalWrite(Level_LED7, LOW);
}
  if (HeartValue > 662 || HeartValue < 361)
{
  digitalWrite(Level_LED8, HIGH);
}
else if (HeartValue < 662 || HeartValue > 361)
{
  digitalWrite(Level_LED8, LOW);
}
  
  // print the results to the serial monitor:
  Serial.print("Heart = " );                       
  Serial.println(HeartValue);    
  Serial.print("Breath = " );                       
  Serial.println(BreathValue);
  Serial.print("Mode = ");      
  Serial.println(DisplayMode);   
  
  // wait 2 milliseconds before the next loop
  // for the analog-to-digital converter to settle
  // after the last reading:
  delay(2);                     
}

May I suggest a low pass filter, either a simple moving average in the code, or a hardware filter are easy to implement.
The method you've described might work, but to get the best results a filter will be much better.