Button interrupt millis delay

Hi guys,

I am little bit in a dead end with millis(). I need to activate a relay with a button, and it relay should remain open 5000ms. I can do it with a Delay(). But, what if I press that button while not all of those millis run out? Obviously, the MCU will not notice it. I can not use interrupt as the button is tied to a D4 on Uno.

So my guess is to play with states. But here I need your help.

Here is what my code look like for now:

const int buttonPin = 4;

const int rlyPin = 2;

int buttonState = 0;

int rlyState = 1;

unsigned long previousMillis = 0;
;

const long interval = 1000;

void setup()
{
    pinMode(rlyPin, OUTPUT);

    pinMode(buttonPin, INPUT);

    digitalWrite(rlyPin, LOW);
}

void loop()
{
    buttonState = digitalRead(buttonPin);

    if (buttonState == HIGH)
    {
        rlyState = LOW;
    }
    else
    {
        rlyState = HIGH;
    }

    digitalWrite(rlyPin, rlyState);
}

Thank you in advance

MOD EDIT
Fixed code tags

Do you want the relay to react (5000ms more) to the second button press during the "relay open" or do you want the relay to close at 5000ms from the first button press?

If the only the code needs to do is react on one button press and keep a relay activated there is no problem using delay.

void loop()
{
  buttonState = digitalRead(buttonPin);
  if (buttonState == HIGH)
  {
    digitalWrite(rlyPin, LOW);
    delay(5000);
  }
  else
  {
    digitalWrite(rlyPin, HIGH);
  }
}

It's not very future proof.

Yes, but in time of delay, if I press button, again, the MCU will not noticed it.

Maybe I was not clear enough.

Relay is OFF.

I press and hold the button, the relay is ON.

I release the button, the relay is ON another few seconds and goes OFF.

But, if I press the button in meantime, I can not turn relay ON, as the MCU is in delay.

So, I maybe want to turn ON and reset this delay.

MOD EDIT
Fixed code tags and improved sketch formatting

const int buttonPin = 4;
const int rlyPin = 2;
int buttonState = 0;
int rlyState = 1;
unsigned long previousMillis = 0;
;
const long interval = 1000;
unsigned long currentMillis = 0;
void setup()
{
    pinMode(rlyPin, OUTPUT);
    pinMode(buttonPin, INPUT);
    digitalWrite(rlyPin, LOW);
}
void loop()
{
    buttonState = digitalRead(buttonPin);
    if (buttonState == HIGH)
    {
        if (currentMillis - previousMillis >= interval)
        {
            previousMillis = currentMillis;
            rlyState = LOW;
            currentMillis = millis();
        }
        else
        {
            rlyState = HIGH;
        }
    }
    digitalWrite(rlyPin, rlyState);
}

Well, first of all you should respond to button CHANGES not current state. Second, you should handle button bouncing (either via software using a small delay(50) after a change is detected, or, better, via hardware with a capacitor and a resistor).

Then you need to better clarify your goal because the code you have shown us turns and keeps the relay on while the button is pressed, and off as soon as you leave the button. Based on your description, I assume you just need a single press to activate the relay for 5 seconds. If you press the button again you reset the 5 seconds: just tell me that's correct, and I'll give you a few tips and some code using millis().

PS: please, always enclose the whole code inside a single "code" block, don't use single line formatting. Thanks.

I have a resistor for debouncing purposes. Thank you for pointing that out. Those are basic stuff, after all.

I didn’t say my code is ok. I don’t have a code in the first place. The second post is clarifying the goal.

And for the “code” issues, I have no idea why it appeared this way. I highlighted the whole code and pressed < code >.

There is a bug with the Discourse forum software that sometimes results in code posted in code tags ending up as a series of single lines of code each in code tags. That is probably what happened here.

I have fixed the code tags and for future reference I suggest that you don't use the Rich Text editor option of the forum post composer

In my experience the easiest way to tidy up the code and add the code tags is as follows

Start by tidying up your code by using Tools/Auto Format in the IDE to make it easier to read. Then use Edit/Copy for Forum and paste what was copied in a new reply. Code tags will have been added to the code to make it easy to read in the forum thus making it easier to provide help.

It is also helpful to post error messages in code tags as it makes it easier to scroll through them and copy them for examination

I usually copy the code to a notepad, and than copy it from there. But on WIN11, it is not the case, lol.

Use Copy for Forum. It's easy and you don't even have to add the code tags yourself

As a matter of interest, which version of the forum post composer ?

Just to make it clear to @who_took_my_nick

Make sure that (at the left hand side) M↓ is selected and not A

Thank you for the clarification but I was trying to make a point by deliberately not explaining how to switch between the editor options

  • This might generate some creative juices in you.