How to detect Button pressed time and keep sketch running

I have a sketch that need to detect button pressed time but need keep sketch running.
have any idea or provide sketch sample to help me?

for explain:

When I press button less than 1s. the sketch turn on the W_LED.
When I press button more than 2s the sketch turn on the Y_LED, but if press button more 2s and not release button, the sketch also needs turn on the Y_LED.

sketch 1:
I use "while" command, but sketch pending here , until button released.
while (digitalRead(buttonPush) == LOW);

Sketch 2:
If I use "if", the startTime will always be update

if (digitalRead(buttonPush) == LOW)
startTime = millis();

if (digitalRead(buttonPush) == HIGH)
duration_time = millis() - startTime ;

Sketch 3: PluseIN have 1 second waiting time when no button is pressed
duration_time = pulseIn(buttonPush/1000, LOW);

below is a part of my current sketch:

#define whiteLED 3
#define yellowLED 11
#define buttonPush 2
#define boostLED_ON_OFF 8


  pinMode(whiteLED, OUTPUT);
  pinMode(yellowLED, OUTPUT);

  pinMode(buttonPush, INPUT);
  pinMode(boostLED_ON_OFF, INPUT);

  digitalWrite (boostLED_ON_OFF, LOW); // default disable boost IC
  digitalWrite (buttonPush, HIGH); // internal pull high

  analogWrite(whiteLED, 0); //default white LED PWM output =0
  analogWrite(yellowLED, 0); //default yellow LED PWM output= 0
  Serial.begin(9600);

void loop()
{

  if (digitalRead(buttonPush) == LOW)// Read status of tack switch
  {
    startTime = millis();                 
    
    while (digitalRead(buttonPush) == LOW);   // sketch pending here. 
    duration_time = millis() - startTime ;
   // duration_time = pulseIn(buttonPush/1000, LOW);
   
    delay(10);

    //===============Button detect for function select====================

    if (duration_time < brightness_level_adj)
    {
      digitalWrite (boostLED_ON_OFF, HIGH); // ENABLE boost LED IC)
      brightness_SEL++;
      if (brightness_SEL > 4)
      {
        analogWrite(whiteLED, brightness_0);
        analogWrite(yellowLED, brightness_0);
        brightness_SEL = 0;
        //color_SEL =1;  // reset color to white color after one cycle
        digitalWrite (boostLED_ON_OFF, LOW); // turn off boosr IC

      }
   }


    if (duration_time > color_SEL_adj)
    {
      color_SEL++;
      if (color_SEL >= 4)
      {
        color_SEL = 1;
      }

      // delay(50);
    }
    Serial.print(" suration = ");Serial.print(duration_time); Serial.println("ms");
    Serial.print(" brightness= "); Serial.println(brightness_SEL);
    Serial.print(" color select= "); Serial.println(color_SEL);
    delay(50);


    //=========================WHITE LED ====================================
    if (brightness_SEL == 1 && color_SEL == 1)
    {
      analogWrite(whiteLED, brightness_25); analogWrite(yellowLED, brightness_0);
    }

    //==========================YELLOW LED ==============================
    if (brightness_SEL == 1 && color_SEL == 2)
    {
      analogWrite(whiteLED, brightness_0); analogWrite(yellowLED, brightness_25);
    }


}
}

There is a difference between a button being pressed and a button becoming pressed. You want to time with the later. To do that, see the State change detection example. Or, go the easy way and use something like Bounce2.

And if you want to do more with your sketch than just that, don't use delay. Anywhere! See Blink without delay for that :slight_smile:

Hello~ Septillion

The problem is not cause from switch bounce or delay.

I would open Y_LED at the same time after the sketch detects pressed button 2 seconds, even if the button is not released.

thanks.

Take a look at this:

https://forum.arduino.cc/index.php?topic=350287.0

Hello Larryd

thanks for your information, but I consider use one button.

When I press button less than 1s. the sketch turn on the W_LED.
When I press button more than 2s the sketch turn on the Y_LED, but if press button more 2s and not release button, the sketch also needs turn on the Y_LED.

Any button pressed for 2s was at one stage pressed for under 1s.

So does this:

When I press button less than 1s. the sketch turn on the W_LED.

.... actually mean press and release within 1s, or does W come on during the 1st second (from t=0 until t=1) and then go off during the 2nd second (t=1 until t=2)?

I think what you want is:

  • Press and release within 1 second, W comes on and stays on
  • Press for longer than 2 seconds, Y comes on, and stays on if button released

Is that right?

And then just for completeness, is anything supposed to happen later that might turn them off again?

Hello arduin_ologist,

Please reference to attached for explain

Step4 is my problem.

thanks.

Step 4 is no different from step 3.

The key thing is surely that if the button becomes pressed, Y comes on at the instant 2s has elapsed since it became pressed. So if you release (ala step 3) or hold it until Armageddon (ala step 4) it makes no difference, Y is on.

I think if you are seeing them as different, there may be something else you haven't explained.

Hello Arduin_ologist,

Here is a part of my sketch.
Because I use "while" command, so I have to release button to exit "while" to turn on Y_LED
But if I don't release button, the sketch still in "while" loop and can't turn on Y_LED, this is not instantaneously.

while (digitalRead(buttonPush) == LOW); // << need release button to exit while loop

duration_time = millis() - startTime ; << button time

// turn on Y_LED

if (duration_time > 2000)
{
analogWrite(yellowLED, 250); // turn Y_LED
}

if (duration_time < 1000)
{
analogWrite(whiteLED, 250); // turn W_LED
}

have any idea?

thanks.

knee266:
have any idea?

You still haven't explained why you see steps 3 and 4 in your requirements spec as different. You can't throw code at a problem that is ambiguous: if Y is supposed to come on after 2s, whether or not you later release the button or hold it down, then your requirements become:

  • As before
  • As nefore
  • Press button >2s, turn on Y-led
  • There is no step 4

Or am I missing something?

And btw turning W on with a release after 1s actually means that release after 2s to turn Y on should also still turn W on since 2s>1s. I think you mean, turn W on with a release after 1s but before 2, but that's not actually what you have said.

I have written a sketch if you want it that:

  • Turns W on if button is pressed but released between 1 and 2s
  • Turns W off if button is pressed and released before 1s
  • Turns Y on if button is held longer than 2s, regardless of released or not after that
  • Never turns Y off since that need was not described
  • Can repeatedly on and off W even after Y is (permanently) on

Hello Arduin_ologist,

  • Turns W on if button is pressed but released between <1s
  • Turns W off if button is pressed and released before <1s
  • Turns Y on if button is held longer than 2s, regardless of released or not after that<< YES
  • Turns Y off if button is held longer than 2s, regardless of released or not after that
  • Never turns Y off since that need was not described<< YES

Can repeatedly on and off W even after Y is (permanently) on << YES

thanks.

Now I'm even more confused.

What does this mean? Turns W on if button is pressed but released between <1s

And these are contradictory:

Turns Y off if button is held longer than 2s, regardless of released or not after that (you added this)
Never turns Y off since that need was not described<< YES (so why does this say yes, contradicts the new line above)

So now it seems (in spite of that contradiction) that the requirement is perhaps:

  • 1-2 second press, W goes on
  • <1 second press, W goes off
  • 2 second press, Y toggles (goes on if off, off if already on; that's the new line you added)

  • Both leds are independent: each can be on or off regardless of the state of the other

This is crying out for a state diagram, where the circles represent the states (that is, the way things are) and the arrows represent the transitions (that is, the actions that cause a move from one state to another.) They're easy to draw in say PowerPoint, and help one see if all possible states and transitions are accounted for. You can look at the diagram and say Hmmm ok, if I'm in and perform , where should that take me.

The example below (source) is for a turnstyle:

You can account for "useless actions" like in the turnstyle diagram if you push when it's locked, it stays locked.

I think you should try draw one for your led system; but at least confirm if my list above is now correct? (The code I wrote yesterday (not posted it here yet) didn't account for Y going off, ever: main question is does a long press need to toggle Y?)

Hello Arduin_ologist,

I provide diagram of full function for you reference.
The "?" function is my question.

below JPG for you reference,

thanks.

The "?" function is my question.

But what IS the question?

Are you asking what should happen if the button is pressed longer than 2 seconds and never released? Because that's surely part of your specification....

The way I understood it, pressing the button longer than 2s turns Y on, and it doesn't matter if it's released just after 2s or held for the rest of time.

Is something supposed to happen if the button is released after 2 seconds?

Hello Arduin_ologist,

The question is press button more than 2 seconds, but how to change the LED color instantaneously without release the BTN.

thanks.

Assuming a switch press goes from HIGH to a LOW at which time you set a Flag and start a 2 second timer.

When the switch goes from LOW to HIGH (released) reset the Flag.

If ever the Flag is set ‘and’ the 2 second timer has timed out, turn on the LED.

Hello~ arduin_ologist and larryd

Finally, I use flag to solved this problem already, thanks.

Flags are great :wink: