Long press button option

Hi, is there an easy way to add a long press option to my button?
without using a button library

  unsigned long buttonPressTime;

  byte upButtonState = digitalRead (upButton);
  if (upButtonState != oldUpButtonState) {
    if (millis () - buttonPressTime >= debounceTime) { // debounce
      buttonPressTime = millis ();  // when we closed the switch
      oldUpButtonState =  upButtonState;  // remember for next time

      if (upButtonState == LOW && mainMenu == true) {   // if button up pressed & main menu is active

        menuPage ++; //increment the current menu page's position count
        if (menuPage > 4) {
          menuPage = 0;  //0-4 (5 menu pages)
        }
      }
   }
}
  1. When the switch is detected as closed, record the time from millis().

  2. When the switch is detected as opened, print millis() minus the time in 1.

  3. In #2, if this time >= the time for a long press, do your stuff . . .

WIth that approach, whatever should happen will a long press will only happen after the button is released which could be substantially longer than what is defined as a long press. The user would never know if they have pressed the button long enough or not. It is better to to act immediately once you have exceeded your long press time so the user knows it has happened.

To do this, outside your debounce routine, check the state of the button and the duration and then act. You will also need to note that a long press action has happened so you don't continuously retrigger.

unsigned long buttonPressTime;
bool longPressTriggered;
const unsigned long longPressTime = 5000;

byte upButtonState = digitalRead (upButton);
if (upButtonState != oldUpButtonState) {
  if (millis () - buttonPressTime >= debounceTime) { // debounce
    buttonPressTime = millis ();  // when we closed the switch
    oldUpButtonState =  upButtonState;  // remember for next time
    longPressTriggered = false;

    if (upButtonState == LOW && mainMenu == true) {   // if button up pressed & main menu is active

      menuPage ++; //increment the current menu page's position count
      if (menuPage > 4) {
        menuPage = 0;  //0-4 (5 menu pages)
      }
    }
  }
}

if ( longPressTriggered == false && upButtonState == LOW && millis() - buttonPressTime >= longPressTime ) {
  // do your long press event
  longPressTriggered = true;
}

Just understand the concepts. Detecting when a button becomes pressed, debouncing and detecting when it becomes unpressed again. Then it is just a matter of comparison in standard millis timing. It doesn’t matter what the “event” is that triggers your timing it is always the same. Short press, long press, double press etc

I worked on this debounce and button press capture function. It needs to be modified a bit for a long press, but the frame work is there.

void readButtonPress(){
  
  static byte areUnpressed = PINB & B00011111;                            // define a protected byte areUnpressed with mask B00011111 to focus on pins of interest to portD upper byte PINB status register (pin 15 to pin 8). 
 
       
    areUnpressed = PINB & B00011111;                                      // capture masked pins status register
    if (areUnpressed != B00011111){                                       // detect whether or not the pin status has changed. meaning buttons are pressed
       myTime3 = (millis() - myTime2);                                    // subtract current system timer from previously captured timer to get how many milliseconds passed since first pass
       if (myTime3 > 10){                                                 // has 10 milliseconds passed? if so capture current millisecond timer value, move status of pressed buttons to loadTX_Decode ready for transmit, zero out myTime3 used in 10 millisecond counter to set up next 10 millisecond debounce.
         myTime2=  millis();  
         loadTX_Decode = areUnpressed;  
         myTime3 =0;             
       }         
    }else{                                                                // if buttons not pressed zero out myTime2 and myTime3, reload pin status register to areUnpressed, move pin status to loadTX_Decode ready to transmit
      myTime2 = 0;
      myTime3 = 0;
      areUnpressed = PINB & B00011111;                                    // since buttons were unpressed expected value B00011111
      loadTX_Decode = areUnpressed ;                                      // load above mentioned into transmit byte 
    }
}