How do you create an on-delay timer?

Hi everyone,

I tried searching for this and couldn't find a solution that I could understand anyway. I need to program a Nano to be a simple on-delay timer. As a PLC programmer to me this seems very simple but for an Arduino it seems a little more tricky.

I have a normally open float switch wired as an input. if that float switch is closed for 10 seconds I want an LED to come on and stay on until the power to the Nano is reset. I tried this and of course it doesn't work.

void setup() {
 
 pinMode(10, OUTPUT);
 pinMode(13, OUTPUT);


 pinMode(2, INPUT_PULLUP);


 digitalWrite(10, LOW);
 digitalWrite(13, LOW);
 

}

void loop() {

 
  if(digitalRead(2) == LOW and delay(10000)
 
  {digitalWrite(10, HIGH);}
 
  


 
}

I know I'm way off but I have no clue how to get it to work. Any help would be greatly appreciated.

Yes, a little more tricky.

You could count the seconds with a delay, or you can make a big step forward and use millis().
The function millis() returns the number of milliseconds since the Arduino started. There are a number of neat tricks that can be done with that. For example doing multiple things at the same time, or keep looking at the switch while also keeping track of the time.

Start with the Blink Without Delay: https://www.arduino.cc/en/Tutorial/BlinkWithoutDelay.

If you don't want to go the millis() way, then perhaps you can try a library for timing. There are also PLC libraries for Arduino, but I have never tried one.

Will bite my tongue and say try this:

if(digitalRead(2) == LOW)
{
delay(10000);
if(digitalRead(2) == LOW)
{
digitalWrite(10, HIGH);
}
}

larryd:
Will bite my tongue and say try this:

if(digitalRead(2) == LOW)
{
delay(10000);
if(digitalRead(2) == LOW)
{
digitalWrite(10, HIGH);
}
}

I tried this and I get "exit status 1 expected initializer before 'if'"

Phobos84:
I tried this and I get “exit status 1 expected initializer before ‘if’”

Did you put it in a function like setup() or loop()? If so, just go back and look for your typo. You overwrote or deleted something. larryd’s code is correct. If that fails, re-post the entire modified sketch.

Sorry I had a bracket out of place. I got that to upload but it's not working properly. Sometimes when I trigger the float switch the LED will come on after 10 seconds and other times it comes on right away. It seems random but never takes more than 10 seconds.

Basically I need a timer that if the float switch is made for 10 seconds it will turn an LED on and it needs to stay on until the Arduino is powered off.. If the float is made for less than 10 seconds it will reset the timer. In PLC's this is a TON instruction. I have no idea how to do this with an Arduino.

Phobos84:
Sorry I had a bracket out of place. I got that to upload but it's not working properly.

Then post it.

void setup() {
 
 pinMode(10, OUTPUT);
 pinMode(13, OUTPUT);


 pinMode(2, INPUT_PULLUP);


 digitalWrite(10, LOW);
 digitalWrite(13, LOW);
 

}

void loop() 
{
 if(digitalRead(2) == LOW)
    
      delay(10000);     
      if(digitalRead(2) == LOW)
        {
           digitalWrite(10, HIGH);
        }
    }

After playing with this more it seems like this code is making it count 10 seconds and if I happen to close the float switch at the end of the 10 second count then the LED comes on. So if I power it up and walk away for a undetermined period of time and flip the switch the time it will take for the LED to come on will be random.

void setup() 
{
 pinMode(10, OUTPUT);
 pinMode(13, OUTPUT);
 pinMode(2, INPUT_PULLUP);
 digitalWrite(10, LOW);
 digitalWrite(13, LOW);
}

void loop() 
{
 if(digitalRead(2) == LOW)
    {
      delay(10000);   
      if(digitalRead(2) == LOW)
        {
           digitalWrite(10, HIGH);
        }
    }

} // END of loop()

Phobos84:
Basically I need a timer that if the float switch is made for 10 seconds it will turn an LED on and it needs to stay on until the Arduino is powered off.. If the float is made for less than 10 seconds it will reset the timer. In PLC's this is a TON instruction. I have no idea how to do this with an Arduino.

Here's a simple TON.

// A basic on-delay timer.  Runs when enabled.
// Reset when resetPin goes low.  Reset overrides enable

uint32_t accValue;
uint32_t preset = 3000; // 3 seconds
uint32_t previousMillis;
uint32_t currentMillis;

const byte enablePin = 8;
const byte resetPin = 10;
const byte doneLED = 13;

void setup() {
  Serial.begin(115200);
  pinMode(enablePin, INPUT_PULLUP);
  pinMode(resetPin, INPUT_PULLUP);
  pinMode(doneLED, OUTPUT);
}

void loop() {
  currentMillis = millis();
  if (digitalRead(enablePin) == LOW) { // pushbutton pressed, run timer
    accValue = accValue + currentMillis - previousMillis;
  }
  else {
    accValue = 0;
  }
  
  if (accValue >= preset) {
    accValue = preset;
    digitalWrite(doneLED, HIGH);
  }
  else digitalWrite(doneLED, LOW);
  previousMillis = currentMillis;

  if (digitalRead(resetPin) == LOW) accValue = 0;

  Serial.println(accValue); // if needed
}

Thank you!

This code is so far over my head it's not even funny. It works much better with this. The only issue is the LED needs to stay on until power loss. With the following code the LED will turn off as soon as I open the switch. So I guess I need a TON with a holding circuit.

// A basic on-delay timer.  Runs when enabled.
// Reset when resetPin goes low.  Reset overrides enable

uint32_t accValue;
uint32_t preset = 10000; // 10 seconds
uint32_t previousMillis;
uint32_t currentMillis;

const byte enablePin = 2;
const byte resetPin = 7;
const byte doneLED = 10;

void setup() {
  Serial.begin(115200);
  pinMode(enablePin, INPUT_PULLUP);
  pinMode(resetPin, INPUT_PULLUP);
  pinMode(doneLED, OUTPUT);
}

void loop() {
  currentMillis = millis();
  if (digitalRead(enablePin) == LOW) { // pushbutton pressed, run timer
    accValue = accValue + currentMillis - previousMillis;
  }
  else {
    accValue = 0;
  }
  
  if (accValue >= preset) {
    accValue = preset;
    digitalWrite(doneLED, HIGH);
  }
  else digitalWrite(doneLED, LOW);
  previousMillis = currentMillis;

  if (digitalRead(resetPin) == LOW) accValue = 0;

  Serial.println(accValue); // if needed
}

Got it. I just removed the else digitalWrite(doneLED, LOW); at the end.

This is what worked

// A basic on-delay timer.  Runs when enabled.
// Reset when resetPin goes low.  Reset overrides enable

uint32_t accValue;
uint32_t preset = 10000; // 10 seconds
uint32_t previousMillis;
uint32_t currentMillis;

const byte enablePin = 2;
const byte resetPin = 7;
const byte doneLED = 10;

void setup() {
  Serial.begin(115200);
  pinMode(enablePin, INPUT_PULLUP);
  pinMode(resetPin, INPUT_PULLUP);
  pinMode(doneLED, OUTPUT);
}

void loop() {
  currentMillis = millis();
  if (digitalRead(enablePin) == LOW) { // pushbutton pressed, run timer
    accValue = accValue + currentMillis - previousMillis;
  }
  else {
    accValue = 0;
  }
  
  if (accValue >= preset) {
    accValue = preset;
    digitalWrite(doneLED, HIGH);
  }
  
  previousMillis = currentMillis;

  if (digitalRead(resetPin) == LOW) accValue = 0;

  Serial.println(accValue); // if needed
}

Thank you guys so much! This forum is awesome! In case anyone is curious this is being used in a car. There is a float switch in an oil pan that detects when the oil is low. When I built the car I thought it would be cool to use this float switch in case I ever lost oil while racing. Well when I wired everything up I found that after hard breaking the oil dash light would flicker on and off as the oil sloshed in the pan. This is normal and I have plenty of oil in the engine. So I just needed a time delay to stop the blinking.

If hard braking causes oil sloshing, you need more of different baffels in the pan.

Paul

Phobos84:
This code is so far over my head it's not even funny.

Nothing really sophisticated there, just take one small piece at at time and you can see how simple it is. It's essentially like looking at the guts of a PLC timer

Phobos84:
With the following code the LED will turn off as soon as I open the switch. So I guess I need a TON with a holding circuit.

You mean like a latch? Just use a boolean set false in setup() and use the timer done condition to set the boolean true. Use the boolean to do whatever.