toggle boolean state

Folks,

Below is a small snippet of code for an alarm clock I'm going to eventually build once I've worked out the code. I'm working on having a dual function button. When a short press is detected do one thing. When a long press is detected do another. I'd like the short press on a button to toggle the boolean state for the alarm. One short press, alarm is on. A second short press and the alarm is off. I've seen code where folks accomplish this but I'm having trouble searching online for what I'd like to do. Particularly because I'm not sure what to search for.

As always, any help is appreciated.

Best,

Tony

    if(button.isPressed())
    {
    pressedTime = millis();
    }

    if(button.isReleased()) 
    {
        releasedTime = millis();
    
        long pressDuration = releasedTime - pressedTime;
    
        if( pressDuration < SHORT_PRESS_TIME )
        { 
          lcd.setCursor(0,2);
          lcd.print("short press detected");
          Serial.println("short press detected");
          shortPress = true;
        }  
    
        if ( pressDuration > LONG_PRESS_TIME )
        {     
          lcd.setCursor(0,2);
          lcd.print("long press detected ");
          Serial.println("long press detected");
          longPress = true;
        }  
    }

First, all variables used to store or do calculations with millis() must be declared as unsigned long. Secondly, make sure you don't have any delay() calls.

Why are there 3 times? This will confuse people as the program will be unresponsive if pressDuration happens to fall between SHORT_PRESS_TIME and LONG_PRESS_TIME.

@aarg - I think I see what you're saying. Since I have less than, a possible space in the middle, and then greater than. I can fix that.

Updated code.

    if(button.isPressed())
    {
    pressedTime = millis();
    }

    if(button.isReleased()) 
    {
        releasedTime = millis();
        long pressDuration = releasedTime - pressedTime;
    
        if( pressDuration < LONG_PRESS_TIME && alarmOn == true)
        { 
          alarmOn = false;
          lcd.setCursor(0,2);
          lcd.print("short press detected");
          Serial.println("short press detected");
          shortPress = true;
        }  

        if( pressDuration < LONG_PRESS_TIME && alarmOn == false)
        { 
          alarmOn = true;
          lcd.setCursor(0,2);
          lcd.print("short press detected");
          Serial.println("short press detected");
          shortPress = true;
        }  

        if ( pressDuration >= LONG_PRESS_TIME)
        {     
          lcd.setCursor(0,2);
          lcd.print("long press detected ");
          Serial.println("long press detected");
          longPress = true;
        }  
    }

The problem is my code isn't toggling. Once the alarm is on, it stays on.

I think I figured it out.

          alarmOn = !alarmOn;

pressDuration, pressedTime, and releasedTime should all be unsigned long.

    if(button.isPressed())
    {
    pressedTime = millis();
    }

    if(button.isReleased())
    {
        releasedTime = millis();
        long pressDuration = releasedTime - pressedTime;

This won't work because 'pressedTime' is not the time the button was FIRST seen pressed but the time it was LAST seen pressed. It is unlikely to ever be more than a millisecond or two before the button is seen as released. Your 'pressDuration' will always be a very small number.

You need to detect state change:

  static boolean oldButtonState = false; // Button is initially not pressed
  boolean newButtonState = button.isPressed();
  if (newButtonState != oldButtonState)
  {
    // State Change Detected
    oldButtonState = newButtonState;
    if (newButtonState)
    {
      // Freshly pressed
      pressedTime = millis();
    }
    else
    {
      releasedTime = millis();
      unsigned long pressDuration = releasedTime - pressedTime;

      // ACT ON pressDuration HERE
    }
}

Best to learn to draw state-transition diagrams and make the states all explicitly named. With
short-press v. long-press there are 3 states, "idle", "short-press" and "long-press", and two ways to exit
the "short-press" state - either by a button release, triggering the short press event, and through
time-out, triggering the long press event (don't wait for the release, that's poor feedback to the user).

For user interfaces and interaction finite state machines are everywhere, learn them!