forked from bhagman/MillisTimer
-
Notifications
You must be signed in to change notification settings - Fork 0
/
MillisTimer.cpp
187 lines (153 loc) · 3.21 KB
/
MillisTimer.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
/*
|| @author Brett Hagman <bhagman@wiring.org.co>
|| @url http://wiring.org.co/
||
|| @description
|| | Timer Library for working with millis().
|| | It provides an easy way to have a recurring action.
|| |
|| | Wiring Cross-platform Library
|| #
||
|| @license Please see the accompanying LICENSE.txt file for this project.
||
*/
#include "MillisTimer.h"
// Constructor
MillisTimer::MillisTimer(uint32_t interval, timerEventHandler handler)
{
m_interval = interval;
m_state = STOPPED; // Stopped
m_repeat = m_repeatCount = 0; // Repeat indefinitely
m_targetTime = millis() + interval;
m_remainingTime = 0;
cb_onExpired = handler;
}
bool MillisTimer::isRunning() const
{
return (m_state == RUNNING);
}
void MillisTimer::run()
{
expired();
}
bool MillisTimer::expired()
{
// Only if we're running
if (m_state == RUNNING)
{
// If we have passed the target time...
if (millis() >= m_targetTime)
{
// Calculate repeat. If repeat = 0, then we
// repeat forever until stopped.
// Otherwise, when we've hit the last repeat (1),
// then we stop.
if (m_repeatCount != 1)
{
if (m_repeatCount > 0)
{
m_repeatCount--;
}
// Set the new target (based on our last target time
// for accuracy)
m_targetTime += m_interval;
}
else
{
m_state = EXPIRED;
}
// Fire the call back.
if (cb_onExpired)
{
cb_onExpired(*this);
}
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
void MillisTimer::stop()
{
m_state = STOPPED;
// If we have stopped before the target time,
// let's save the remaining time so we can resume later.
if (millis() < m_targetTime)
{
m_remainingTime = m_targetTime - millis();
}
}
// Start the timer.
void MillisTimer::start()
{
startFrom(millis());
}
// Start from a specific time provided.
void MillisTimer::startFrom(uint32_t startTime)
{
m_state = RUNNING;
// If we have some remaining time, then let's use that.
if (m_remainingTime > 0)
{
m_targetTime = startTime + m_remainingTime;
m_remainingTime = 0;
}
else
{
// otherwise, we start normally
m_targetTime = startTime + m_interval;
}
}
// Arbitrarily set the target time.
void MillisTimer::setTargetTime(uint32_t targetTime)
{
m_targetTime = targetTime;
}
// Reset the timer. Stop, and reset repeat count.
void MillisTimer::reset()
{
m_state = STOPPED;
m_remainingTime = 0;
m_repeatCount = m_repeat;
}
void MillisTimer::setInterval(uint32_t interval)
{
m_interval = interval;
}
void MillisTimer::setRepeats(uint32_t repeatCount)
{
m_repeat = m_repeatCount = repeatCount;
}
void MillisTimer::expiredHandler(timerEventHandler handler)
{
cb_onExpired = handler;
}
uint32_t MillisTimer::getTargetTime() const
{
return m_targetTime;
}
uint32_t MillisTimer::getRemainingTime() const
{
if (m_state == RUNNING)
{
return m_targetTime - millis();
}
else
{
return m_remainingTime;
}
}
uint32_t MillisTimer::getRemainingRepeats() const
{
if (m_state == EXPIRED && m_repeatCount == 1)
return 0;
else
return m_repeatCount;
}