Para que todo esto?
if (milisegundos % 100 == 0) {
decimas++;
// Si han pasado 10 décimas de segundo se cuenta un segundo
if (decimas == 10) {
decimas = 0;
segundos++;
}
// Si han pasado 60 segundos se cuenta un minuto
if (segundos == 60) {
segundos = 0;
minutos++;
}
// Si han pasado 60 minutos se cuenta una hora
if (minutos == 60) {
minutos = 0;
horas++;
}
Si ya lleva la cuenta millis(). Volver a contar lo que ya esta contabilizado es una pérdida de tiempo.
Solo opera con dos variables, una que capture el momento en el que empiezas, tu Start o Arranque y otro en el que terminas, tu Stop o Fin. Restas millis() y listo y presentas convirtiendo millis() a h:m:s.xxxx lo que gustes.
Esta es una versión funcional, solo muestra hh:mm:ss asi que amplia a tu gusto
#include <LiquidCrystal_I2C.h>
#include <Wire.h>
LiquidCrystal_I2C lcd(0x27, 2, 1, 0, 4, 5, 6, 7, 3, POSITIVE);
// Variables para los cálculos internos del cronómetro
int horas = 0;
int minutos = 0;
int segundos = 0;
int decimas = 0;
int contador = 0;
unsigned long startTime, stopTime;
bool start, startAnt = false;
bool stop, stopAnt = false;
bool reset, resetAnt = false;
int boton_resta = 7; // restar unidades contador
int boton_reset = 8; // resetear contador y cronometro
int sensor_inicio = 9; // pulsador_inicio en PIN digital 10
int sensor_fin = 10; // pulsador_pausa en PIN digital 9
bool flag = false;
bool freset = false;
// estas variables son para simular
byte estado = 0;
unsigned long demoro;
//char *convertirSegundosAHMmSs(long seconds) {
void convertirSegundosAHMmSs(unsigned long seconds) {
static unsigned long secondsAnt = 0;
char tmp[20];
int s = seconds % 60;
int m = (seconds / 60) % 60;
int h = (seconds / (60 * 60)) % 24;
sprintf(tmp, "%02d:%02d:%02d", h,m,s);
if (seconds != secondsAnt) {
Serial.println("Recibidos: " + String(seconds));
Serial.println(tmp);
}
secondsAnt = seconds;
//return tmp;
}
void setup() {
Serial.begin(115200); // Comienzo de la comunicación serie
Serial.println("Iniciando programa.");
pinMode(sensor_inicio, INPUT_PULLUP); // Pin digital 10 como entrada
pinMode(sensor_fin, INPUT_PULLUP); // Pin digital 9 como entrada
pinMode(boton_reset, INPUT); // Pin digital 8 como entrada
pinMode(boton_resta, INPUT); // Pin digital 7 como entrada
// Inicializamos el LCD
lcd.begin(16, 2);
lcd.backlight();
}
void (*resetFunc)(void) = 0; // declare reset function at address 0
void loop() {
// Si presionamos el pulsador de inicio se pone todo a cero, se reinicia em
// cronómetro y se suma una unidad al contador
//start = digitalRead(sensor_inicio);
// stop = digitalRead(sensor_fin);
//reset = digitalRead(boton_reset);
// switch(estado) {
// case 0: // arranco
// start = true;
// estado = true;
// demoro = millis();
// break;
// case 1: start = 0;
// estado = 2;
// break;
// case 2: if (millis() - demoro > 10000UL) {
// stop = true;
// estado = 3;
// }
// break;
// case 3: stop = 0;
// estado = 4;
// demoro = millis();
// break;
// case 4: if (millis() - demoro > 4000UL) {
// reset = true;
// estado = 5;
// }
// break;
// case 5: if (millis() - demoro > 5000UL) {
// reset = false;
// estado = 6;
// }
// break;
// case 6: // vuelvo a empezar
// estado = 0;
// break;
// }
if (start && !startAnt) { // siempre usa este criterio. El de mirar el flanco no un estado.
startTime = millis();
flag = true;
freset = false;
}
startAnt = start;
if (stop && !stopAnt) { // siempre usa este criterio. El de mirar el flanco no un estado.
stopTime = millis()-startTime;
flag = false;
}
stopAnt = stop;
if (reset && !resetAnt) { // siempre usa este criterio. El de mirar el flanco no un estado.
freset = true;
}
resetAnt = reset;
if (freset)
//Serial.println(convertirSegundosAHMmSs(0));
convertirSegundosAHMmSs(0);
else {
if (flag) {
//Serial.println(convertirSegundosAHMmSs(startTime/1000));
convertirSegundosAHMmSs(startTime/1000);
}
else {
//Serial.println(convertirSegundosAHMmSs(stopTime/1000));
convertirSegundosAHMmSs(stopTime/1000);
}
}
}