LED delay / pattern help

Hello,

I'm trying to press a button and after 3 seconds, the first LED lights up, and after another 3 seconds while the button is still pressed, a second LED lights up. After this, I want to press a second button while the first button is still being pressed and trigger an LED pattern (just blinking back and forth).

I was able to get the LED sequence I wanted going in the first part of the interaction, but I am unsure how to write the code that should trigger a pattern when both of the buttons become pressed. Right now my computer is not understanding my code:

const int led1 =  7;
const int led2 =  8;

const int buttonPin1 = 2;
int buttonState1 = 0;
const int buttonPin2 = 3;
int buttonState2 = 0;

void setup() {
  pinMode(led1, OUTPUT);
  pinMode(led2, OUTPUT);
  pinMode(buttonPin1, INPUT);
  pinMode(buttonPin2, INPUT);

}

void loop() {
  buttonState1 = digitalRead(buttonPin1);
  buttonState2 = digitalRead(buttonPin2);

// One LED lights up after button is pressed for 3 seconds,
// Another LED lights up after a total of 6 seconds

  if (buttonState1 == HIGH && buttonState2 == LOW) {
    delay(3000);
    digitalWrite(led1, HIGH);
    delay(3000);
    digitalWrite(led2, HIGH);
  } 

// Blinking back and forth pattern

  else if (buttonState1 == HIGH && buttonState2 == HIGH) {
    digitalWrite(led1, HIGH);
    digitalWrite(led2, LOW);
    delay(50);
    digitalWrite(led1, LOW);
    digitalWrite(led2, HIGH);
    delay(50);
  } 
  else {
    digitalWrite(led1, LOW);
    digitalWrite(led2, LOW);
  }

}

This code does 'work' when I adjust the delays on the first part of the loop to around 500, then the computer is able to accept the next part of the interaction somehow. But when the delay is set to 3 seconds, the computer does not catch on to the next part of the code.

Edit: the computer will accept the blinking pattern 6 seconds after both LEDs are lit up, but i'd like the blinking pattern to happen immediately once the second & first button are pressed together. I can't do this with delay can I?

Any advice on how to get this working properly is appreciated.

Thanks!

I'd guess the "problem" is the delay().

EDIT - Now we KNOW the problem is delay().

Have you tried holding both buttons for at least 6 seconds? The processor isn't reading the button during the delay time and most of the time your program is doing nothing but delaying.

If you don't want to wait for the delay to "expire" you'll have to use millis() and the 'Blink Without Delay' method. ...Most real-world programs avoid the use of delay() or it's used very carefully.

[u]Blink Without Delay[/u]
[u]Demonstration code for several things at the same time[/u]

P.S.
It would be helpful if the comments in your code say if a button-push reads high or low. It's fairly common to use the built-in pull-up resistors so a button-push goes low.

The problem is that pressing both buttons at once may seem like simultaneous to you, but one button is going to make contact a millisecond or two before the other. Remember the Arduino can do 16,000 things in one millisecond. So it sees one button and doesn't know the other one is coming in the future.

You could just put in a small delay after detecting one button, to wait and then check both buttons. Maybe 10 milliseconds.

Of course the better way is to do it without any delays and use millis() for timing.

Hi,

Can you please post a copy of your circuit, in CAD or a picture of a hand drawn circuit in jpg, png?

Thanks.. Tom.. :slight_smile:

Just trying to understand: Am I right that in all of the description in the opening post, the first button is never released?

There’s nothing in OP’s words that says the buttons must both be newly pressed at the same instant, that I can see. (As pointed out it’s impossible, but I don’t think OP asked for that anyway.)

My take:

  • Press and hold button1 and start the clock, t=0
  • If button1 still pressed and t=3, led1 on
  • If button1 still pressed and t=6, led2 on
  • If button1 still pressed and t>6, and button2 pressed*, led1/led2 do a wig-wag

Is that correct?

If not, please clarify!

*If it is correct what should happen if button2 is pressed before t=6 but still pressed at t=6… does it get ignored, ie needs to release and re-press, or does it cause the wig-wag? (I think button2 needs a new press if t>6, to cause the wig-wag… not sure)

If it is correct, what should happen on buttons being eventually released?

  • If button1 is released when neither, either or both led1 and 2 are on (but not wig-wagging) then do led1 and led2 (if on) go off and we go back to the original state?
  • If both buttons are pressed and we’re wig-wagging, what should happen if button2 is released… back to the state of led1 and led2 solid on with button1 only? Or back to the original state, although button1 is still pressed, and wait for a release and new-press of button1?
  • If both buttons are pressed and we’re wig-wagging, what should happen if button1 is released leaving button2 pressed by itself…

This is crying out for a state diagram!

MorganS:
The problem is that pressing both buttons at once may seem like simultaneous to you, but one button is going to make contact a millisecond or two before the other.

More than a millisecond or two! :astonished:

MorganS:
The problem is that pressing both buttons at once may seem like simultaneous to you, but one button is going to make contact a millisecond or two before the other.

I would give that 200-500 ms difference for "simultaneous" press.

But I have the feeling that the OP is looking to see whether both are pressed, regardless of how much time there was in between the two buttons becoming pressed.

Hi,
I see from your code you have the buttons wired between 5V and the digital input pin of your controller.

Do you have a 10k resistor connected from the input pin of the controller to gnd?

What model Arduino are you using?

Thanks.. Tom... :slight_smile:

wvmarle:
But I have the feeling that the OP is looking to see whether both are pressed, regardless of how much time there was in between the two buttons becoming pressed.

That's how it read to me: press and hold button1, 3s later led1 comes on, still holding button1 3s later (6s total) led2 comes on, and still holding button1 if button2 is pressed any time after 6s total, led1 and led2 do a wig-wag pattern. Ignore button2 if it's pressed before 6s and require a release and new press if button2 was already held across the 6s boundary.

I coded it like that in a bit of free time all delay-less OP if you want it. (Took a decision that if button1 is released at any time it goes back to the start state; if button2 is released it goes from the wig-wag back to led1 and led2 solid on.) State change detect with the buttons in an array and the states in a switch...case.

Here's a state diagram for my understanding of OP's ask. In anticipation of using an array for the buttons I call them 0 and 1, not 1 and 2.

sayHovis:
I coded it....OP if you want it.

No takers, but wth, it was a fun exercise.

Hopefully s/he will have a solution by now.

you could add a counter variable, and make the buttons increase it until it reaches a certain number, that would delay the action with no need for ()delay,
if (buttonState1 == HIGH && buttonState2 == LOW) count=count+1, leds would need another if to light ie if (count=300) to light first or to light the second one if (count=600), so you tweak the delay by either changing the increment or the final value....
count needs to reset itself when it triggers the function, so add count=0 somwhere like if (count>0 && buttonState1 == LOW).

for the auto sequence, when both are pressed, Blink Without Delay is nice so it doesn't interfere with your timings, just figure out how to condition it right