Freeze arduino mega

Estimados,
Les comento que estoy empezando con arduino y haciendo unos ejercicios de interrupción noto que la placa se cuelga. EL programa es sencillo. Tiene dos estados, en el primero el programa se inicializa en un blink de 10ms al ir apretando la interrupción va duplicando el tiempo de blink. LLegado a un limite se pasa a otro estado que va dividiendo por 2 el tiempo del blink. El problema es que en un momento al ver la el puerto serie queda freezado en 0 el tiempo. Puede ser que la placa este dañada?

#define ESTADOSUBE 1
#define ESTADOBAJA 2
int estado=ESTADOSUBE;
int pulsador=digitalPinToInterrupt(3);
int tiempo=10;
int led=13;
int anterior=0;

void setup() 
{
  pinMode(led,OUTPUT);
  digitalWrite(led,LOW);
  Serial.begin(9600);
  attachInterrupt(pulsador, handler_tiempo,FALLING);  
}
void loop(){
  switch(estado)
  {
    case ESTADOSUBE:
    {
      if(tiempo>2500)
      {
        estado=ESTADOBAJA;
        }
        prendeapaga();
        Serial.print("ESTADOSUBE");
        Serial.print("\n");
        Serial.print(tiempo);
        Serial.print("\n");
        
      }
      break;
    case ESTADOBAJA:
    {
      if(tiempo<20)
      {
        estado=ESTADOSUBE;
        }
        prendeapaga();
        Serial.print("ESTADOBAJA");
        Serial.print("\n");
        Serial.print(tiempo);
        Serial.print("\n");
       
      }
       break;
    }
  }

void handler_tiempo(){
  if(millis()-anterior>200)
  {
  if(estado==ESTADOBAJA){
    tiempo=tiempo/2;
    }
  else if(estado==ESTADOSUBE){
    tiempo=tiempo*2;
    }
  }
  anterior=millis();
}

void prendeapaga()
{
  digitalWrite(led,HIGH);
  delay(tiempo);
  digitalWrite(led,LOW);
  delay(tiempo);  
  }

Hi,
Posiblemente se debe a que estas usando delay cuando contestas un interrupt. El interrupt usa el timer de los miliseconds. Esto puedde traer conflictos. Si buscas en el arduino topics encuetra esta contestacion. Creo que debes de evitar usar delays cuando respondes a un interrupt.

"The delay() function uses the milliseconds interrupt. Inside an interrupt handler, all other interrupts are suspended so the millis() counter doesn't count and delay() never ends. delayMicroseconds() will work in the interrupt routine "

Además de lo que menciona @tauro, estas usando enteros para guardar el valor de millis() por lo que posiblemente se está desbordando, debes usar unsigned long, es decir, esto:

int anterior=0;

debe quedar así

unsigned long anterior=0;

ademas, ¿para que usar una interrupción para algo tan lento como un botón?.
Debes dejar el uso de interrupciones solo para eventos que ocurren muy rápido y que puedan llegar a perderse mientras se ejecuta el loop. Es sumamente difícil que pierdas un evento donde se pulsa un botón, a menos claro, que uses delay en tu programa

Mira, le hice uno pequeños cambios a tu código, quitando la interrupción, creo que funciona como deseas

#define ESTADOSUBE 1
#define ESTADOBAJA 2
byte estado= ESTADOBAJA;
const byte pulsador=3;
int tiempo=10;
const byte led=13;
unsigned long anterior=0;
unsigned long db;
bool anteriorPulsador;


void setup() 
{
  pinMode(led,OUTPUT);
  digitalWrite(led,LOW);
  Serial.begin(9600);
 pinMode(pulsador, INPUT_PULLUP);  
}

void loop(){
  
bool estadoPulsador=digitalRead(pulsador);

  switch(estado)
  {

    case ESTADOSUBE:
    
      if(tiempo>2500)
        {
        estado=ESTADOBAJA;
        }
     prendeapaga();
       break;

    case ESTADOBAJA:
    
      if(tiempo<20)
      {
        estado=ESTADOSUBE;
        }
        prendeapaga();
        
       break;
    }
  


if(!estadoPulsador && anteriorPulsador && millis()- db >= 100UL){
    
     if(estado==ESTADOBAJA){
         tiempo=tiempo/2;
        Serial.println("ESTADOSUBE");
        Serial.println(tiempo);       
      }

     else if(estado==ESTADOSUBE){
       tiempo=tiempo*2;
       Serial.println("ESTADOBAJA");
       Serial.println(tiempo);
     
      }

     db=millis();
     }
     
  anteriorPulsador = estadoPulsador;
  }
   
void prendeapaga(){

   if(millis()-anterior >= tiempo){
       
digitalWrite(led, !digitalRead(led));
       anterior=millis();
   }
}

Y por cierto...

El problema es que en un momento al ver la el puerto serie queda freezado en 0 el tiempo.

no encontré por ningún diccionario la palabra freezado

P.D. en el código uso el botón como PULL_UP, su usas PULL_DOWN solo cambia las sentencias en el if del boton

Les comento que cambie en mi código la definición del tiempo. En vez de ser entero lo defini como "unsigned long" como que comentaron en la respuesta. El programa funciona y no se tilda o queda "freezado" (spanglish tal vez mal usado de congelar).

PD: Les comento que soy estudiante de ingeniria mecanica y jamás programe nada, por lo que el proyecto es solo un ejercicio a modo didáctico que nos dieron en la facultad para usar interrupciones y máquinas de estado.

Muchas gracias por la ayuda.

Saludos

#define ESTADOSUBE 1
#define ESTADOBAJA 2
int estado=ESTADOSUBE;
int pulsador=digitalPinToInterrupt(3);
int tiempo=10;
int led=53;
unsigned long anterior=0; // PARECE QUE TRAE PROBLEMAS GUARDAR EL TIEMPO COMO ENTERO

void setup() 
{
  pinMode(led,OUTPUT);
  digitalWrite(led,LOW);
  Serial.begin(9600);
  attachInterrupt(pulsador, handler_tiempo,FALLING);  
}
void loop(){
  switch(estado)
  {
    case ESTADOSUBE:
    {
      if(tiempo>2500)
      {
        estado=ESTADOBAJA;
        }
        prendeapaga();
        Serial.print("ESTADOSUBE");
        Serial.print("\n");
        Serial.print(tiempo);
        Serial.print("\n");
        
      }
      break;
    case ESTADOBAJA:
    {
      if(tiempo<20)
      {
        estado=ESTADOSUBE;
        }
        prendeapaga();
        Serial.print("ESTADOBAJA");
        Serial.print("\n");
        Serial.print(tiempo);
        Serial.print("\n");
       
      }
       break;
    }
  }

void handler_tiempo(){
  if(millis()-anterior>200)
  {
  if(estado==ESTADOBAJA){
    tiempo=tiempo/2;
    }
  else if(estado==ESTADOSUBE){
    tiempo=tiempo*2;
    }
  }
  anterior=millis();
}

void prendeapaga()
{
  digitalWrite(led,HIGH);
  delay(tiempo);
  digitalWrite(led,LOW);
  delay(tiempo);  
  }

El delay no tiene nada que ver, de hecho muchos usan interrupciones y delay en sus códigos y accionan pulsadores con interrupciones.

La falla estaba en la definición de las variables int que bien indico RIG por unsigned long.

MODERADOR: Hilo movido a Sofware.