Detener cuenta atrás

Buenas a todos, tengo creada una cuenta atrás con un bucle, que cada vez que se repite, decrementa el valor de la variable "i" para que el tiempo de espera entre pitidos sea cada vez mas breve.
Tengo un keypad conectado, quiero que cuando se pulse alguna tecla, se detenga la cuenta atras, parece fácil , pero cuando coincide que pulso la tecla y el bucle está dentro del tiempo de espera entre pitidos, no capta que he pulsado una tecla, ya que en ese momento se esta pausando el sonido cierto tiempo, aquí os dejo el código para que podáis verlo mejor, un saludo y gracias de antemano.

void cuenta_atras(){ 
    int i = 400;
    while(i > 0 && tecla == NO_KEY){
      tone(speakerPin, tones[9], i);
      tecla = teclado.getKey();
      i = i - 25;
  }
  noTone(speakerPin);
}

si quieres captar un evento independientemente del sketch puedes usar una interrupcion:
http://www.arduino.cc/en/Reference/AttachInterrupt

Y donde pones la interrupción josé. El keypad es como mínimo 3x3 o 4x4 de modo que son 3/4 entradas que vigilar. Claro que se puede pero hay que usar o diodos para bloquear caminos o alguna compuerta lógica.
Lo que se me ocurre es hacer una interrupción por timer a 1mseg por ejemplo y barrer el teclado, si hay tecla presionada levantas un flag y detenies la cuenta atrás.

// defino dato como volatile bool

volatile bool dato;

// resto del programa

bool keypad() {
    // scaneo las teclas y devuelvo el dato presionado y 
    // no recuerdo la librería keypad pero creo que ya lo hace

    // levanto un flag.
    if(teclaPresionada)
      dato = 1;  // 1 para teclaPresionada
    else
     dato = 0;    // 0 para TeclaNoPresionada
   
   return dato;
}

y con este flag

void cuenta_atras(){ 
    int i = 400;
    while(i > 0 && !dato){
      tone(speakerPin, tones[9], i);
      i = i - 25;
  }
  noTone(speakerPin);
}

¿Y qué tal recurriendo a nuestro viejo amigo millis?

Algo así más o menos:

void cuenta_atras(){
	int i = 400;
	while(i > 0 && tecla == NO_KEY){
		tone(speakerPin, tones[9]);
		unsigned start=millis();
		while (millis()-start < i) {
			tecla=teclado.getKey();
			if (tecla != NO_KEY) break;
		}
		i = i - 25;
	}
	noTone(speakerPin);
}

Serafín tramposo!!! lo mismo que dije yo usando millis(), jajajaja

Crei que solo se podia hacer por interrupcion porque me parecio leer en algun sitio que la funcion tone() era bloqueante ,lo cual no es correcto.....

La función tone es bloqueante, supongo, si se usa el tercer parámetro (duración).
Surbyte, lo único es que en lugar de crear mi propia función millis opté por usar la que ya viene implementada :smiling_imp:

Todo bien Serafín!!! no pasa nada y de hecho es mas facil de implementar tu solución que la mía aunque ambas conduzcan al mismo resultado.

Gracias a todos por las repuestas, al final he utilizado la función millis y me ha ido bien.

De todos modos voy a darle tmb la razón a josé. Se puede hacer lo que josé dice pero requiere de algun trabajo.
Veamos: Supongamos un teclado 4x4 asi no tengo alternativa. 4 filas son barridas como salidas y 4 como entradas. Esas 4 entradas deberían activar la interrupción que sugiere josé.
La forma fácil es usando 4 diodos con sus anodos conectados a cada una las columnas supongamos que son las que coinciden con las entradas del arduino que ya mencione y los cátodos a la interrupción. Entonces como esperamos justamente el momento en que barremos filas poniendo un HIGH el diodo conduce hacia la IRQ y la pone en flanco de subida y tenemos el evento.

Facilmente como sugirió josé se puede entonces con el agregado de 4 diodos y una Interrupcion al pin 2 o 3 si usamos un UNO, detectar la tecla presionada.