Como crear un timer en cuenta regresiva

Estimados, junto con saludarles y desearles a todos un fantástico día me veo en la obligación de pedir su ayuda con un proyecto.
Les cuento que es lo que necesito.
Necesito que cuando una entrada digital esté en 0 permanente pueda hacer un conteo de retroceso y que se active una salida por ese periodo de tiempo y que al apagarse esa salida el tiempo quedé en cero para posteriormente volver a cargarle un tiempo x con el serial.
Agradezco enormemente el espacio y espero no molestarles soy nuevo es mi primer post y soy muy novato en esto muchas gracias.

Bienvenido.
La idea del foro es ayudarte con tu código, no hacerlo por vos, por lo tanto te sugiero que presentes lo que tienes y lo vemos o hagas una búsqueda en Google ya que ejemplos abundan, luego, si tienes dudas nos consultas.

Saludos

1 Like

Gracias por tu respuesta gatul, y claro no quiero que sea fácil el tema quiero aprender si se facilita el código así de fácil no aprenderé mucho sería un copiar y pegar.
Tengo un código pero estoy tratando de descifrar cómo subirlo por este medio ya que al parecer no se debe subir código como un comentario.

Pulsas </> en la barra de herramientas del editor y luego pegas el código en la leyenda
escribe o pega el código aquí
es muy sencillo.
Lo que si, por favor, que el código esté indentado así es más fácil de leer.

Saludos

1 Like

Moderador:
Lee las Normas del foro y postead tu código/error usando etiquetas de código.
Ve a edición, luego selecciona todo el código que has publicado, lo cortas y click en </>


1 Like

amigos aqui les comparto el codigo solicitado esta es la primera parte.


#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <LCD.h>
#include <Wire.h>

LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7);

SoftwareSerial hc06(0, 1);



#define in1  2    // pin rele señal de fin de ciclo reactor A
#define in2  3    // pin rele señal de fin de ciclo reactor B
#define in3  4    // swich de apagado bomba bacterias reactor A
#define in4  5    // swich de apagao bomba bacterias reactor B
#define in5  6    // pin rele señal de contador bomba de llenado A
#define in6  7    // pin rele señal de contador bomba de llenado B

#define k1  A1    // salidas para contacor de bomba de bacterias reactor A
#define k2  A0    // salidas para contacor de bomba de bacterias reactor B

#define alarmA  12  // salida para una sirena en 12v reactor A
#define alarmB  13  // salida para una sirena en 12v reactor B


unsigned long tiempoA ;
unsigned long guardadoA ;
const long intervaloA = 910;

unsigned long tiempoB ;
unsigned long guardadoB ;
const long intervaloB = 910;

unsigned long t;


int esperaA = 0;
int esperaB = 0;
int T_esperaA = 0;
int T_esperaB = 0;

int estado ;
int cont = 0;
boolean ciclo = false;

int estado1 ;
int cont1 = 0;
boolean ciclo1 = false;

int estado2 ;
int cont2 = 0;
boolean ciclo2 = false;

int estado3 ;
int cont3 = 0;
boolean ciclo3 = false;


char estadobt = 0;
int menu = 1;

void setup() {
  Serial.begin(9600);
  hc06.begin(9600);
  hc06.flush();
  delay(500);



  pinMode (in1, INPUT);       // entradas
  pinMode (in2, INPUT);
  pinMode (in3, INPUT);
  pinMode (in4, INPUT);
  pinMode (in5, INPUT);
  pinMode (in6, INPUT);


  pinMode (k1, OUTPUT);      // salidas
  pinMode (k2, OUTPUT);
  pinMode (alarmA, OUTPUT);
  pinMode (alarmB, OUTPUT);
  digitalWrite(k1, LOW);      // al iniciar todas estaran en 1
  digitalWrite(k2, LOW);
  digitalWrite(alarmA, LOW);
  digitalWrite(alarmB, LOW);

  EEPROM.get(0, cont);
  EEPROM.get(10, cont1);
  EEPROM.get(20, cont2);
  EEPROM.get(30, cont3);


  lcd.setBacklightPin(3, POSITIVE); // puerto P3 de PCF8574 como positivo
  lcd.setBacklight(HIGH);   // habilita iluminacion posterior de LCD
  lcd.begin(20, 4);  // inicializacion de pantalla lcd
  lcd.display();
  lcd.clear();
}

void loop() {
  
    despliegue();
    BacteriasA ();
    BacteriasB ();
    contador_A ();
    contador_B ();
    llenado_A ();
    llenado_B ();
  
}



void BacteriasA () {


 if ( digitalRead(in1) == 0  ) {
    tiempoA = millis();

    if (tiempoA - guardadoA >= intervaloA) {
      guardadoA = tiempoA;

      if (esperaA > 0) {
        esperaA -- ;
        digitalWrite(k1, HIGH);
      }

      else {
        digitalWrite(k1, LOW);
        T_esperaA = 0;
      }

    }

    if (digitalRead(in1) == 1) {

      digitalWrite(k2, LOW);
      esperaB = T_esperaB;
    }
  }

  contador_A ();
}


void BacteriasB () {


  if ( digitalRead(in2) == 0  ) {
    tiempoB = millis();

    if (tiempoB - guardadoB >= intervaloB) {
      guardadoB = tiempoB;

      if (esperaB > 0) {
        esperaB -- ;
        digitalWrite(k2, HIGH);
      }

      else {
        digitalWrite(k2, LOW);
        T_esperaB = 0;
      }

    }

    if (digitalRead(in2) == 1) {

      digitalWrite(k2, LOW);
      esperaB = T_esperaB;
    }
  }

  contador_B ();
}


void contador_A () {

  estado1 = digitalRead (in1);
  if (estado1 <= 0 && ciclo1) {
    cont1++;
    EEPROM.put(10, cont1);
    ciclo1 = false;
  }

  if (estado1 >= 1 && ciclo1 == false) {

    ciclo1 = true;
  }
}

void contador_B () {

  estado = digitalRead (in2);
  if (estado <= 0 && ciclo) {
    cont++;
    EEPROM.put(0, cont);
    ciclo = false;
  }

  if (estado >= 1 && ciclo == false) {

    ciclo = true;
  }
}

void llenado_A () {

  estado2 = digitalRead (in5);
  if (estado2 <= 0 && ciclo2) {
    cont2++;
    EEPROM.put(20, cont2);
    ciclo2 = false;
  }

  if (estado2 >= 1 && ciclo2 == false) {

    ciclo2 = true;
  }
}

void llenado_B () {

  estado3 = digitalRead (in6);
  if (estado3 <= 0 && ciclo3) {
    cont3++;
    EEPROM.put(30, cont3);
    ciclo3 = false;
  }

  if (estado3 >= 1 && ciclo3 == false) {

    ciclo3 = true;
  }
}

aqui esta la otra etiqueta que se llama despliegue

void despliegue() {

  if (hc06.available()) {
    estadobt  = hc06.read();
  }

  // menu principal
  if (estadobt == '1') {
    menu = 1;
  }
  // menu conteo ciclos reactores
  if (estadobt == '2') {
    menu = 2;
  }
  // menu conteo bombas de llenado
  if (estadobt == '3') {
    menu = 3;
  }
  // comando reset contador de ciclos reactores
  if (estadobt == '4') {
    cont = 0;
    cont1 = 0;
    EEPROM.put(0, cont);
    EEPROM.put(10, cont1);
  }
  // comando reset contador bombas de llenado
  if (estadobt == '5') {
    cont2 = 0;
    cont3 = 0;
    EEPROM.put(20, cont2);
    EEPROM.put(30, cont3);
  }
  // tiempo de funcionamiento bomba de vaciado reactor A
  if (estadobt == '6') {
    T_esperaA = 20;
  }
  // tiempo de funcionamiento bomba de vaciado reactor A
  if (estadobt == '7') {
    T_esperaA = 240;
  }
  // tiempo de funcionamiento bomba de vaciado reactor A
  if (estadobt == '8') {
    T_esperaA = 600;
  }
  // tiempo de funcionamiento bomba de vaciado reactor B
  if (estadobt == '9') {
    T_esperaB = 20;
  }
  // tiempo de funcionamiento bomba de vaciado reactor B
  if (estadobt == '0') {
    T_esperaB = 240;
  }
  // tiempo de funcionamiento bomba de vaciado reactor B
  if (estadobt == 'a') {
    T_esperaB = 600;
  }


  switch (menu) {
    case 1 : // menu principal
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Tiempo Vaciado  ");
      lcd.setCursor(0, 1);
      lcd.print("Bomba de Bacterias");

      BacteriasA();
      lcd.setCursor(0, 2);
      lcd.print("Time A:");
      lcd.setCursor(7, 2);
      lcd.print( t );

      BacteriasB();
      lcd.setCursor(0, 3);
      lcd.print("Time B:");
      lcd.setCursor(7, 3);
      lcd.print( esperaB );
      delay (500);
      break;

    case 2: //menu contador de ciclos
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("N\337 de ciclos reactor  ");

      contador_A ();
      lcd.setCursor(0, 1);
      lcd.print("Ciclos A =  ");
      lcd.setCursor(11, 1);
      lcd.print(cont1);

      contador_B ();
      lcd.setCursor(0, 2);
      lcd.print("Ciclos B = ");
      lcd.setCursor(11, 2);
      lcd.print(cont);
      delay (500);

      break;

    case 3: // menu contador bombas de llenado
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("N\337 de ciclos llenado  ");

      llenado_A ();
      lcd.setCursor(0, 1);
      lcd.print("Llenado A =  ");
      lcd.setCursor(13, 1);
      lcd.print(cont2);

      llenado_B ();
      lcd.setCursor(0, 2);
      lcd.print("Llenado B = ");
      lcd.setCursor(13, 2);
      lcd.print(cont3);
      delay (500);

      break;



  }
}

por favor ayuda muchas gracias a todos

bueno quiero comentarles para que es este codigo.
este codigo es para crear un timer de descenso en cuenta regresiva el problema es que cada vez que le cargo el tiempo a través del celular ( modulo BT) el tiempo se actualiza pero al llegar a cero no queda en cero se vuelve a reiniciar al tiempo que le cargue, mi idea es que al cargarle un tiempo solo haga ese tiempo y no vuelva a repetir a menos que uno le mande el comando, lo de mas del codigo es un registro de cuentas para saber cuantas veces hizo el ciclo es para llevar un control nada mas.
por favor ayúdenme con esa parte de mi código ya llevo 1 semana analizando y no puedo dar con la falla .

recién subí el código completo, muchas gracias.

Si he comprendido bien el código.... prueba con este loop:

void loop() {
  while (!hc06.available());
  despliegue();
  BacteriasA ();
  BacteriasB ();
  contador_A ();
  contador_B ();
  llenado_A ();
  llenado_B ();
}

A ver que pasa.

Gracias por tu pronta respuesta voy a probar el código muchas gracias

Amigo una pregunta por qué lo negaste ? Que explicación o lógica tendría según tu experiencia.

Pero. ¿funciono?.

no amigo no funciono es mas se bloquea el programa

no funciono

vuelvo a subir el programa corregi algunos detalles

#include <SoftwareSerial.h>
#include <EEPROM.h>
#include <LiquidCrystal_I2C.h>
#include <LCD.h>
#include <Wire.h>

LiquidCrystal_I2C lcd (0x27, 2, 1, 0, 4, 5, 6, 7);

SoftwareSerial hc06(0, 1);



#define in1  2    // pin rele señal de fin de ciclo reactor A
#define in2  3    // pin rele señal de fin de ciclo reactor B
#define in3  4    // swich de apagado bomba bacterias reactor A
#define in4  5    // swich de apagao bomba bacterias reactor B
#define in5  6    // pin rele señal de contador bomba de llenado A
#define in6  7    // pin rele señal de contador bomba de llenado B

#define k1  A1    // salidas para contacor de bomba de bacterias reactor A
#define k2  A0    // salidas para contacor de bomba de bacterias reactor B

#define alarmA  12  // salida para una sirena en 12v reactor A
#define alarmB  13  // salida para una sirena en 12v reactor B


unsigned long tiempoA ;
unsigned long guardadoA ;
const long intervaloA = 910;

unsigned long tiempoB ;
unsigned long guardadoB ;
const long intervaloB = 910;

int esperaA = 0;
int esperaB = 0;
int T_esperaA = 0;
int T_esperaB = 0;

int estado ;
int cont = 0;
boolean ciclo = false;

int estado1 ;
int cont1 = 0;
boolean ciclo1 = false;

int estado2 ;
int cont2 = 0;
boolean ciclo2 = false;

int estado3 ;
int cont3 = 0;
boolean ciclo3 = false;


char estadobt = 0;
int menu = 1;

void setup() {
  Serial.begin(9600);
  hc06.begin(9600);
  hc06.flush();
  delay(500);



  pinMode (in1, INPUT);       // entradas
  pinMode (in2, INPUT);
  pinMode (in3, INPUT);
  pinMode (in4, INPUT);
  pinMode (in5, INPUT);
  pinMode (in6, INPUT);


  pinMode (k1, OUTPUT);      // salidas
  pinMode (k2, OUTPUT);
  pinMode (alarmA, OUTPUT);
  pinMode (alarmB, OUTPUT);
  digitalWrite(k1, LOW);      // al iniciar todas estaran en 1
  digitalWrite(k2, LOW);
  digitalWrite(alarmA, LOW);
  digitalWrite(alarmB, LOW);

  EEPROM.get(0, cont);
  EEPROM.get(10, cont1);
  EEPROM.get(20, cont2);
  EEPROM.get(30, cont3);


  lcd.setBacklightPin(3, POSITIVE); // puerto P3 de PCF8574 como positivo
  lcd.setBacklight(HIGH);   // habilita iluminacion posterior de LCD
  lcd.begin(20, 4);  // inicializacion de pantalla lcd
  lcd.display();
  lcd.clear();
}

void loop() {

  despliegue();
  BacteriasA ();
  BacteriasB ();
  contador_A ();
  contador_B ();
  llenado_A ();
  llenado_B ();

}



void BacteriasA () {


  if ( digitalRead(in1) == 0  ) {
    tiempoA = millis();

    if (tiempoA - guardadoA >= intervaloA) {
      guardadoA = tiempoA;

      if (esperaA > 0) {
        esperaA -- ;
        digitalWrite(k1, HIGH);

      }

      else {
        digitalWrite(k1, LOW);
        esperaA = 0;
        T_esperaA = 0;
      }

    }

  }


  if (digitalRead(in1) == 1) {
    digitalWrite(k1, LOW);

    esperaA = T_esperaA;
  }


  contador_A ();
}


void BacteriasB () {


  if ( digitalRead(in2) == 0  ) {
    tiempoB = millis();

    if (tiempoB - guardadoB >= intervaloB) {
      guardadoB = tiempoB;

      if (esperaB > 0) {
        esperaB -- ;
        digitalWrite(k2, HIGH);

      }

      else {
        digitalWrite(k2, LOW);
        T_esperaB = 0;
        esperaB = 0;
      }

    }
  }
    if (digitalRead(in2) == 1) {

      digitalWrite(k2, LOW);
      
      esperaB = T_esperaB;
    }
  

  contador_B ();
}


void contador_A () {

  estado1 = digitalRead (in1);
  if (estado1 <= 0 && ciclo1) {
    cont1++;
    EEPROM.put(10, cont1);
    ciclo1 = false;
  }

  if (estado1 >= 1 && ciclo1 == false) {

    ciclo1 = true;
  }
}

void contador_B () {

  estado = digitalRead (in2);
  if (estado <= 0 && ciclo) {
    cont++;
    EEPROM.put(0, cont);
    ciclo = false;
  }

  if (estado >= 1 && ciclo == false) {

    ciclo = true;
  }
}

void llenado_A () {

  estado2 = digitalRead (in5);
  if (estado2 <= 0 && ciclo2) {
    cont2++;
    EEPROM.put(20, cont2);
    ciclo2 = false;
  }

  if (estado2 >= 1 && ciclo2 == false) {

    ciclo2 = true;
  }
}

void llenado_B () {

  estado3 = digitalRead (in6);
  if (estado3 <= 0 && ciclo3) {
    cont3++;
    EEPROM.put(30, cont3);
    ciclo3 = false;
  }

  if (estado3 >= 1 && ciclo3 == false) {

    ciclo3 = true;
  }
}

el despliegue del menu

void despliegue() {

  if (hc06.available()) {
    estadobt  = hc06.read();
  }

  // menu principal
  if (estadobt == '1') {
    menu = 1;
  }
  // menu conteo ciclos reactores
  if (estadobt == '2') {
    menu = 2;
  }
  // menu conteo bombas de llenado
  if (estadobt == '3') {
    menu = 3;
  }
  // comando reset contador de ciclos reactores
  if (estadobt == '4') {
    cont = 0;
    cont1 = 0;
    EEPROM.put(0, cont);
    EEPROM.put(10, cont1);
  }
  // comando reset contador bombas de llenado
  if (estadobt == '5') {
    cont2 = 0;
    cont3 = 0;
    EEPROM.put(20, cont2);
    EEPROM.put(30, cont3);
  }
  // tiempo de funcionamiento bomba de vaciado reactor A
  if (estadobt == '6') {
    T_esperaA = 20;
  }
  // tiempo de funcionamiento bomba de vaciado reactor A
  if (estadobt == '7') {
    T_esperaA = 240;
  }
  // tiempo de funcionamiento bomba de vaciado reactor A
  if (estadobt == '8') {
    T_esperaA = 600;
  }
  // tiempo de funcionamiento bomba de vaciado reactor B
  if (estadobt == '9') {
    T_esperaB = 20;
  }
  // tiempo de funcionamiento bomba de vaciado reactor B
  if (estadobt == '0') {
    T_esperaB = 240;
  }
  // tiempo de funcionamiento bomba de vaciado reactor B
  if (estadobt == 'a') {
    T_esperaB = 600;
  }


  switch (menu) {
    case 1 : // menu principal
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Tiempo Vaciado  ");
      lcd.setCursor(0, 1);
      lcd.print("Bomba de Bacterias");

      BacteriasA();
      lcd.setCursor(0, 2);
      lcd.print("Time A:");
      lcd.setCursor(7, 2);
      lcd.print( esperaA );

      BacteriasB();
      lcd.setCursor(0, 3);
      lcd.print("Time B:");
      lcd.setCursor(7, 3);
      lcd.print( esperaB );
      delay (500);
      break;

    case 2: //menu contador de ciclos
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("N\337 de ciclos reactor  ");

      contador_A ();
      lcd.setCursor(0, 1);
      lcd.print("Ciclos A =  ");
      lcd.setCursor(11, 1);
      lcd.print(cont1);

      contador_B ();
      lcd.setCursor(0, 2);
      lcd.print("Ciclos B = ");
      lcd.setCursor(11, 2);
      lcd.print(cont);
      delay (500);

      break;

    case 3: // menu contador bombas de llenado
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("N\337 de ciclos llenado  ");

      llenado_A ();
      lcd.setCursor(0, 1);
      lcd.print("Llenado A =  ");
      lcd.setCursor(13, 1);
      lcd.print(cont2);

      llenado_B ();
      lcd.setCursor(0, 2);
      lcd.print("Llenado B = ");
      lcd.setCursor(13, 2);
      lcd.print(cont3);
      delay (500);

      break;



  }
}

alguna ayuda o idea por favor

Si, ya te ayudaremos, se paciente.
El programa esta mal hecho y tiene muchas cosas repetidas. Permítenos mirarlo y entenderlo con tranquilidad.

gracias por tu tiempo y me imagino q este mal si soy novato en esto