### Simple HMS Count Down Timer

Creator: Andrew Mascolo
Date: 11/7/2014

As the name implies, this is a Hour, Minute and Second timer. You can set the time as either direct HMS or just in seconds (See SetTimer() ). The SetTimer function also prevents overflow, meaning if seconds or minutes is greater than 59, the difference is taken and the result is added to either minutes or hours.

Example:
SetTimer(1, 0, 70) -> 1H, 1M, 10S
or
SetTimer(3665) -> 1H, 1M, 5S

## Functions:

CountDownTimer() : The timer itself (This is the constructor in the library)
Timer() : (This is the actual timer in the library)
TimeHasChanged() : This returns true if the time has changed (in seconds)
SetTimer() : Input the time to count from, Format: H,M,S or just seconds ie. 3600 = 1 hour
StartTimer() : Start the timer sequence
StopTimer() : Stops the Timer completely
StopTimerAt() : Stops the timer at a specific time, Format: H,M,S
PauseTimer() : Pauses the timer until told to resume
ResumeTimer() : Resume timer from where it was paused at
ResetTimer() : This starts the timer over from the initial setTime
TimeCheck() : Returns true if the time is equal to particular time
ShowMicroSeconds() : Returns the current Microseconds
ShowMilliSeconds() : Returns the current Milliseconds
ShowSeconds() : Returns the current Seconds
ShowMinutes() : Returns the current Minutes
ShowHours() : Returns the current Hours

# Sketch

```unsigned long Watch, _micro, time = micros();
unsigned int Clock = 0, R_clock;
boolean Reset = false, Stop = false, Paused = false;
volatile boolean timeFlag = false;

void setup()
{
Serial.begin(115200);
SetTimer(0,0,10); // 10 seconds
StartTimer();
}

void loop()
{
CountDownTimer(); // run the timer

// this prevents the time from being constantly shown.
if (TimeHasChanged() )
{
Serial.print(ShowHours());
Serial.print(":");
Serial.print(ShowMinutes());
Serial.print(":");
Serial.print(ShowSeconds());
Serial.print(":");
Serial.print(ShowMilliSeconds());
Serial.print(":");
Serial.println(ShowMicroSeconds());
// This DOES NOT format the time to 0:0x when seconds is less than 10.
// if you need to format the time to standard format, use the sprintf() function.
}
}

boolean CountDownTimer()
{
static unsigned long duration = 1000000; // 1 second
timeFlag = false;

if (!Stop && !Paused) // if not Stopped or Paused, run timer
{
// check the time difference and see if 1 second has elapsed
if ((_micro = micros()) - time > duration )
{
Clock--;
timeFlag = true;

if (Clock == 0) // check to see if the clock is 0
Stop = true; // If so, stop the timer

// check to see if micros() has rolled over, if not,
// then increment "time" by duration
_micro < time ? time = _micro : time += duration;
}
}
return !Stop; // return the state of the timer
}

void ResetTimer()
{
SetTimer(R_clock);
Stop = false;
}

void StartTimer()
{
Watch = micros(); // get the initial microseconds at the start of the timer
time = micros(); // hwd added so timer will reset if stopped and then started
Stop = false;
Paused = false;
}

void StopTimer()
{
Stop = true;
}

void StopTimerAt(unsigned int hours, unsigned int minutes, unsigned int seconds)
{
if (TimeCheck(hours, minutes, seconds) )
Stop = true;
}

void PauseTimer()
{
Paused = true;
}

void ResumeTimer() // You can resume the timer if you ever stop it.
{
Paused = false;
}

void SetTimer(unsigned int hours, unsigned int minutes, unsigned int seconds)
{
// This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1, 2, 0
unsigned int _S = (seconds / 60), _M = (minutes / 60);
if(_S) minutes += _S;
if(_M) hours += _M;

Clock = (hours * 3600) + (minutes * 60) + (seconds % 60);
R_clock = Clock;
Stop = false;
}

void SetTimer(unsigned int seconds)
{
// StartTimer(seconds / 3600, (seconds / 3600) / 60, seconds % 60);
Clock = seconds;
R_clock = Clock;
Stop = false;
}

int ShowHours()
{
return Clock / 3600;
}

int ShowMinutes()
{
return (Clock / 60) % 60;
}

int ShowSeconds()
{
return Clock % 60;
}

unsigned long ShowMilliSeconds()
{
return (_micro - Watch)/ 1000.0;
}

unsigned long ShowMicroSeconds()
{
return _micro - Watch;
}

boolean TimeHasChanged()
{
return timeFlag;
}

// output true if timer equals requested time
boolean TimeCheck(unsigned int hours, unsigned int minutes, unsigned int seconds)
{
return (hours == ShowHours() && minutes == ShowMinutes() && seconds == ShowSeconds());
}

```

## Output:

```H:M:S:Mil:Mic
0:0:9:999:999916
0:0:8:1999:1999912
0:0:7:2999:2999916
0:0:6:3999:3999912
0:0:5:4999:4999912
0:0:4:5999:5999920
0:0:3:6999:6999920
0:0:2:7999:7999916
0:0:1:8999:8999916
0:0:0:9999:9999912

```