Pressing and holding a button to increment/decrement a counter quickly

Hi.

I've been trying to solve this one for a few hours now and not gotten anywhere.

A project I'm building needs a counter to be incremented and decremented with two push buttons. The counter has a large range (1-512) so I'd like to avoid having to press the "+" button 255 times to reach the middle. I have already implemented wrap-around at each end of the counter which halves the maximum possible number of button presses.

Ideally, I would have a system where a short press of the "+" or "-" button increments/decrements by 1, and a long press (say, more than 500ms) inc/dec by 10, and continues to do so as long as the button is held.

I already have state change detection working for the single press of each button which inc/dec the counter as it should. I have no idea how to approach the press-and-hold portion of it through.

I have had a look at a few examples of press-and-hold but none seem to quite fit my application and nor have I been successful is altering any to work for me.

Below is the portion of code that I'm currently using. It is working as it should but needs the press-and-hold functionality adding:

const int upButtonPin = 6;            //Pin that the Address Up button is connected to. Internal pullup used.
const int downButtonPin = 7;          //Pin that the Address Down button is connected to. Internal pullup used.

boolean upButtonState = false; // indicates if the button is active/pressed
boolean upLastButtonState = false; // indicate if the button has been long-pressed
boolean downButtonState = false; // indicates if the button is active/pressed
boolean downLastButtonState = false; // indicate if the button has been long-pressed



void setup();

[Various code etc...]

void loop();

[Various code etc...]

upButtonState = digitalRead(upButtonPin);
    if (upButtonState != upLastButtonState) {
      if (upButtonState == LOW) {
        txAddress ++;
      }
      delay(50);
    }
    upLastButtonState = upButtonState;

    downButtonState = digitalRead(downButtonPin);
    if (downButtonState != downLastButtonState) {
      if (downButtonState == LOW) {
        txAddress --;
      }
      delay(50);
    }
    downLastButtonState = downButtonState;
    

  if (txAddress > 507) {    // Wrap around the TX address if it's higher that 506 (512 minus the 6 faders)
    txAddress = 1;
  }

  if (txAddress < 1) {      // Same but for the bottom end
    txAddress = 507;

[Various other code etc...]

Most people time the button press using millis(). If "time down" exceeds a certain threshold, change the increment.

You shouldn't use delay() with this method, except possibly for button debouncing, as you will miss button events.

Google "arduino long button press" for tutorials.