user53592: I wrote code that tracks the duration of a button click. It has bounce protection and frequent clicks. (Freeze)
My code:
bool freeze_time, btn_read, debounce;
unsigned int freeze_timer, btn_timer;

#define BTN 6

void setup() {
  Serial.begin(9600);
  pinMode(BTN, INPUT);
}

void loop() {
  /* Freeze Timer Protection */
  if(freeze_time) {
    if((millis() - freeze_timer) >= 2500) {
      freeze_time = false;
      btn_read = false;
    }
  }
  /* Read Button State */
  if(digitalRead(BTN) == HIGH) {
    if(!btn_read) {
      btn_timer = millis();
      debounce = true;
      btn_read = true;
    }
  }
  /* BTN Read Process */  
  if(btn_read) {
    /* Debounce Protection */
    if(debounce) {
      if((millis() - btn_timer) >= 1000) {
        if(digitalRead(BTN) == HIGH) {
          Serial.println("Debounce ok.");
          btn_timer = millis();
          debounce = false;
        } else {
          Serial.println("Debounce fail.");
          freeze_time = true;
          debounce = false;
        }
      }
    }
    /* BTN Read Process */ 
    else if(!freeze_time) {
      if((millis() - btn_timer) >= 1500) {
        if(digitalRead(BTN) == HIGH) {
          Serial.println("Ok. Button Pressed > 1500ms");
          freeze_timer = millis();
          freeze_time = true;
        } else {
          Serial.println("Ok. Button Pressed < 1500ms");
          freeze_timer = millis();
          freeze_time = true;
        }
      }
    }
  }  
}

I checked it on real Arduino UNO and Tinkercad simulator. Initially, everything works well, but if I press the button indefinitely, the system will fail (every time you press the serial port, messages appear as if all flags were lost and the timers did not work. I filmed the behavior:
1) Initially: http://recordit.co/lVlR1z1CUq
2) System is broken: http://recordit.co/lhvzM100DI
What could be the problem and how to make it fault tolerant?

user54326: Why did the timers stop working?
The main issue seems to be that freeze_timer and btn_timer are of type unsigned int, while millis, as stated in its documentation, returns an unsigned long.
As you may know, unsigned int is normally be able to hold a much smaller range of values than unsigned long. In the case of whatever compiler Tinkercad uses for the Arduino Uno, I checked and unsigned int can hold values from 0 to 65535, while unsigned long can hold values from 0 to 4294967295. Whenever you save an unsigned long into an unsigned int, it will be reduced modulo 65536.
This means that once you pass 65.536 seconds checks such as the (millis() - freeze_timer) >= 2500 will always be true (at least until millis wraps back around after 4294967.296 seconds - around 50 days).
If you would like to learn a bit more about integer conversions, I think this Stack Overflow question covers it.
The simplest solution is, of course, to declare freeze_timer and btn_timer to be of the appropriate type, unsigned long.
Use simpler code
All of the above being said, like Gerben said, the code seems overly complex.
There also seem to be other issues. For instance, I would expect the debounce behavior should not ignore presses that last less than 1 second. Like Gerben said, 10 ms should be enough to discard any bounces.
Furthermore, I think it would be more appropriate to not even discard presses that last less than 10 ms. I would say the debouncer should trigger "press" regardless of whether the press lasted less than 10 ms. It's role should just be to ignore multiple presses within that 10 ms window (although to be fair, ignoring short presses is not a terribly big issue).
Although one could make some guesses, to really help you with this, we would need a description of your intended behavior. What is the purpose of freezing? Is it intended to allow multiple presses to be triggered when you never release the button (or maybe you should wait until release before triggering one again)?

53592: <p>I wrote code that tracks the duration of a button click. It has bounce protection and frequent clicks. (Freeze)</p>

<p>My code:</p>

<pre><code>bool freeze_time, btn_read, debounce;
unsigned int freeze_timer, btn_timer;

#define BTN 6

void setup() {
  Serial.begin(9600);
  pinMode(BTN, INPUT);
}

void loop() {
  /* Freeze Timer Protection */
  if(freeze_time) {
    if((millis() - freeze_timer) &gt;= 2500) {
      freeze_time = false;
      btn_read = false;
    }
  }
  /* Read Button State */
  if(digitalRead(BTN) == HIGH) {
    if(!btn_read) {
      btn_timer = millis();
      debounce = true;
      btn_read = true;
    }
  }
  /* BTN Read Process */  
  if(btn_read) {
    /* Debounce Protection */
    if(debounce) {
      if((millis() - btn_timer) &gt;= 1000) {
        if(digitalRead(BTN) == HIGH) {
          Serial.println("Debounce ok.");
          btn_timer = millis();
          debounce = false;
        } else {
          Serial.println("Debounce fail.");
          freeze_time = true;
          debounce = false;
        }
      }
    }
    /* BTN Read Process */ 
    else if(!freeze_time) {
      if((millis() - btn_timer) &gt;= 1500) {
        if(digitalRead(BTN) == HIGH) {
          Serial.println("Ok. Button Pressed &gt; 1500ms");
          freeze_timer = millis();
          freeze_time = true;
        } else {
          Serial.println("Ok. Button Pressed &lt; 1500ms");
          freeze_timer = millis();
          freeze_time = true;
        }
      }
    }
  }  
}
</code></pre>

<p>I checked it on real Arduino UNO and Tinkercad simulator. Initially, everything works well, but if I press the button indefinitely, the system will fail (every time you press the serial port, messages appear as if all flags were lost and the timers did not work. I filmed the behavior:</p>

<p>1) Initially: <a href="http://recordit.co/lVlR1z1CUq" rel="nofollow noreferrer">http://recordit.co/lVlR1z1CUq</a>
2) System is broken: <a href="http://recordit.co/lhvzM100DI" rel="nofollow noreferrer">http://recordit.co/lhvzM100DI</a></p>

<p>What could be the problem and how to make it fault tolerant?</p>
 54326: <h1>Why did the timers stop working?</h1>

<p>The main issue seems to be that <code>freeze_timer</code> and <code>btn_timer</code> are of type <code>unsigned int</code>, while <code>millis</code>, as stated in its <a href="https://www.arduino.cc/reference/en/language/functions/time/millis/" rel="nofollow noreferrer">documentation</a>, returns an <code>unsigned long</code>.</p>

<p>As you may know, <code>unsigned int</code> is normally be able to hold a much smaller range of values than <code>unsigned long</code>. In the case of whatever compiler Tinkercad uses for the Arduino Uno, I checked and <code>unsigned int</code> can hold values from 0 to 65535, while <code>unsigned long</code> can hold values from 0 to 4294967295. Whenever you save an <code>unsigned long</code> into an <code>unsigned int</code>, it will be reduced modulo 65536.</p>

<p>This means that once you pass 65.536 seconds checks such as the <code>(millis() - freeze_timer) &gt;= 2500</code> will always be true (at least until <code>millis</code> wraps back around after 4294967.296 seconds - around 50 days).</p>

<p>If you would like to learn a bit more about integer conversions, I think <a href="https://stackoverflow.com/questions/27889213/c-integer-downcast">this Stack Overflow question</a> covers it.</p>

<p>The simplest solution is, of course, to declare <code>freeze_timer</code> and <code>btn_timer</code> to be of the appropriate type, <code>unsigned long</code>.</p>

<h1>Use simpler code</h1>

<p>All of the above being said, like <a href="https://arduino.stackexchange.com/questions/63008/code-test-the-duration-press-of-the-button#comment135530_63008">Gerben</a> said, the code seems overly complex.</p>

<p>There also seem to be other issues. For instance, I would expect the debounce behavior should not ignore presses that last less than 1 second. Like Gerben said, 10 ms should be enough to discard any bounces.</p>

<p>Furthermore, I think it would be more appropriate to not even discard presses that last less than 10 ms. I would say the debouncer should trigger "press" regardless of whether the press lasted less than 10 ms. It's role should just be to ignore <em>multiple</em> presses within that 10 ms window (although to be fair, ignoring short presses is not a terribly big issue).</p>

<p>Although one could make some guesses, to really help you with this, we would need a description of your intended behavior. What is the purpose of freezing? Is it intended to allow multiple presses to be triggered when you never release the button (or maybe you should wait until release before triggering one again)?</p>
