Tengo problemas con un timer aleatorio de tiempos largos

Buenas, como comente antes estoy comenzando, ya he realizado cosas basicas pero aqui me trabe. Soy tecnico electronico pero mas de HW no de programacion, pero Arduino me llama a inventar soluciones a mi medida.
El asunto es que me encargan una botonera de "hombre muerto" y las funciones serian:

  1. Iniciar un Timer aleatorio en el orden de los 60 a 90 segundos (o mas segun resulte)
  2. Cuando falten 15 segundos para llegar al tiempo en cada isntancia, disparar una salida para activar buzer, led etc ( PIN 11, AvisoPin).
  3. Si antes de conluir el tiempo se presiona un boton, todo se reinicia.
  4. Cuando concluya el tiempo disparar una alarma que sera una salida hacia un relay (PIN 10, SalidaPin) y un led (PIN 12, LedPin).

Hasta aqui parece una pavada, pero he modificado tantas veces que me perdi, pego codigo y disculpen si no es simple y limpio, ya ire mejorando.
Gracias de antemano.

int ledPin = 12;         // Pin del led de alarma
int resetButtonPin = 8;  // Pin del pulsador
int AvisoPin = 11;       // Pin del buzzer de aviso
int SalidaPin = 10;      // Pin salida de relay
long randomTime;         // tiempo aleatorio en segundos
int startTime;           // hora de inicio del timer
long currentTime;        // hora actual
long remainingTime;      // tiempo restante en el timer
int resetButtonState;    // Declara la variable para el estado del pulsador de

void setup()  // Bloque de Configuración
{
  //Serial.begin(9600);  // Inicializa el puerto serial para depurar
  //randomSeed(analogRead(A0));
  randomSeed(millis());

  pinMode(ledPin, OUTPUT);       // Fija pin 13 como salida
  pinMode(AvisoPin, OUTPUT);     // Fija pin 12 como salida
  pinMode(SalidaPin, OUTPUT);    // Fija pin 11 como salida
  digitalWrite(ledPin, LOW);     // inicia salida led como apagada
  digitalWrite(AvisoPin, LOW);   // inicia salida Aviso como apagada
  digitalWrite(SalidaPin, LOW);  // inicia salida Salida como apagada
  // Inicializa el pin del pulsador de reinicio como entrada
  pinMode(resetButtonPin, INPUT);
  // Genera un numero aleatorio entre 45 y 75 segundos
  randomTime = random(45, 75);

  // Establece la hora de inicio del timer
  startTime = millis();
}

void loop()  // Bloque de ejecución cíclica
{
  // Lee el estado del pulsador de reinicio
  resetButtonState = digitalRead(resetButtonPin);

  // Si el pulsador de reinicio está presionado, reinicia el timer
  if (resetButtonState == HIGH) {
    // Reinicia el timer generando un nuevo tiempo aleatorio y estableciendo una
    // nueva hora de inicio
    randomTime = random(45, 75);
    startTime = millis();
  }
  // Calcula el tiempo restante en el timer
  currentTime = millis();
  //remainingTime = randomTime - (currentTime - startTime);
  remainingTime = randomTime * 1000 - (currentTime - startTime);
  // Si el tiempo restante es menor que 15 segundos, emite una alarma
  if (remainingTime <= 15000) {
    digitalWrite(AvisoPin, HIGH);  // Emite una alarma
  }

  // Si el tiempo restante es menor o igual a cero, emite la alarma final
  if (remainingTime <= 0) {
    digitalWrite(ledPin, HIGH);     // Emite la alarma final
    digitalWrite(SalidaPin, HIGH);  //Dispara relay de alarma
  }

  // Espera un segundo antes de volver a calcular el tiempo restante
  delay(1000);
}

Bueno los problemas son:
No cuenta los segundos que corresponden, a los 35 segundos aprox se dispara el aviso y un instante despues la alarma.
Una vez que esta disparado el pulsador no reinicia el contador, solo con el reset se reinicia, pero este es un problema menor.
Escucho los males del codigo :woozy_face:

¿Pretendías que startTime fuera int en lugar de long o unsigned long?

usas random pero no entre 60 y 90 sino cualquier random
ahora veo que en el setup usas
// Genera un numero aleatorio entre 45 y 75 segundos
randomTime = random(45, 75);
Bueno explicaste una cosa y usas otra. Normal

Bueno ya vio el detalle mas importante @xfpd con el uso de int pero todos los elementos que usen millis() deben ser unsigned long cierto es que no usarás algo que llegue a 47 mas extra pero es bueno aprender como definir ciertas cosas. Acostúmbrate.

int ledPin = 12;         // Pin del led de alarma
int resetButtonPin = 8;  // Pin del pulsador
int AvisoPin = 11;       // Pin del buzzer de aviso
int SalidaPin = 10;      // Pin salida de relay
unsigned long randomTime;         // tiempo aleatorio en segundos
unsigned long startTime;           // hora de inicio del timer
unsigned long currentTime;        // hora actual
unsigned long remainingTime;      // tiempo restante en el timer
unsigned long demoro;
int resetButtonState;    // Declara la variable para el estado del pulsador de

void setup()  // Bloque de Configuración
{
  Serial.begin(9600);  // Inicializa el puerto serial para depurar
  //randomSeed(analogRead(A0));
  randomSeed(millis());

  pinMode(ledPin, OUTPUT);       // Fija pin 13 como salida
  pinMode(AvisoPin, OUTPUT);     // Fija pin 12 como salida
  pinMode(SalidaPin, OUTPUT);    // Fija pin 11 como salida
  digitalWrite(ledPin, LOW);     // inicia salida led como apagada
  digitalWrite(AvisoPin, LOW);   // inicia salida Aviso como apagada
  digitalWrite(SalidaPin, LOW);  // inicia salida Salida como apagada
  // Inicializa el pin del pulsador de reinicio como entrada
  pinMode(resetButtonPin, INPUT);
  // Genera un numero aleatorio entre 45 y 75 segundos
  randomTime = random(45, 75);

  // Establece la hora de inicio del timer
  startTime = millis();
}

void loop()  // Bloque de ejecución cíclica
{
  // Lee el estado del pulsador de reinicio
  resetButtonState = digitalRead(resetButtonPin);

  // Si el pulsador de reinicio está presionado, reinicia el timer
  if (resetButtonState == HIGH) {
    // Reinicia el timer generando un nuevo tiempo aleatorio y estableciendo una
    // nueva hora de inicio
    randomTime = random(45, 75);
    Serial.println("Nro generado:"+String(randomTime));
    startTime = millis();
  }
  if (millis() - demoro > 1000) {
    // Calcula el tiempo restante en el timer
      currentTime = millis();
      //remainingTime = randomTime - (currentTime - startTime);
      remainingTime = randomTime * 1000 - (currentTime - startTime);
      // Si el tiempo restante es menor que 15 segundos, emite una alarma
      if (remainingTime <= 15000) {
        digitalWrite(AvisoPin, HIGH);  // Emite una alarma
      }

      // Si el tiempo restante es menor o igual a cero, emite la alarma final
      if (remainingTime <= 0) {
        digitalWrite(ledPin, HIGH);     // Emite la alarma final
        digitalWrite(SalidaPin, HIGH);  //Dispara relay de alarma
      }
      Serial.println(remainingTime/1000);
      demoro = millis();
  }  
}

Gracias [Surbyte] y ahi ya estuve corrigiendo, efectivamente en unsigned long arranco la solucion, tambien arregle lo del pulsador que estaba invertido y el volver a cero el contador, asi que rehice todo de vuelta pero contando hacia adelante, por consejo de mi hijo creamos una funcion para el random y simplificar y ademas detener todas las salidas. tambien cambiamos la referencia del random por la lectura de pin analogico sin uso para que varie en serio. Va el codigo arreglado.


int ledPin = 12;            // LED puebas de la placa: pin 13
int resetButtonPin = 8;     // Pin del pulsador
int AvisoPin = 11;          // Pin del buzzer de aviso
int SalidaPin = 10;         // Pin salida de relay
unsigned long randomTime;   // tiempo aleatorio en segundos
unsigned long currentTime;  // hora actual
signed long remainingTime;  // tiempo restante en el timer
int resetButtonState = 0;   // Declara la variable para el estado del pulsador de

void setup()  // Bloque de Configuración
{
  //Serial.begin(9600);  // Inicializa el puerto serial para depurar
  randomSeed(analogRead(A0));

  pinMode(ledPin, OUTPUT);       // Fija pin 13 como salida
  pinMode(AvisoPin, OUTPUT);     // Fija pin 12 como salida
  pinMode(SalidaPin, OUTPUT);    // Fija pin 11 como salida
  digitalWrite(ledPin, LOW);     // inicia salida led como apagada
  digitalWrite(AvisoPin, LOW);   // inicia salida Aviso como apagada
  digitalWrite(SalidaPin, LOW);  // inicia salida Salida como apagada
  // Inicializa el pin del pulsador de reinicio como entrada
  pinMode(resetButtonPin, INPUT_PULLUP);

  // Establece la hora de inicio del timer
  iniciarTimer();
}

void loop()  // Bloque de ejecución cíclica
{
  // Lee el estado del pulsador de reinicio
  // El input esta invertido por el INPUT_PULLUP, lo invertimos para tener el valor correcto.
  resetButtonState = !digitalRead(resetButtonPin);

  // Si el pulsador de reinicio está presionado, reinicia el timer
  if (resetButtonState == HIGH) {
    // Reinicia el timer generando un nuevo tiempo aleatorio y estableciendo una
    // nueva hora de inicio
    iniciarTimer();
  }
  // Calcula el tiempo restante en el timer
  currentTime += 1;
  remainingTime = randomTime - currentTime;

  // Si el tiempo restante es menor que 15 segundos, emite una alarma
  if (remainingTime <= 15) {
    digitalWrite(AvisoPin, HIGH);  // Emite una alarma de aviso
  }

  // Si el tiempo restante es menor o igual a cero, emite la alarma final
  if (currentTime > randomTime) {
    digitalWrite(ledPin, HIGH);     // Emite la alarma final
    digitalWrite(SalidaPin, HIGH);  //Dispara relay de alarma
  }

  // Espera un segundo antes de volver a calcular el tiempo restante
  delay(1000);
}
void iniciarTimer() {

  // Genera un numero aleatorio en segundos
  randomTime = random(60, 90);
  currentTime = 0;

  digitalWrite(AvisoPin, LOW);
  digitalWrite(SalidaPin, LOW);
  digitalWrite(ledPin, LOW);
}

Gracias, Solucionado

Las gracias a @xfpd mas que a mi, yo solo lo puse en un código para que lo vieras. De hecho ajusté varias cosas.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.