1 | /* Count Up/Down Timer */
|
2 |
|
3 | /*
|
4 | Helpful Corrections by:
|
5 | Github user Mannelito - Correction to ResumeTimer function
|
6 | */
|
7 | /*
|
8 | The MIT License (MIT)
|
9 |
|
10 | Copyright (c) 2016 Andrew Mascolo Jr
|
11 |
|
12 | Permission is hereby granted, free of charge, to any person obtaining a copy
|
13 | of this software and associated documentation files (the "Software"), to deal
|
14 | in the Software without restriction, including without limitation the rights
|
15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
16 | copies of the Software, and to permit persons to whom the Software is
|
17 | furnished to do so, subject to the following conditions:
|
18 |
|
19 | The above copyright notice and this permission notice shall be included in all
|
20 | copies or substantial portions of the Software.
|
21 |
|
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
28 | SOFTWARE.
|
29 |
|
30 | */
|
31 |
|
32 | #ifndef CountUpDownTimer_h
|
33 | #define CountUpDownTimer_h
|
34 |
|
35 | #include<Arduino.h>
|
36 | #define UP 1
|
37 | #define DOWN 0
|
38 |
|
39 | class CountUpDownTimer
|
40 | {
|
41 | public:
|
42 | CountUpDownTimer(bool type, bool precision = LOW) : _type(type), _precision(precision)
|
43 | {
|
44 | SetStopTime((type? 0xFFFF : 0)); // 18h 12m 15s
|
45 | time = precision ? micros() : millis();
|
46 | Clock = 0;
|
47 | Reset = false, Stop = true, Paused = true;
|
48 | timeFlag = false;
|
49 | duration = precision ? 1000000 : 1000;
|
50 | }
|
51 | unsigned long _InternalClock()
|
52 | {
|
53 | return _precision ? micros() : millis();
|
54 | }
|
55 |
|
56 | boolean Timer()
|
57 | {
|
58 | timeFlag = false;
|
59 | if (!Stop && !Paused) // if not Stopped or Paused, run timer
|
60 | {
|
61 | if(Paused)
|
62 | time = _InternalClock();
|
63 |
|
64 | if ((_intTime = _InternalClock() ) - time > duration ) // check the time difference and see if 1 second has elapsed
|
65 | {
|
66 | _type == UP? Clock++ : Clock--;
|
67 |
|
68 | timeFlag = true;
|
69 |
|
70 | if ((_type == DOWN && Clock == 0) || TimeCheck()) // check to see if the clock is 0
|
71 | Stop = true; // If so, stop the timer
|
72 |
|
73 | time = _intTime;
|
74 |
|
75 | if(_intTime < time)
|
76 | time = 0; // check to see if micros() has rolled over, if not, then increment "time" by duration
|
77 | }
|
78 | }
|
79 |
|
80 | return !Stop; // return the state of the timer
|
81 | }
|
82 |
|
83 | void ResetTimer()
|
84 | {
|
85 | if(_type)
|
86 | Clock = 0;
|
87 | else
|
88 | SetTimer(R_clock);
|
89 | Stop = false;
|
90 | }
|
91 |
|
92 | void StartTimer()
|
93 | {
|
94 | Watch = _InternalClock();
|
95 | Stop = false;
|
96 | Paused = false;
|
97 | // if(_type == UP)
|
98 | // Clock = 0;
|
99 | }
|
100 |
|
101 | void StopTimer()
|
102 | {
|
103 | Stop = true;
|
104 | }
|
105 |
|
106 | void StopTimerAt(unsigned long hours, unsigned long minutes, unsigned long seconds)
|
107 | {
|
108 | if (TimeCheck(hours, minutes, seconds) )
|
109 | Stop = true;
|
110 | }
|
111 |
|
112 | void PauseTimer()
|
113 | {
|
114 | time = _InternalClock();
|
115 | Paused = true;
|
116 | }
|
117 |
|
118 | void ResumeTimer() // You can resume the timer if you ever stop it.
|
119 | {
|
120 | Paused = false;
|
121 | time = _InternalClock();
|
122 | }
|
123 |
|
124 | void SetTimer(unsigned long hours, unsigned long minutes, unsigned long seconds)
|
125 | {
|
126 | // This handles invalid time overflow ie 1(H), 0(M), 120(S) -> 1h, 2m, 0s
|
127 | unsigned int _S = (seconds / 60), _M = (minutes / 60);
|
128 | if(_S) minutes += _S;
|
129 | if(_M) hours += _M;
|
130 |
|
131 | Clock = (hours * 3600) + (minutes * 60) + (seconds % 60);
|
132 | R_clock = Clock;
|
133 | Stop = false;
|
134 | }
|
135 |
|
136 | void SetTimer(unsigned long seconds)
|
137 | {
|
138 | // StartTimer(seconds / 3600, (seconds / 3600) / 60, seconds % 60);
|
139 | Clock = seconds;
|
140 | R_clock = Clock;
|
141 | Stop = false;
|
142 | }
|
143 |
|
144 | void SetStopTime(unsigned long seconds)
|
145 | {
|
146 | STh = seconds / 3600;
|
147 | STm = (seconds / 60) % 60;
|
148 | STs = seconds % 60;
|
149 | STotaltime = seconds;
|
150 | }
|
151 |
|
152 | void SetStopTime(unsigned long hours, unsigned long minutes, unsigned long seconds)
|
153 | {
|
154 | STh = hours;
|
155 | STm = minutes;
|
156 | STs = seconds;
|
157 | STotaltime = (hours * 3600) + (minutes * 60) + (seconds % 60);
|
158 | }
|
159 |
|
160 | unsigned long ShowHours()
|
161 | {
|
162 | return Clock / 3600;
|
163 | }
|
164 |
|
165 | unsigned long ShowMinutes()
|
166 | {
|
167 | return (Clock / 60) % 60;
|
168 | }
|
169 |
|
170 | unsigned long ShowSeconds()
|
171 | {
|
172 | return Clock % 60;
|
173 | }
|
174 |
|
175 | unsigned long ShowMilliSeconds()
|
176 | {
|
177 | if (_precision == HIGH)
|
178 | return ((_intTime - Watch)/ 1000.0) + 1;
|
179 | else
|
180 | return (_intTime - Watch) + 1;
|
181 | }
|
182 |
|
183 | unsigned long ShowMicroSeconds()
|
184 | {
|
185 | if (_precision == LOW)
|
186 | return ((_intTime - Watch)/ 1000.0) + 1;
|
187 | else
|
188 | return (_intTime - Watch) + 1;
|
189 | }
|
190 |
|
191 | unsigned long ShowTotalSeconds()
|
192 | {
|
193 | return Clock;
|
194 | }
|
195 |
|
196 | unsigned long ShowStopTime()
|
197 | {
|
198 | return STotaltime;
|
199 | }
|
200 |
|
201 | boolean TimeHasChanged()
|
202 | {
|
203 | return timeFlag;
|
204 | }
|
205 |
|
206 | boolean TimeCheck(unsigned int hours, unsigned int minutes, unsigned int seconds) // output true if timer equals requested time or has passed it.
|
207 | {
|
208 | unsigned long TC = ((hours * 3600) + (minutes * 60) + (seconds % 60));
|
209 | if(_type)
|
210 | return (Clock >= TC);
|
211 | else
|
212 | return (Clock <= TC);
|
213 | }
|
214 |
|
215 | boolean TimeCheck() // output true if timer equals requested time or has passed it.
|
216 | {
|
217 | if(_type)
|
218 | return Clock >= STotaltime;
|
219 | else
|
220 | return Clock <= STotaltime;
|
221 | }
|
222 | boolean Stop;
|
223 | private:
|
224 | unsigned long duration;
|
225 | unsigned long STh, STm, STs, STotaltime;
|
226 | unsigned long Watch, _intTime, time;
|
227 | unsigned long Clock, R_clock;
|
228 | boolean Reset, Paused;
|
229 | volatile boolean timeFlag;
|
230 | bool _type, _precision;
|
231 | };
|
232 |
|
233 | #endif
|