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... 
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!