Unable to register fast clicks while using interrupts

const int green = D3;
const int yellow = D4;
const int red = D5;
const int ledPin =  D7;     
volatile byte state = LOW;
unsigned long btime = 0;
//Variables
int flag = 0;
unsigned long now = millis();
int click = 0;
void setup() {
    Serial.begin(9600);
  //Input or output?
    pinMode(ledPin, OUTPUT);      
  pinMode(green, INPUT_PULLUP);
  pinMode(yellow, INPUT_PULLUP);
  pinMode(red, INPUT_PULLUP);
  digitalWrite(ledPin,LOW);
 attachInterrupt(green, blink, FALLING);
 attachInterrupt(yellow, blink, FALLING);
 attachInterrupt(red, blink, FALLING);
  
}

void loop(){
        // btime = millis();
        Serial.println(flag);
        
        // Serial.println(digitalRead(green));
        // Serial.println(digitalRead(yellow));
        // Serial.println(digitalRead(red));
        Serial.println("inloop");
        digitalWrite(ledPin,LOW);
    
//   digitalWrite(ledPin, state);
    if(flag == 1){
        if ((millis()-now)>2000){
            buttonClick();
            Serial.println("inneriF");
        }
        else{
            
            flag=0;
            now=millis();
            Serial.println(now);
            Serial.println("innerelse");        
        
        }
    }
    
    
  
  delay(400);
  
}
void blink(){
    
    
    flag = 1;
    Serial.println("inblink");
}
void buttonClick(){
    Serial.println("insideButtonClick");
    
    if(pinReadFast(green) == LOW){
        Serial.println("inButtonClick");  // only for serial print can be commented   
        delay(5); // delay necessary for letting noise settle, hoping noise is smaller than 20 ms
        if(digitalRead(green) == LOW){
            Serial.println("green");
            now = millis();
            digitalWrite(ledPin,HIGH);
            delay(100);  // as per current understanding, can be removed 
        }
        
    }
    else if(digitalRead(yellow) == LOW){
        Serial.println("inButtonClick");  // only for serial print can be commented   
        delay(5); // delay necessary for letting noise settle, hoping noise is smaller than 20 ms
        if(digitalRead(yellow) == LOW){
            Serial.println("yellow     ");
            now = millis();
            digitalWrite(ledPin,HIGH);
            delay(100);  // as per current understanding, can be removed 
        }
        
    }
    else if(digitalRead(red) == LOW){
        Serial.println("inButtonClick");  // only for serial print can be commented   
        delay(5); // delay necessary for letting noise settle, hoping noise is smaller than 20 ms
        if(digitalRead(red) == LOW){
            Serial.println("red");
            now = millis();
            digitalWrite(ledPin,HIGH);
            delay(100);  // as per current understanding, can be removed 
        }
        
    }
    
    flag = 0;
 
}

///////////////////////
I am trying to use 3 switches to blink an led using interrupts and the code works fine for the long clicks but whenever a click is
small or if the button is released too fast it doesn’t register a click,
the interrupt fires and the “blink” function executed and by the time it reaches the “buttonClick” function the user click
is done so the “if” statement inside the buttonClick does not execute and the
the function fails.

So why don’t you register which button was pressed in the interrupt? I.e., use pinReadFast() on green, yellow, red to determine which pin is low and store that instead of ‘flag’. Then buttonClick() no longer needs to do the decoding.

Additionally, you may want to debounce the switch a bit.

Btw, for future, try using the ‘preformatted text’ function of this forum to format your code, is easier to read for us.

4 Likes

What joost said, either call pinReadFast from your interrupt handler, or have three separate interrupt handlers, one for red, one for yellow, and one for green, and have a separate flag for red, yellow, and green.

Also, yes, you will need to debounce. And you should not call Serial.print from an interrupt handler, it’s not safe. It works most of the time, but if your interrupt arrives while in another Serial.print bad things can happen.

4 Likes