// I have mistakenly used word 'timer' instead of 'stop watch'.
// Sorry :-)
#include <TM1637Display.h>
#include <Stepper.h>
#define RESTART_SWITCH_PIN 5 // PushButton
#define PAUSE_SWITCH_PIN 2 // PushButton
#define INPUT_NONE 0
#define INPUT_PAUSE 1
#define INPUT_RESTART 2
#define DIO_PIN 4 // TM1637's DIO pin
#define CLK_PIN 3 // TM1637's CLK pin
#define COLON 0b11100000 // for use with
// TM1637Display::showNumberDecEx()
int input; // contains one of the above defined 'INPUT_*' values
int secs = 0; // timer's seconds
int mins = 0; // timer's minutes
int f_secs = 0; // formatted time as that is printed
double next_secs_inc_millis = 0; /* return value of next millis()
when secs should be incremented*/
double last_stopped_millis = 0; /* millis() when the timer was
stopped last time */
bool timer_running = 0; // is timer currently running?
TM1637Display display = TM1637Display(CLK_PIN, DIO_PIN);
// Resets the timer
void timer_reset(void) {
secs = 0;
mins = 0;
timer_running = 0;
display.showNumberDecEx(0000, COLON, true);
}
// Toggles between start and stop of timer
void timer_pause(void) {
if(timer_running) {
//! timer was running already
last_stopped_millis = millis();
}
timer_running = !timer_running; // toggle timer_running status
next_secs_inc_millis = last_stopped_millis+1000; /* so that
timer_run() increments immediately after this function call*/
}
// Displays and increments time
void timer_run(void) {
if(!(secs%60) && (secs>=60)) {
secs = 0;
mins++;
}
// ex. of formatted time: 0102 (mins,secs)
f_secs = (mins*100)+secs;
display.showNumberDecEx(f_secs, COLON, true);
double crr_millis = millis();
if(crr_millis >= next_secs_inc_millis) {
secs += 1;
next_secs_inc_millis = crr_millis+1000;
}
}
// Program's entry point
void setup() {
// Serial.begin(9600); // for debugging
// pinMode(LED_BUILTIN, OUTPUT); // for debugging
display.setBrightness(5);
display.clear();
pinMode(RESTART_SWITCH_PIN, INPUT);
pinMode(PAUSE_SWITCH_PIN, INPUT);
timer_reset();
}
// Interprets and returns button inputs: Pause and Reset
int take_input(void) {
static int prev_restart_val = LOW, prev_pause_val = LOW;
static int restart_val = LOW, pause_val = LOW;
prev_restart_val = restart_val;
prev_pause_val = pause_val;
restart_val = digitalRead(RESTART_SWITCH_PIN);
pause_val = digitalRead(PAUSE_SWITCH_PIN);
if(pause_val == LOW && prev_pause_val == HIGH) {
//! pause button just released
// Serial.println("Pause pressed!"); // for debugging
return INPUT_PAUSE;
} else if(restart_val == LOW && prev_restart_val == HIGH) {
//! restart button just released
// Serial.println("Restart pressed!"); // for debugging
return INPUT_RESTART;
}
return INPUT_NONE;
}
// The main loop of the program
void loop() {
input = take_input();
switch(input) {
case INPUT_NONE:
if(timer_running) { timer_run(); }
break;
case INPUT_PAUSE:
timer_pause();
break;
case INPUT_RESTART:
timer_reset();
break;
}
delay(10); // give some delay to save processing power
}