nuevo proyecto para una especie de contador regresivo

buenas compañeros....os comento mi proyecto a ver si me guiais por donde es mejor hacerlo...
la idea es un contador regresivo de 30 segundos. el cual al finalizar suena un buzzer(este contador seria en bucle)el proyecto llevaria un pulsador el cual al pulsar anularia el anterior contador durante x tiempo(por ejemplo 1 min)a las 3 pulsaciones sonaria una sirena la cual teminaria con todo el proyecto.
y para terminar un segundo pulsador el cual reinicia todo el rpograma para empezar de nuevo..
no quiero que me hagan el sketch ni nada parecido...solo guiarme sobre que funciones utilizar...ya que por mucho que he leido no me aclara si usar millis, delay o por donde sacarlo
pd: iria sin lcd el proyecto
gracias a todos

Siempre millis(), el delay es para cosas muy puntuales. Para los dos pulsadores te conviene declararlos en pullup `para simplificar conexionado. Podés hacer en papel un diagrama de flujo con las funciones que necesitás que haga el contador y luego eso lo traducis en lenguaje C++. Es relativamente sencillo. Intentalo y si tenés dudas consultá puntualmente.

millis() cuenta hacia arriba porque son los milisegundos desde que Arduino se energizó.
Guardar su valor en una variable te permite hacer cualquier cosa.

En tu caso que quieres un contador regresivo (descendente) ya sabes el valor que quieres, entonces supongamos fuera 10 seg = 10000 mseg.

ahora imagina que todo depende de una tecla que incia el proceso.
tocas la tecla y cargas el valor de millis() en una variable, supongamos que esa variable toma el valor de 20000 solo por complicar las cosas.

Asi que cuando millis() llege a 20000 + 10000 se cumplirán tus 10000 mseg no?

Si a cada momento desde que presionaste el pulsador tu presentas por Serial.print(millis()-valorinicial) veras 0... hasta llegar a 10000

Pero a los fines de presentación lo quieres al revés.. o sea 10000 hasta 0.. bueno, de algo sirve la escuela primaria no? Simple resta de los valores adecuados dará tu contador regresivo.

en teoría no me importa si es regresivo o no ... la cuestión es que llegue a 20 segundos (20.000 milis) me da igual que cuente hacia arriba o hacia abajo.
pensandolo, estaba por poner un conteo en el pulsador el cual al pulsar la 1 vez active un delay de 1 min.
en la segunda pulsacion otro delay de 1 min y en el 3, un pitido final mas largo con reseteo de todo

Moderador:
Te estaba llamando la atención cuando veo que fue un moderador del foro en inglés el que habrá separado un comentario tuyo o un posteo tuyo en el foro en inglés y al darse cuenta que es un doble posteo (cross post) lo unió con este ya empezado.
Por favor, lee las Normas del foro.
si tienes abierto un hilo de un tema, no puedes consultar por el mismo tema en otro hilo, además eso casi siempre resulta en un secuestro del tema, porque tu cambias la dirección del autor de ese tema para que los demás te respondan.
Ambas son faltas a las normas así que un buen repaso o una buena lectura no te vendrán mal.
He visto que consultas desde el 2015 así que por eso lo digo.

Respecto a tu comentario en inglés (que espero luego edites para que los demás se enteren) esta visto que no has leído lo que @Pablo_Lucini o yo te hemos dicho asi que nada mas por ahora.

perdona surbyte pero yo no he abierto ningun otro post preguntando lo mismo...solo abrí 1..sera algún mal entendido por que como te digo solo he abierto 1...aparte mi post en ingles...yo lo escribí en español en respuesta a tu comentario y lo raro que al día siguiente me salio mi comentario en ingles...
ya te digo no he abierto 2 post preguntando lo mismo ... lo único que hice fue responderte desde mi móvil a tu ultimo comentario.
y volviendo al tema ya tengo parte del programa hecho....es muy simple pero me basta para lo que es....
para empezar he metido el buzzer con su tono y seguido un delay sin tono de los 20 seg que necesitaba...eso lo he metido en loop y me hace exactamente lo que necesito...pitido con su led, 20 seg de espera y pitido y asi de manera infinita...
ahora solo me queda implementar el pulsador con el conteo para cuando pulse me de por ejemplo un delay de 1 min, en el segundo otro delay de 1 min y por ultimo en el 3 pitido mas largo y parada del programa.
de que manera puedo hacer que con cada pulsacion corte ese programa...
lo mismo es una tonteria pero en el loop puedo llamarlo loop 1 y en la pulsacion para el loop1 dirante 1 min??o eso no se puede hacer??

const int Pinbuzzer = 9;//buzzer
const int Pinled1 = 4;  //led 1
const int Pinled2 = 5;  //led 2
const int inputPin =7; //boton
int conta = 0;
int estadoCero = 0; // valor inicial contador

 void setup() 
{
 Serial.begin(9600);
  pinMode (Pinled1,OUTPUT);
  pinMode (Pinbuzzer,OUTPUT);
  pinMode (inputPin,INPUT);
  pinMode (Pinled2, OUTPUT);
}

void loop(){
  int pl = digitalRead(inputPin);
  if(pl!=estadoCero){
    if(pl==HIGH)
 {
  conta++;
  Serial.println(conta);
 }
  }
  estadoCero=pl;
  if (conta==1){
  digitalWrite(Pinled2, HIGH);
  delay (60000);
  digitalWrite(Pinled2,LOW);
  }
  if (conta==2){
  digitalWrite(Pinled2, HIGH);
  delay (60000);
  digitalWrite(Pinled2,LOW);
  }
  if (conta==3){
     tone(Pinbuzzer, 440);
  
  delay (10000);
  }
    conta=0;
  //generar tono de 440Hz durante 1500 ms
  tone(Pinbuzzer, 440);
  digitalWrite(Pinled1, HIGH);
  delay(1500);
 
  //detener tono durante 500ms  
  noTone(Pinbuzzer);
  digitalWrite(Pinled1, LOW);
 delay(20000);
 
}

esto es lo que tengo hecho por ahora...se que no es nada del otro mundo y esta mal hecho pero su funcion la hace....
lo que no consigo que actue bien es el pulsador que hay veces que va y otras que no....
Pd: lleva resistencia de 10k

Hola @yeyo_gato, no importa si esta bien o mal lo único que te pido dejes de usar es el bendito delay(), eso arruina todo lo que quieras hacer y te explico por qué.
Ahora que veo tu código dejamos de hablar en el aire y hablamos en concreto, sobre lo que has hecho, y sobre la idea.

Primero haré criticas constructivas para que veas porque hay cosas que trabajan diferente a lo que piensas.

Empecemos por la detección de tu pulsador.

int pl = digitalRead(inputPin);
  if (pl!=estadoCero){
      if (pl==HIGH) {
          conta++;
          Serial.println(conta);
     }
  }
  estadoCero = pl;

Esto no esta mal, funciona y hace lo mismo que yo suelo usar que me resuelta mas entendible pero como dije, es lo mismo.
Mi versión (que no es mía) es mirar el flanco. Tu haces lo mismo de otro modo.

Yo uso en un solo if y con variables bool para pl y estadoCero no int porque es un desperdicio de memoria. Si ya se, tienes mucha pero cuando no?

  bool pl = digitalRead(inputPin);
  if (pl && !estadoCero){
      conta++;
      Serial.println(conta);
  }
  estadoCero = pl;

Listo lo mismo, solo es otra forma de hacer lo que has hecho. Como dije no esta mal.

Ahora si, esto si que no me gusta.. y claro si pones un delay(60000) 60 segundos que el Arduino no hace nada... menos prestarle atencion a un pulsador que se presione para decirle, EHHH detente!!
Entonces esto no

if (conta==1) {
      digitalWrite(Pinled2, HIGH);
      delay (60000);
      digitalWrite(Pinled2,LOW);
  }
  if (conta==2){
      digitalWrite(Pinled2, HIGH);
      delay (60000);
      digitalWrite(Pinled2,LOW);
  }
  if (conta==3){
     tone(Pinbuzzer, 440);
     delay (10000);
  }
  conta = 0;

En su lugar usaremos millis() y máquina de estados. Por favor lee esto

Ve a Documentación => Indice de temas tutoriales => millis() y también lee máquina de estados.

Bueno no lo terminé porque no me da el tiempo pero mirá si todo lo que ya hacias lo hace correctamente usando millis() y máquina de estado.
Luego falta agregar al finalizar el 3 estado que suene la sirena x 1500 mseg y luego detener o una pausa como has indicado.

const int Pinbuzzer = 9;  // buzzer
const int Pinled1   = 4;  // led 1
const int Pinled2   = 5;  // led 2
const int inputPin  = 7;  // boton
int conta = 0;
bool pl, estadoCero = false; // valor inicial contador
byte estado1, estado2;
unsigned long start;

void setup() {
  Serial.begin(9600);
  pinMode (Pinled1,OUTPUT);
  pinMode (Pinbuzzer,OUTPUT);
  pinMode (inputPin,INPUT);
  pinMode (Pinled2, OUTPUT);
}

void loop(){
  pl = digitalRead(inputPin);
  if (pl && !estadoCero){
      conta++;
      Serial.println(conta);
  }
  estadoCero = pl;
  switch(conta) {
    case 1: tarea();
            break;
    case 2: tarea();
            break;
    case 3: 
            switch(estado2) {
              case 0: tone(Pinbuzzer, 440);
                      start = millis();
                      estado2 = 1;
                      break;
              case 1: if (millis() - start > 10000UL) {
                          estado2 = 2;
                          noTone(Pinbuzzer);
                      }
                      break;
              case 2: estado2 = 0;
                      conta = 0;
                      break;           
            }    
  }

  // conta = 0;
  // //generar tono de 440Hz durante 1500 ms
  // tone(Pinbuzzer, 440);
  // digitalWrite(Pinled1, HIGH);
  // delay(1500);
 
  // //detener tono durante 500ms 
  // noTone(Pinbuzzer);
  // digitalWrite(Pinled1, LOW);
  // delay(20000);
}

void tarea() {
  switch(estado1) {
  case 0: digitalWrite(Pinled2, HIGH);
          start = millis();
          estado1 = 1;
          break;
  case 1: if (millis() - start > 60000UL) {
              estado1 = 2;
              digitalWrite(Pinled2,LOW);
          }
          break;
  case 2: estado1 = 0;
          break;           
  }
}

Si lees lo que te he indicado esto te resueltará al menos mas digerible.

En este código a diferencia del tuyo, en cualquier momento puedes interrumpir, aun no lo hemos hecho porque quiero que lo entiendas.

Ok luego lo pasare y comprobare...
El delay lo puse por que me da igual que mientras este el delay no haga nada,el tema es que al pusar nadie puede hacer nada hasta que pase ese tiempo de ahi la cosa del delay...

Y si eso es lo que el delay no deja hacer asi que tu post inicial

y para terminar un segundo pulsador el cual reinicia todo el rpograma para empezar de nuevo..

con delay() no se puede resolver.

El segundo pulsador iria directo al reset de arduino...asi no me complico tanto y vuelvo al inicio sin problemas.

Bueno... hubieras dicho eso y no te hacia el programa que te hice.
Pero esta bien, si te sirve.

No ombre eso lo pense despues....buscando por google el tema de resetear todo y me salio eso....pero no te preocupes solo era una opcion la cual coger si finalmente no conseguia hacerlo...
Para el boton si no recuerdo mal necesito un retardo no??

ya he probado el codigo...el problema es el pulsador...la primera parte la hace bien...el problema es la 2 parte que son los estados del pulsador.
por mas que pulso no hace nada...no se si sera mi pulsador o que...

Pregunta, cada vez que presionas se lee que conta aumenta?
O sea.. presionas y dice 1, presionas y dice 2 y finalmente dice 3?

Al final se soluciono... No se como pero funciona el pulsador.
Aora seguire con el codigo para hacer el resto del programa...a ver que consigo.
Lei lo que me comentaste varias veces, pero o yo soy muy torpe o no me entero de nada.....aparte de eso buscare mas a ver si me aclara

Nadie nació sabiendo.

Mira la correlación entre esto

if (conta==1) {
      digitalWrite(Pinled2, HIGH);
      delay (60000);
      digitalWrite(Pinled2,LOW);
  }

y lo que yo hice como tarea()

cuando creas una máquina de estado necesitas una variable que justamente identificará a cada momento el estado en que se encuentra. En este caso, la llamé estado1 y la definí como byte porque nunca he hecho cosas que superen 256 pasos o estados. En tu caso solo son 3, pero no creas que he superado 10.

Entonces tu primer estado será el 0 algo que ya hice cuando definí byte estado1 = 0; y lo primero que debes hacer en ese case 0 será

digitalWrite(Pinled2, HIGH);

Ahora bien, como el comando se ejecuta y debemos pasar al siguiente estado o sea a estado1 = 1;
y además acá comenzamos a usar millis() porque para reemplazar delay() debo capturar el valor actual del contador millis() y lo hago asi.

start = millis();

esto carga el valor del contador en la variable del tipo unsigned long (no uses otra cosas que no sea este tipo de variable).

Finalmente unamos todo

case 0: digitalWrite(Pinled2, HIGH);
            estado1 = 1;                       // siguiente estado. Ya no pasará por acá al siguiente loop.
            start = millis();                   // start toma el valor de millis() y eso me permite reemplazar delay
            break;

Eso fue nada mas para tu primer instrucción, pero preparamos todos para la segunda delay(60000);

Si leíste en Documentación los tutoriales de milils() habras visto que algo como este delay ser resuelve asi

if (millis() - start >= 60000UL) {

millis() - start siempre te daré el valor como si pusieras en marcha el cronómetro en ese momento. Comienza por 0 y hasta llegar a 60000 milisegundos no será VERDADERO.
Cuando lo sea, ejecuta lo que tenga dentro {} y qué pondremos dentro, pues un nuevo estado y tu tercera instrucción.
El nuevo estado es estado1 = 2;
Y que debia hacer tu código luego de 60 segundos? pues poner a LOW el pinLed2.
como queda todo el case 1: pues de este modo

case 1: if (millis() - start >= 60000UL) {
               digitalWrite(Pinled2,LOW);
               estado1 = 2;
            }
            break;

ya resolvimos tu código pero aca viene un problema o no.
En tu código cuando conta = 1 ejecuta esto 1 y otra vez y si eso deseas entonces el estado1 = 2 debe tener solo una instrucción que regrese al case 0 o sea a estado1 = 0 de lo contrario, podemos no hacer nada pero en algun momento hay que poner estado1 = 0 para que este listo para algo nuevo, como por ejemplo tu segundo pulsador.

con ello digo que case 2 puede ser

case 2: estado1 = 0;  // con lo que se repite el ciclo mientras conta = 1
            break;

o puede ser

case 2:             // algo vacio con lo que no se ejecuta mas que una vez. 
            break;