Agregar START y STOP a temporizador

Buen día compañeros, tengo un problema, estoy haciendo un temporizador y encontré un código muy buen pero el problema es que comienza la cuenta regresiva a penas se enciende el arduino, lo que quiero es agregarle un pulsador para comenzar y detener la cuenta regresiva pero no logro que funcione de la manera correcta, espero contar con su ayuda, por ahora estoy usando el tinkercad.
PD: hace 7 años que no programo un arduino

#include <LiquidCrystal.h>

//Crear el objeto LCD con los números correspondientes (rs, en, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
long hour = 17, minute = 59, second = 59;
long countdown_time = (hour * 3600) + (minute * 60) + second;
int exitloop = 0;
String stopwatch = "stop";
int start_time = 0;
const int rele = 8;
String action;
long timein[6], initialsecond = 0;
int i = 0;
const int startpin = 7, stoppin = 6;

void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(2, 0);
  lcd.print("TEMPORIZADOR");

  pinMode(startpin, INPUT);
  pinMode(stoppin, INPUT);
  pinMode(rele, OUTPUT);
}

void loop() {

  //Aquí comienza la cuenta regresiva
  long countdowntime_seconds = countdown_time - (millis() / 1000);
  if (countdowntime_seconds >= 0) {
    long countdown_hour = countdowntime_seconds / 3600;
    long countdown_minute = ((countdowntime_seconds / 60) % 60);
    long countdown_sec = countdowntime_seconds % 60;
    lcd.setCursor(4, 1);
    if (countdown_hour < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_hour);
    lcd.print(":");
    if (countdown_minute < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_minute);
    lcd.print(":");
    if (countdown_sec < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_sec);
    if (countdowntime_seconds == 0) {
      digitalWrite(rele, HIGH);
    }
  }
  delay(500);
}

Algo simple con dos botones conectados entre gnd y el pin.
Boton Start entre GND y pin 7.
Boton Stop entre GND y pin 6.

#include <LiquidCrystal.h>

//Crear el objeto LCD con los números correspondientes (rs, en, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long hour = 17, minute = 59, second = 59;
unsigned long countdown_time;
int exitloop = 0;
String stopwatch = "stop";
int start_time = 0;
const int rele = 8;
String action;
long timein[6], initialsecond = 0;
int i = 0;
const int startpin = 7, stoppin = 6;
int startButton, startButtonAnt = false;
int stopButton, stopButtonAnt = false;
int startCountDown = false;
unsigned long countdown_hour;
unsigned long countdown_minute;
unsigned long countdown_sec;
unsigned long countdowntime_seconds;

void presentoLCD() {
    lcd.setCursor(4, 1);
    if (countdown_hour < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_hour);
    lcd.print(":");
    if (countdown_minute < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_minute);
    lcd.print(":");
    if (countdown_sec < 10) {
      lcd.print("0");
    }
    lcd.print(countdown_sec);
    if (countdowntime_seconds == 0) {
      digitalWrite(rele, HIGH);
    }
}

void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(2, 0);
  lcd.print("TEMPORIZADOR");

  pinMode(startpin, INPUT_PULLUP);
  pinMode(stoppin, INPUT_PULLUP);
  pinMode(rele, OUTPUT);
}

void loop() {

  startButton = digitalRead(startpin);

  if (startButton && !startButtonAnt) {
      startCountDown = true;
      hour = 17, minute = 59, second = 59;
      countdown_time = (hour * 3600) + (minute * 60) + second;
  }
  startButtonAnt = startButton;

  stopButton = digitalRead(startpin);

  if (stopButton && !stopButtonAnt) {
      startCountDown = false;
  }
  stopButtonAnt = stopButton;


  if (startCountDown) {
      // Aquí comienza la cuenta regresiva
      countdowntime_seconds = countdown_time - (millis() / 1000);
      if (countdowntime_seconds >= 0) {
         countdown_hour = countdowntime_seconds / 3600;
         countdown_minute = ((countdowntime_seconds / 60) % 60);
         countdown_sec = countdowntime_seconds % 60;
      }
      presentoLCD();
  }
  delay(500);
}

He hecho del modo en que me indicaste, aunque ya anteriormente había intentado algo similar solamente que con resistencias en los pulsadores, aún así con el código que me entregaste no ha funcionado el programa, ahora lo hice con el Arduino, lee los estados de los pulsadores pero no cambia al contador.

Bueno solo requería unos ajustes.

#include <LiquidCrystal.h>

//Crear el objeto LCD con los números correspondientes (rs, en, d4, d5, d6, d7)
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

unsigned long hour = 17, minute = 59, second = 59;
unsigned long countdown_time;
int exitloop = 0;
String stopwatch = "stop";
int start_time = 0;
const int rele = 8;
String action;
long timein[6], initialsecond = 0;
int i = 0;
const int startpin = 7, stoppin = 6;
int startButton, startButtonAnt = false;
int stopButton, stopButtonAnt = false;
int startCountDown = false;
unsigned long countdown_hour;
unsigned long countdown_minute;
unsigned long countdown_sec, secAnt;
unsigned long countdowntime_seconds;

void presentoLCD() {
    char buffer[16];
    lcd.setCursor(4, 1);
    sprintf(buffer,"%02ld:%02ld:%02ld", countdown_hour,countdown_minute, countdown_sec);
    lcd.print(buffer);
    Serial.println(buffer);

    if (countdowntime_seconds == 0) {
      digitalWrite(rele, HIGH);
    }
}

void setup() {
  lcd.begin(16, 2);
  lcd.setCursor(2, 0);
  lcd.print("TEMPORIZADOR");

  pinMode(startpin, INPUT_PULLUP);
  pinMode(stoppin, INPUT_PULLUP);
  pinMode(rele, OUTPUT);
  Serial.begin(115200);
}

void loop() {

  startButton = digitalRead(startpin);

  if (!startButton && startButtonAnt) {
      
      lcd.setCursor(0, 0);
      //         0123456789012345
      lcd.print("    Encender    ");
      Serial.println("Encendido");
      startCountDown = true;
      hour = 17, minute = 59, second = 59;
      countdown_time = (hour * 3600) + (minute * 60) + second;
  }
  startButtonAnt = startButton;

  stopButton = digitalRead(stoppin);

  if (!stopButton && stopButtonAnt) {
      lcd.setCursor(0, 0);
       //         0123456789012345
       lcd.print("    Apagado     ");
       Serial.println("Apagado");
      startCountDown = false;
  }
  stopButtonAnt = stopButton;


  if (startCountDown) {
      // Aquí comienza la cuenta regresiva
      countdowntime_seconds = countdown_time - (millis() / 1000);
      if (countdowntime_seconds >= 0) {
         countdown_hour = countdowntime_seconds / 3600;
         countdown_minute = ((countdowntime_seconds / 60) % 60);
         countdown_sec = countdowntime_seconds % 60;
      }    
      if (countdown_sec != secAnt)
          presentoLCD();
      secAnt = countdown_sec;
  }
}

Lo puedes ver aca simulado creo.

Ahi dejé algunas mejoras.
Basicamente el uso de sprintf te permite programar tantas situaciones con if si es < 10. .
Defines una funcion que formatea la salida usando % para empezar a indicarlo
%0 el 0 indica que muestre 0 no significativos cuando se trata de unidades
%02 ese 2 indica la cantidad de digitos
lo que sigue depende del tipo de variable
entero, unsigned int o int es d
enterlo largo o sea unsigned long es ld
flotante o float es f
string es s
hexadecimal es x
etc, etc, etc

Sí funcionó, pero creo que expliqué mal lo que debe de hacer el botón de STOP y escribí que pare la cuenta regresiva y se entendió como que funciona como Pausa, en verdad lo que debe de hacer el botón de STOP es borrar toda la cuenta regresiva y tener que volver a presionar START para que comience nuevamente a contar regresivamente. Igualmente muchas gracias por tu ayuda, estoy viendo cómo tratar de modificar el tuyo y lo que había avanzado ayer para ver las modificaciones que debo de hacer para resolver el problema.

Bueno, trabaja un poco. No solo es copiar y pegar.

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