Problema con una alarma

Hola a todos!

Estoy desarrollando una alarma con Arduino UNO para mis clases en la secundaria.

La alarma debe cumplir 3 funciones:

Si recibe 1 pulso, debe mostrar un mensaje que diga 'alarma activada'

Si recibe 2 pulsos, debe mostrar un mensaje que diga 'alarma prendida'

Si recibe pulsos constantes, debe mostrar 1 mensaje 1 sola vez, que diga 'alarma activada'

Todo esto a través del monitor serial y debe trabajar con el mismo puerto.

La cuestión es, que no logro hacer que la mande el mensaje de "alarma activada" sin que interfiera con las otras funciones y no se me ocurre como hacerlo.

Muéstranos el código que tienes (mira en las Normas del foro la forma correcta de hacerlo) y vemos qué habría que modificar.

Saludos

Hola gatul, este es mi codigo:

int conta = 0;

void setup() {
  Serial.begin(9600);
  pinMode(4, INPUT);
}

void loop() {
  if (digitalRead(4) == HIGH){
   if(digitalRead(4) == LOW){
    conta++;
    Serial.println(conta);
    delay(400);
    if(conta == 1){
  Serial.println("Alarma Encendida");
  }
    if(conta == 2){
  Serial.println("Alarma Apagada");
 conta = conta - conta;
}
 if (conta > 2){
  conta = 1;
 }
}
}
}

Esto va conectado a una central de alarma que se activa mediante un control remoto, la cual envia pulsos que el codigo lee para mandar esos mensajes.
Los mensajes de "alarma apagada" y "alarma encendida" se muestran como yo quiero que lo hagan, pero al momento de configurar el de "alarma sonando", este interfiere con las anteriores funciones. Todo esto debe ser a traves del mismo puerto, estuve probando muchas cosas para ver si podia hacerlo funcionar pero nada sirve.

En mi opinión no tendría que responder inmediatamente a recibir un pulso sinó dar un tiempo de espera (o sea definir un tiempo ventana) durante el que si no se reciben más pulsos, recién entonces reaccione.
Obviamente no se pueden usar delays, hay que usar millis().

Digamos algo así, al detectar un pulso incrementar el contador como haces ahora y guardar en una variable el tiempo (en millis()) en que se detectó el pulso.
Luego controlar si el valor del contador es mayor que 0, así sabés que al menos ya se recibió un pulso entonces te fijas si ya pasó el tiempo de ventana. Si ya pasó el tiempo, entonces actúas en función del valor del contador y luego pones el contador en 0 para prepararlo para cuando llegue el próximo comando.

En resumen.
Se recibe un pulso, se incrementa el contador y se empieza a medir el tiempo.
Si durante el tiempo definido no se recibe otro pulso, ejecutas la acción que corresponda.
Si antes de terminar el tiempo se recibe otro pulso, se incrementa el contador y se empieza a medir nuevamente el tiempo.

Entiendo lo que dices gatul. Mientras buscaba soluciones a mi problema me encontré con eso mismo.
El problema es que no logro comprender muy bien como manipular el comando millis() para que logre lo que necesito.
¿Tiene algun ejemplo del que pueda servirme?

Primero te comento una falla en tu código.

if (conta > 2){
  conta = 1;
 }

Nunca se va a cumplir porque cuando conta es 2 lo pones en 0 con

conta = conta - conta;

Por cierto, ¿por qué no

conta = 0;

directamente?


Una posible solución a tu consulta es

int conta = 0;
unsigned long tiempoAnt = 0;
unsigned long ventana = 500; // 500 mseg

void setup() {

  Serial.begin(9600);
  pinMode(4, INPUT);
}

void loop() {

  if (digitalRead(4) == HIGH){
    if(digitalRead(4) == LOW){
      conta++;
      tiempoAnt = millis(); // guarda tiempo del pulso
//      Serial.println(conta);
    }
  }

  if(conta > 0){
    if(millis() - tiempoAnt >= ventana){
      if(conta == 1){
        Serial.println("Alarma Encendida");
      }
      else if(conta == 2){
        Serial.println("Alarma Apagada");
      }
      conta = 0;
    }
    else if(conta == 3){ // si no se cumplio el tiempo ventana
        Serial.println("Alarma Sonando");
    }
  }
}

Te lo explico:
Cuando detecta el flanco descendente del pulso (porque pasa de HIGH a LOW), incrementa el contador, guarda el tiempo.
Luego, si conta > 0 significa que hubo pulsos, entonces compara la diferencia entre el tiempo actual y el guardado con el valor de ventana (arbitrariamente lo puse en 500 mseg, deberías ajustarlo).
Si es mayor o igual entonces ya no entran pulsos y debe actuar según los pulsos que ha contado.
Con 1 ó 2 pulsos emite el mensaje correspondiente.
Luego resetea conta y sale del if() para volver a esperar que se produzcan nuevos pulsos.
Si no se cumplió el tiempo, verifica si ya contó 3 pulsos y emite mensaje acorde.
Ya no emitirá mensajes en tanto sigan entrando pulsos "continuos".

Te recomiendo que leas el tema Entender millis... en la sección Documentación.

Saludos