Search code examples
arduinointerruptarduino-esp8266

How do I tell the code in Arduino if I press a button twice with interrupts?


I am using an esp32 in Arduino. What I want to do is: If I press the button once, it should Serial.print "I was pressed once" If I press the button twice, it should Serial.print "I was pressed twice"

I am using the attachInterrupt() function, but I don't know how to tell the code how to read it when I press the button twice. What my code also does is turning on a LED when it senses I pressed the button.

Here is what I have achieved so far :

int boton = 0; 
int led = 5;
int valorBoton; //value of the button, if it off(1) or on (0) 
unsigned int count = 0 ; //counter

void setup() {
    Serial.begin(115200); //velocity
    pinMode(led, OUTPUT); //OUTPUT LED
    pinMode(boton, INPUT); //INFUPT BUTTON
    digitalWrite(led, LOW); //THE LED IS LOW INITIALLY
    attachInterrupt(digitalPinToInterrupt(0),button1,RISING);
}

void loop() {
    count++; 
    Serial.println(count); //printing the counter
    delay(1000);
}

void button1(){ //the function button1 is a parameter of attachInterrupt
    digitalWrite(led, HIGH); //when it is pressed, led is on 
    Serial.println("I was pressed");
    count = 0; // if I was pressed, then the count starts from cero all over again 
}

I expect to print Serial.println("I was pressed twice") when I press the button


Solution

  • It can be implemented in many ways. One way is to create an interrupt function to just increase a counter, then in loop function check whether the user pressed the function twice (by counting delay between presses) then decide if it is one or two presses.

    Remember to change max_delay for max wait time between two press.

    // maximum allowed delay between two presses
    const int max_delay = 500;
    
    int counter = 0;
    bool done = false;
    
    const byte ledPin = 13;
    const byte buttonPin = 0;
    unsigned long first_pressed_millis = 0;
    
    void counter_incr()
    {
        counter++;
    }
    
    void setup()
    {
        Serial.begin(115200);
        pinMode(ledPin, OUTPUT);          //OUTPUT LED
        pinMode(buttonPin, INPUT_PULLUP); //INPUT BUTTON as pullup
        digitalWrite(ledPin, LOW);        //THE LED IS LOW INITIALLY
        attachInterrupt(digitalPinToInterrupt(buttonPin), counter_incr, RISING);
    }
    
    void loop()
    {
        if (counter > 0)
        {
            first_pressed_millis = millis();
            // wait for user to press the button again
            while (millis() - first_pressed_millis < max_delay)
            {
                // if button pressed again
                if (counter > 1)
                {
                    Serial.println("Button pressed twice!");
                    done = true;
                    break;
                }
            }
            // if on timeout no button pressed it means the button pressed only one time
            if (!done)
                Serial.println("Button pressed once!");
            counter = 0;
        }
    }