Resetear arduino despues de alertar

Hola, vengo aqui para ver si alguien me puede ayudar con esto, el codigo que adjunte es para una alerta de sismos o cualquier otro movimiento, el punto es que cuando el buzzer (La alerta) se dispara y comienza a alertar, no se detiene hasta que se resetea manualmente mediante el boton de Arduino, ¿alguien sabe de alguna forma en la que automaticamente, despues de alertar cierta cantidad de segundos se detenga sin tener que hacerlo manualmente?
Un saludo a todos, y gracias

int movimiento=0;

void setup() {
Serial.begin(9600);
pinMode(8,OUTPUT); //pin led
pinMode(9,OUTPUT); //buzzer
pinMode(A0,INPUT); //sensor vibracion

}

void loop() {
 movimiento=analogRead(A0);
 Serial.println(movimiento);
 delay(30);

 while(movimiento>=200)
 digitalWrite(8,HIGH);
 digitalWrite(9,HIGH);
 delay(300);
  digitalWrite(8,LOW);
 digitalWrite(9,LOW);
 delay(300);
}

Que significa esto para ti?

 while (movimiento>=200)

es decir, que crees que hace el programa en esta línea?

Que, cuando las medidas de el sensor rebasen >200 suene la alarma, pero una vez que se activa no se apaga hasta que se resetea Arduino manualmente

Mi duda es, si hay alguna otra forma que se me escape, en la que se apague la alarma despues de equis cantidad de segundos

Porque justamente el While le dice que mientras este x encima de 200 se quede ahi.
En las condiciones del while no hay nada que le diga que luego de X segundos se apague o sea que el contenido dentro del while se vuelva FALSO

La cosa funciona asi
Ahora solo tienes algo que le dice... si hay un nivel que supere 200 quedate haciendo lo que esta dentro del while, pero lo que te está faltando es que dentro del while se lea de nuevo si movimiento ha cambiado, cosa que ambos sabemos que si ocurrirá.

esta es la solución mas simple a tu problema sin el tema tiempo

coloca la lectura de analogRead(A0) (además de la actual) dentro del while y saldra cuando no se de la condicion que ahora tienes.

Voy a modificar tu programa para que refleje los cambios que esperas.

#define INTERVALO 60000UL   // 60x1000 mseg = 60 segundos

int movimiento = 0;
unsigned long start;
unsigned long blink;
byte estado = 0;


void setup() {
  Serial.begin(9600);
  pinMode(8,OUTPUT); //pin led
  pinMode(9,OUTPUT); //buzzer
  pinMode(A0,INPUT); //sensor vibracion
}

void loop() {
  movimiento = analogRead(A0);
  Serial.println(movimiento);
  delay(30);
  
  if (movimiento >= 200) 
      start = millis();   // con esto inicializo el tiempo

  while (movimiento >= 200 && (millis()-start > INTERVALO)) {
        movimiento = analogRead(A0);
        while (estado) {
            case 0: digitalWrite(8,HIGH);
                    digitalWrite(9,HIGH);
                    estado = 1;
                    blink = millis();
                    break;
            case 1: if (millis() - blink > 300UL) {
                        digitalWrite(8,LOW);
                        digitalWrite(9,LOW);
                        estado = 2;
                        blink = millis();
                    }
                    break;
            case 2: if (millis() - blink > 300UL) {
                        estado = 0;
                    }
                    break;
        }
  }
}

Compilando el programa como tu indicas obtengo el siguiente error

Arduino:1.8.9 (Windows 10), Tarjeta:"Arduino/Genuino Uno"

C:\Users\1078110411\Documents\Arduino\sketch_jul24b\sketch_jul24b.ino: In function 'void loop()':

sketch_jul24b:27:13: error: case label '0' not within a switch statement

             case 0: digitalWrite(8,HIGH);

             ^

sketch_jul24b:32:13: error: case label '1' not within a switch statement

             case 1: if (millis() - blink > 300UL) {

             ^

sketch_jul24b:39:13: error: case label '2' not within a switch statement

             case 2: if (millis() - blink > 300UL) {

             ^

exit status 1
case label '0' not within a switch statement

Este informe podría contener más información con
"Mostrar salida detallada durante la compilación"
opción habilitada en Archivo -> Preferencias.

¿Sabes a que se deba?

Ya intente ver si faltaba algun signo como {} y buscar en Google, pero nada... :confused:

El error fue mio pero esta muy claro dice

error: case label '0' not within a switch statement

case 0: no esta dentro de una instrucción switch y yo le puse while

cambia esto

while (estado) {
            case 0: digitalWrite(8,HIGH);

por esto

switch(estado) {
           case 0: digitalWrite(8,HIGH);

Si, ahora no suena el Buzzer ni el led pero ya vi mas o menos que hace cada cosa, gracias surbyte, ya iré mejorando el programa por cuenta propia, saludos

Cuando se programa no se pone esto

digitalWrite(8,HIGH);
digitalWrite(9,HIGH);

sino que se asigna etiquetas por ejemplo de este modo

#define LED        8
#define BUZZER  9

y luego

digitalWrite(LED,HIGH);
digitalWrite(BUZZER,HIGH);

Dirás, pero, es lo mismo!! No, claro que no es lo mismo.
Desde el punto de vista de la programación lo es pero para nosotros es entender que hay un LED y un Buzzer, si tu no lo mencionas yo ni enterado.

Lo dice acá

pinMode(8,OUTPUT); //pin led
pinMode(9,OUTPUT); //buzzer

Pero solo tu tienes presente eso. Luego si cada vez que activas o desactivas algo esta presente su etiqueta para nosotros tiene mas claridad y para ti en unos meses también la tendrá.

Dices que ahora no funcionan LED y Buzzer?

Okey, tomaré en cuenta lo de las etiquetas.

Así es, ni el LED ni el Buzzer se activan cuando hay movimiento, el sensor de movimiento si realiza la lectura (Se ve en el serial plotter) , el circuito no está mal ya que cargue el sketch, de antes de la modificación y todo va bien.

Saludos.

Ahora me doy cuenta de otro error de mi parte

 while (movimiento >= 200 && (millis()-start > INTERVALO)) {

Esto dice que ambas condiciones debes ser TRUE para que continue y la que solo es TRUE es la de movimiento pero la de tiempo no lo es entonces sale inmediatamente y no se escucha nada.

Debe ser asi

 while (movimiento >= 200 && (millis()-start <= INTERVALO)) {

O sea que mientras el sismógrafo indique >= 200 Y el tiempo sea menor o igual que el INTERVALO entonces seguirá dentro.

Ahora va todo bien... Te agradezco por tu ayuda surbyte, gracias y saludos!