How to make an arduino button to forget his past purpose? For my school project im making an arduino speedometer for a bicycle. I will be using a reed switch sensor to get the speed. There will also be an clock and a termometer, it will be on a 16x2 lcd screen. To get the speed I will need the user to type in his bike size, in zoll. I managed to let the user tap the button until his size and then double tap the button to confirm it. Alright, fine. Now I need the same button to FORGET his last purpose. Because I want to use the same button to change the screen between speed, clock and termometer. SPEED -> tap -> CLOCK -> tap -> TEMPERATURE -> tap -> SPEED ........

I hope you get the idea. After the user picks his size, if he keeps tapping the number it would just keep on growing. So, im trying to make the button forget, or make him go trough that loop only once. 

Pick your size tap tap tap double tap, thank you. And stop! I want him to do that only once and never again. I will need the same principle when the user will adjust his clock, he will have to tap to set it, save the number but reset the buttons function.

#include &lt;LiquidCrystal_I2C.h&gt;
#include &lt;LiquidCrystal.h&gt;
LiquidCrystal_I2C lcd(0x27, 16,2);
#define buttonPin 7        
int a = 16;
int b = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.print("RADGROESSE IN");
  lcd.setCursor(0, 1);
  lcd.print("ZOLL EINGEBEN");

   // Set button input pin
   pinMode(buttonPin, INPUT);
   digitalWrite(buttonPin, HIGH );
}
void loop() {
   int b = checkButton();
   if (b == 1) clickEvent();
   if (b == 2) doubleClickEvent();
}
void clickEvent() {

   lcd.setCursor(14, 1);
    lcd.print(a);
    delay(100);
    lcd.print(" ");
    delay(100);
    a++;
    delay(100);
    if(a &gt;= 23){
      a = 16;
      }
}
void doubleClickEvent() {
      b = a - 1;
      Serial.println("Button was idle for one second or more");
      lcd.clear();
      lcd.print("ZOLL = ");
      lcd.setCursor(7, 0);
      lcd.print(b);

}

//=================================================
//  MULTI-CLICK:  One Button, Multiple Events

// Button timing variables
int debounce = 20;          // ms debounce period to prevent flickering when pressing or releasing the button
int DCgap = 420;            // max ms between clicks for a double click event
// Button variables
boolean buttonVal = HIGH;   // value read from button
boolean buttonLast = HIGH;  // buffered value of the button's previous state
boolean DCwaiting = false;  // whether we're waiting for a double click (down)
boolean DConUp = false;     // whether to register a double click on next release, or whether to wait and click
boolean singleOK = true;    // whether it's OK to do a single click
long downTime = -1;         // time the button was pressed down
long upTime = -1;           // time the button was released

int checkButton() {   
   int event = 0;
   buttonVal = digitalRead(buttonPin);
   // Button pressed down
   if (buttonVal == LOW &amp;&amp; buttonLast == HIGH &amp;&amp; (millis() - upTime) &gt; debounce)
   {
       downTime = millis();
       singleOK = true;
       if ((millis()-upTime) &lt; DCgap &amp;&amp; DConUp == false &amp;&amp; DCwaiting == true)  DConUp = true;
       else  DConUp = false;
       DCwaiting = false;
   }
   // Button released
   else if (buttonVal == HIGH &amp;&amp; buttonLast == LOW &amp;&amp; (millis() - downTime) &gt; debounce)
   {       
           upTime = millis();
           if (DConUp == false) DCwaiting = true;
           else
           {
               event = 2;
               DConUp = false;
               DCwaiting = false;
               singleOK = false;
           }
   }
   // Test for normal click event: DCgap expired
   if ( buttonVal == HIGH &amp;&amp; (millis()-upTime) &gt;= DCgap &amp;&amp; DCwaiting == true &amp;&amp; DConUp == false &amp;&amp; singleOK == true &amp;&amp; event != 2)
   {
       event = 1;
       DCwaiting = false;
   }

   buttonLast = buttonVal;
   return event;
}


Thank you! I would really appreciate it!
What you likely need is a state machine. The behavior of the actions depends on the state the program is currently in.

In your case, the state machine might look like this:



What does it mean?


black circle: this is where the system powers on
rectangle: a state
arrow: a transition from one state to another
green text: action


For the problematic double click action, you can see:


it changes the state from "set size" to "speed"
in all other cases, it does not change the state (actually it changes the state to the same state)


I always recommend drawing the state machine before implementing it. It makes mistakes much more obvious.

There are several ways to implement it. The easiest one being a switch/case. More advanced implementations may use object orientation. When using switch/case, I prefer to have one method per state, like so:

void loop()
{
    switch(state):
        case setsize:
             setsize();
             break;
        case speed:
             speed();
             break;
        ...
}


If you know about function pointers, it gets even easier:

enum State {
  setsize = 0,
  speed,
  clock,
  temperature
};

State state;

void setup() {
  state = State::setsize;
}


typedef void (* functionPointer) ();
functionPointer process[] = {do_setsize, do_speed, do_clock, do_temperature};
void loop() {
  process[state]();
}

void do_setsize()
{
  state = State::speed;
}
void do_speed()
{
  state = State::clock;
}
void do_temperature()
{
  state = State::speed;
}
void do_clock()
{
  state = State::temperature;
}