switch input delayed output without using delay

Hello, I am trying to delay the output of an arduino pin with the input of a switch without using delay.
I have a toggle switch that will pull low and hold low. When that input goes low I need a short delay (1/2 second) then have an output trigger high and stay until the toggle switch is turned off then I need that high pin to instantly go back low.
I modified the debounce sketch and have it sort of working using an extended delay on the debounce but it holds the output high for that duration after the toggle is switched off. I am not sure where to change the timing to make it work like I need. Can someone point me in the correct direction.
Thank you.



// constants won't change. They're used here to set pin numbers:
const int buttonPin = 3;    // the number of the pushbutton pin
const int ledPin = 11;      // the number of the LED pin

// Variables will change:
int ledState = LOW;         // the current state of the output pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin

// the following variables are unsigned longs because the time, measured in
// milliseconds, will quickly become a bigger number than can be stored in an int.
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 500;    // the debounce time; increase if the output flickers

void setup() {
  pinMode(buttonPin, INPUT);
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  // set initial LED state
  digitalWrite(ledPin, ledState);

void loop() {
  // read the state of the switch into a local variable:
  int reading = digitalRead(buttonPin);

  // check to see if you just pressed the button
  // (i.e. the input went from LOW to HIGH), and you've waited long enough
  // since the last press to ignore any noise:

  // If the switch changed, due to noise or pressing:
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer than the debounce
    // delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is LOW
      if (buttonState == LOW) {
        ledState = HIGH;
        ledState = LOW;

  // set the LED:
  digitalWrite(ledPin, ledState);

  // save the reading. Next time through the loop, it'll be the lastButtonState:
  lastButtonState = reading;

Your approach is wrong. You should leave the debounce portion of the code alone and use it to provide the switch state only. Change the debounce time to around 50ms.

If it were me I would use a little state machine with 3 states. The first state waits for the switch to turn on. When the switch is turned on the current time is saved in order to measure the 1/2 second delay and the state transitions to waiting for the delay to complete. When the delay completes the output is set to HIGH and the state transitions to waiting for the switch to turn off. When the switch turns off the output is set to LOW and the state transitions to the first state (waiting for the switch to turn on).

The states can be tracked by an enumeration or a counter. A switch statement can be used to determine which state you are currently in.

Fine explanation of the required state machine :slight_smile:

Also consider that the debounce time may or may not be subtracted from the 1/2 second delay - as you like.

Without experimenting or looking at the input you really don’t know how long the bounce will last.

You could dispense with an explicit debounce, set the output when the HIGH to LOW transition is detected, and not read the input during the .5 second delay by which time the bouncing would be gone. However, if the button is released during that delay time you won’t catch it until the delay is over, which might be OK.

The button should not be released within the .5 second delay and if it was it would be a non issue.
I would love to use a state machine but I don't understand how to do that. I get pretty frustrated that I still cant fully understand this and I have been messing with arduino's for a few years now. as soon as I think I understand what I am doing I try something new and get totally lost, then google search until I can find something that mostly does what I want it to do or make some changes and see if it now does what I want.

I would love to use a state machine but I don't understand how to do that. I get pretty frustrated that I still cant fully understand this and I have been messing with arduino's for a few years now.

Maybe this state machine tutorial can be of some help. There are a number of hits for state machine on a site search.

I've read so many examples and tried so many different things and I still dont know why I cannot wrap my head around this stuff. I even go back to the basic tutorials and can make it through them but then I cannot figure out something as simple as this. I was hoping to just be able to add some sort of delay without actually using delay, but oh well I guess using the extended debounce delay will have to be good enough for this project. I've already been working on trying to get this figured out for the past 6-7 hours.