Code after "if" statement executed even condition is not met

Hello all
I'm implementing timout funcion for pressed button. Not sure all code is required but variable "lastFire" contains value of "millis()" the time button was pressed last time. Variable "prevFire" contains value of "millis()" previous button press. In main loop I have implemented this simple condition

void loop() {

  if (SetMode != 0) {
    currTime = millis();
    if ((currTime - lastFire) > 5000) {
      Serial.println("Button timeout");
      Serial.println(currTime);
      Serial.println(lastFire);
      Serial.println(prevFire);
      Serial.println(currTime - lastFire);
      SetMode = 0;
    }
  }
  
}

which should change variable "SetMode" to zero if the time from last button press is more than 5 seconds. I had to add "Serial.println" statements there to investigate because this code gets randomly executed after some of button presses.

Console Monitor shows results like

Button timeout
62537
57536
55920
5001
Button timeout
86329
86329
85724
0

The first "Button timeout" is correct after 5 seconds of "idle" but the second one happens after random presses of the buttons. You can see the "previous" press happened 605ms before the last press of button.

Question to me is how it's possible that it executes the code after the "if" statement if the condition is not met (0 is not greater than 5000)
I had an idea that the "lastFire" variable gets changed after the "if" statement is evaluated but in such case it should be the "prevFire" value to be used for evaluation and still same - condition was not met (
605 is not greater than 5000)

Please any idea?

If necessary I would provide whole code including interrupt driven buttons (touching only "lastFire" variable) + timer driven LED blinking (not touching any of these variables)

buttons_with_interrupt_leds_with_timer.txt (5.94 KB)

I don't know what Arduino you have.
I don't know if you have any large arrays.
I don't know how currTime is declared.
I don't know how lastFire is declared.

The problem is likely to be in the code that you have not shown. Please share it properly by autoformatting it and posting it inline with code tags.

You have not saved your lastfire to the current millis after the event so looping round the if condition will always be true

vaj4088:
I don't know what Arduino you have.
I don't know if you have any large arrays.
I don't know how currTime is declared.
I don't know how lastFire is declared.

The problem is likely to be in the code that you have not shown. Please share it properly by autoformatting it and posting it inline with code tags.

Hello,
whole code is attached to the original post.
I'm using Arduino Uno.
One simple array of four interger values.
Variables to hold "millis()" are declared as unsigned long integers.

Thank you for reviewing the code and sharing any idea what to check there. I'm out of ideas now.

// 4 buttons controled by solution taken from https://create.arduino.cc/projecthub/Svizel_pritula/10-buttons-using-1-interrupt-2bd1f8
// defines Common and Buttons pins
const int commonPin = 2;
const int buttonPins[] = {11,10,9,8};

// Common anode RGB LED connected over resitors to pins 3, 4 and 5 (red, green, blue)
// volatile variables defined to be used in Timer interrupt function
volatile uint8_t pinLED = 3; // default first (RED) LED
volatile uint8_t timer_flip = 0;

// global variables to be used in the button interrupt function
unsigned long currTime;     // curent time to compare
unsigned long lastFire = 0; // time of last button press
unsigned long prevFire = 0; // time of previous buttin press

byte PButton = 0; // Indicates whether button was pressed (>0) and number of pressed button (1..4)

byte SetMode = 0; // Indicates whether we are in Setting Mode and which "level"
byte PrevMode;    // Used for testing whether the Setting Mode level has changed or not


void setup() {

  interrupts(); 

  // Prepare TIMER 1 for interrupt frequency 10 Hz (LED blinking)
  cli(); // stop interrupts
  TCCR1A = 0; // set entire TCCR1A register to 0
  TCCR1B = 0; // same for TCCR1B
  TCNT1 = 0; // initialize counter value to 0
  // set compare match register for 10 Hz increments
  OCR1A = 1562; // 200 millisecond cycle (100ms down, 100ms up)
  // turn on CTC mode
  TCCR1B |= (1 << WGM12);
  // no clock selected at the moment. It's done during Mode Selection (red, green, blue)
  // enable timer compare interrupt
  TIMSK1 |= (1 << OCIE1A);
  sei(); // allow interrupts
  
  configureCommon(); // Setup pins for interrupt from buttons
  attachInterrupt(digitalPinToInterrupt(commonPin), pressInterrupt, FALLING); // enter interrupt function during falling on Common pin

  Serial.begin(115200);

  pinMode(3, OUTPUT);    // sets the digital pin 3 as output
  digitalWrite(3, HIGH);
  pinMode(4, OUTPUT);
  digitalWrite(4, HIGH);
  pinMode(5, OUTPUT);
  digitalWrite(5, HIGH);
}

ISR(TIMER1_COMPA_vect){
   if (timer_flip == 0) {
     timer_flip = 1;
     digitalWrite(pinLED, LOW);
   } else {
     timer_flip = 0;
     digitalWrite(pinLED, HIGH);
   }
}

void pressInterrupt() { // ISR
//  Serial.println("interrupt");
  if (millis() - lastFire < 150) { // Debounce
//    Serial.println("debounce");
    return;
  }
  prevFire = lastFire;
  lastFire = millis();

  configureDistinct(); // Setup pins for testing individual buttons

  for (int i = 0; i < sizeof(buttonPins) / sizeof(int); i++) { // Test each button for press
    if (!digitalRead(buttonPins[i])) {
      PButton = i + 1; // pressed button is detected in array keys 0..3 ie. translated to button numbers 1..4
    }
  }
  if (PButton != 0) {
    PrevMode = SetMode;
    if (SetMode > 0) {
      switch (PButton) {
        case 1: // if we are already in Set Mode and button 1 is pressed then increment Set Mode level (red->green->blue->red...)
          SetMode++;
          if (SetMode > 3) {
            SetMode = 1; // Set Mode 1 will blink Red LED, 2 will blink Green LED and 3 will blink Blue LED
          }
          break;
        case 4:
          // if LED is blinking the Timer (bliking) is stopped and LED is lighting
          TCCR1B = TCCR1B & B11111000; // stop clock
          TCNT1 = 0; // initialize counter value to 0
          digitalWrite(pinLED, LOW);
          break;
      }
    } else if (PButton == 1) {
      SetMode = 1; // enter Set Mode only if button 1 is pressed
    }
    // If Setting Mode level has changed do the action
    if (PrevMode != SetMode) {
      switch (SetMode) {
        case 1: // Red LED blinking
          // stop blinking of Blue LED
          TCCR1B = TCCR1B & 0xf8; // stop Timer1 (clear bits CS10-CS12)
          TCNT1 = 0;              // initialize counter value to 0          
          digitalWrite(5, HIGH);  // switch off Blue LED
          pinLED = 3;             // set blinking on pin 3 (Red LED)
          TCCR1B |= (1 << CS12) | (0 << CS11) | (1 << CS10); // start Timer1
          break;
        case 2: // Green LED blinking
          TCCR1B = TCCR1B & 0xf8;
          TCNT1 = 0;
          digitalWrite(3, HIGH);  // switch off Red LED
          pinLED = 4;             // set blinking on pin 4 (Green LED)
          TCCR1B |= (1 << CS12) | (0 << CS11) | (1 << CS10);
          break;
        case 3: // Blue LED blinking
          TCCR1B = TCCR1B & 0xf8;
          TCNT1 = 0;
          digitalWrite(4, HIGH);  // switch off Green LED
          pinLED = 5;             // set blinking on pin 4 (Blue LED)
          TCCR1B |= (1 << CS12) | (0 << CS11) | (1 << CS10);
          break;
      }
    }
  }

  PButton = 0; // Pressed button reset to 0 (nothing pressed)

  configureCommon(); // Return to original state ie. waiting for intrrupt from any button

}

// Interrupt waits for Common pin is falling to LOW level from any Button pin
void configureCommon() {
  pinMode(commonPin, INPUT_PULLUP);

  for (int i = 0; i < sizeof(buttonPins) / sizeof(int); i++) {
    pinMode(buttonPins[i], OUTPUT);
    digitalWrite(buttonPins[i], LOW);
  }
}

// All Button pins are input+pullup and one or more of them are hold on LOW level from the Common pin
void configureDistinct() {
  pinMode(commonPin, OUTPUT);
  digitalWrite(commonPin, LOW);

  for (int i = 0; i < sizeof(buttonPins) / sizeof(int); i++) {
    pinMode(buttonPins[i], INPUT_PULLUP);
  }
}

void loop() {

  if (SetMode != 0) {    // if Set Mode level is 1..3
    currTime = millis(); // take current time
    if ((currTime - lastFire) > 5000) { // if more than 5 seconds since last button press
      Serial.println("Button timeout");
      Serial.println(currTime);
      Serial.println(lastFire);
      Serial.println(prevFire);
      Serial.println(currTime - lastFire);
      TCCR1B = TCCR1B & 0xf8; // stop Timer1
      TCNT1 = 0;              // initialize counter value to 0
      SetMode = 0;            // escape from any Set Mode
      digitalWrite(3, HIGH);  // and switch off all LEDs
      digitalWrite(4, HIGH);
      digitalWrite(5, HIGH);
    }
  }
  
}