work.

Dependencies:   Blynk mbed

Committer:
lixianyu
Date:
Thu Jun 16 08:12:33 2016 +0000
Revision:
4:e5018e5ba340
Parent:
2:6cd3b0947188
ok

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lixianyu 2:6cd3b0947188 1 /*
lixianyu 2:6cd3b0947188 2 * SimpleTimer.cpp
lixianyu 2:6cd3b0947188 3 *
lixianyu 2:6cd3b0947188 4 * SimpleTimer - A timer library for Arduino.
lixianyu 2:6cd3b0947188 5 * Author: mromani@ottotecnica.com
lixianyu 2:6cd3b0947188 6 * Copyright (c) 2010 OTTOTECNICA Italy
lixianyu 2:6cd3b0947188 7 *
lixianyu 2:6cd3b0947188 8 * This library is free software; you can redistribute it
lixianyu 2:6cd3b0947188 9 * and/or modify it under the terms of the GNU Lesser
lixianyu 2:6cd3b0947188 10 * General Public License as published by the Free Software
lixianyu 2:6cd3b0947188 11 * Foundation; either version 2.1 of the License, or (at
lixianyu 2:6cd3b0947188 12 * your option) any later version.
lixianyu 2:6cd3b0947188 13 *
lixianyu 2:6cd3b0947188 14 * This library is distributed in the hope that it will
lixianyu 2:6cd3b0947188 15 * be useful, but WITHOUT ANY WARRANTY; without even the
lixianyu 2:6cd3b0947188 16 * implied warranty of MERCHANTABILITY or FITNESS FOR A
lixianyu 2:6cd3b0947188 17 * PARTICULAR PURPOSE. See the GNU Lesser General Public
lixianyu 2:6cd3b0947188 18 * License for more details.
lixianyu 2:6cd3b0947188 19 *
lixianyu 2:6cd3b0947188 20 * You should have received a copy of the GNU Lesser
lixianyu 2:6cd3b0947188 21 * General Public License along with this library; if not,
lixianyu 2:6cd3b0947188 22 * write to the Free Software Foundation, Inc.,
lixianyu 2:6cd3b0947188 23 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
lixianyu 2:6cd3b0947188 24 */
lixianyu 2:6cd3b0947188 25
lixianyu 2:6cd3b0947188 26 #include "mbed.h"
lixianyu 2:6cd3b0947188 27 #include "SimpleTimer.h"
lixianyu 2:6cd3b0947188 28
lixianyu 2:6cd3b0947188 29
lixianyu 2:6cd3b0947188 30 // Select time function:
lixianyu 2:6cd3b0947188 31 /*
lixianyu 2:6cd3b0947188 32 inline unsigned long SimpleTimer::elapsed()
lixianyu 2:6cd3b0947188 33 {
lixianyu 2:6cd3b0947188 34 return _timer.read_us();
lixianyu 2:6cd3b0947188 35 }
lixianyu 2:6cd3b0947188 36 */
lixianyu 2:6cd3b0947188 37 int SimpleTimer::elapsed()
lixianyu 2:6cd3b0947188 38 {
lixianyu 2:6cd3b0947188 39 return _timer.read_ms();
lixianyu 2:6cd3b0947188 40 }
lixianyu 2:6cd3b0947188 41
lixianyu 2:6cd3b0947188 42 SimpleTimer::SimpleTimer(Timer &timer) : _timer(timer)
lixianyu 2:6cd3b0947188 43 {
lixianyu 2:6cd3b0947188 44 int current_millis = elapsed();
lixianyu 2:6cd3b0947188 45
lixianyu 2:6cd3b0947188 46 for (int i = 0; i < MAX_TIMERS; i++) {
lixianyu 2:6cd3b0947188 47 enabled[i] = false;
lixianyu 2:6cd3b0947188 48 callbacks[i] = 0; // If the callback pointer is zero, the slot is free, i.e. doesn't "contain" any timer
lixianyu 2:6cd3b0947188 49 prev_millis[i] = current_millis;
lixianyu 2:6cd3b0947188 50 numRuns[i] = 0;
lixianyu 2:6cd3b0947188 51 }
lixianyu 2:6cd3b0947188 52
lixianyu 2:6cd3b0947188 53 numTimers = 0;
lixianyu 2:6cd3b0947188 54 }
lixianyu 2:6cd3b0947188 55
lixianyu 2:6cd3b0947188 56 void SimpleTimer::run()
lixianyu 2:6cd3b0947188 57 {
lixianyu 2:6cd3b0947188 58 int i;
lixianyu 2:6cd3b0947188 59 int current_millis;
lixianyu 2:6cd3b0947188 60
lixianyu 2:6cd3b0947188 61 // get current time
lixianyu 2:6cd3b0947188 62 current_millis = elapsed();
lixianyu 2:6cd3b0947188 63
lixianyu 2:6cd3b0947188 64 for (i = 0; i < MAX_TIMERS; i++) {
lixianyu 2:6cd3b0947188 65
lixianyu 2:6cd3b0947188 66 toBeCalled[i] = DEFCALL_DONTRUN;
lixianyu 2:6cd3b0947188 67
lixianyu 2:6cd3b0947188 68 // no callback == no timer, i.e. jump over empty slots
lixianyu 2:6cd3b0947188 69 if (callbacks[i]) {
lixianyu 2:6cd3b0947188 70
lixianyu 2:6cd3b0947188 71 // is it time to process this timer ?
lixianyu 2:6cd3b0947188 72 // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
lixianyu 2:6cd3b0947188 73
lixianyu 2:6cd3b0947188 74 if (current_millis - prev_millis[i] >= delays[i]) {
lixianyu 2:6cd3b0947188 75
lixianyu 2:6cd3b0947188 76 // update time
lixianyu 2:6cd3b0947188 77 //prev_millis[i] = current_millis;
lixianyu 2:6cd3b0947188 78 prev_millis[i] += delays[i];
lixianyu 2:6cd3b0947188 79
lixianyu 2:6cd3b0947188 80 // check if the timer callback has to be executed
lixianyu 2:6cd3b0947188 81 if (enabled[i]) {
lixianyu 2:6cd3b0947188 82
lixianyu 2:6cd3b0947188 83 // "run forever" timers must always be executed
lixianyu 2:6cd3b0947188 84 if (maxNumRuns[i] == RUN_FOREVER) {
lixianyu 2:6cd3b0947188 85 toBeCalled[i] = DEFCALL_RUNONLY;
lixianyu 2:6cd3b0947188 86 }
lixianyu 2:6cd3b0947188 87 // other timers get executed the specified number of times
lixianyu 2:6cd3b0947188 88 else if (numRuns[i] < maxNumRuns[i]) {
lixianyu 2:6cd3b0947188 89 toBeCalled[i] = DEFCALL_RUNONLY;
lixianyu 2:6cd3b0947188 90 numRuns[i]++;
lixianyu 2:6cd3b0947188 91
lixianyu 2:6cd3b0947188 92 // after the last run, delete the timer
lixianyu 2:6cd3b0947188 93 if (numRuns[i] >= maxNumRuns[i]) {
lixianyu 2:6cd3b0947188 94 toBeCalled[i] = DEFCALL_RUNANDDEL;
lixianyu 2:6cd3b0947188 95 }
lixianyu 2:6cd3b0947188 96 }
lixianyu 2:6cd3b0947188 97 }
lixianyu 2:6cd3b0947188 98 }
lixianyu 2:6cd3b0947188 99 }
lixianyu 2:6cd3b0947188 100 }
lixianyu 2:6cd3b0947188 101
lixianyu 2:6cd3b0947188 102 for (i = 0; i < MAX_TIMERS; i++) {
lixianyu 2:6cd3b0947188 103 switch(toBeCalled[i]) {
lixianyu 2:6cd3b0947188 104 case DEFCALL_DONTRUN:
lixianyu 2:6cd3b0947188 105 break;
lixianyu 2:6cd3b0947188 106
lixianyu 2:6cd3b0947188 107 case DEFCALL_RUNONLY:
lixianyu 2:6cd3b0947188 108 callbacks[i]();
lixianyu 2:6cd3b0947188 109 break;
lixianyu 2:6cd3b0947188 110
lixianyu 2:6cd3b0947188 111 case DEFCALL_RUNANDDEL:
lixianyu 2:6cd3b0947188 112 callbacks[i]();
lixianyu 2:6cd3b0947188 113 deleteTimer(i);
lixianyu 2:6cd3b0947188 114 break;
lixianyu 2:6cd3b0947188 115 }
lixianyu 2:6cd3b0947188 116 }
lixianyu 2:6cd3b0947188 117 }
lixianyu 2:6cd3b0947188 118
lixianyu 2:6cd3b0947188 119
lixianyu 2:6cd3b0947188 120 // find the first available slot
lixianyu 2:6cd3b0947188 121 // return -1 if none found
lixianyu 2:6cd3b0947188 122 int SimpleTimer::findFirstFreeSlot()
lixianyu 2:6cd3b0947188 123 {
lixianyu 2:6cd3b0947188 124 int i;
lixianyu 2:6cd3b0947188 125
lixianyu 2:6cd3b0947188 126 // all slots are used
lixianyu 2:6cd3b0947188 127 if (numTimers >= MAX_TIMERS) {
lixianyu 2:6cd3b0947188 128 return -1;
lixianyu 2:6cd3b0947188 129 }
lixianyu 2:6cd3b0947188 130
lixianyu 2:6cd3b0947188 131 // return the first slot with no callback (i.e. free)
lixianyu 2:6cd3b0947188 132 for (i = 0; i < MAX_TIMERS; i++) {
lixianyu 2:6cd3b0947188 133 if (callbacks[i] == 0) {
lixianyu 2:6cd3b0947188 134 return i;
lixianyu 2:6cd3b0947188 135 }
lixianyu 2:6cd3b0947188 136 }
lixianyu 2:6cd3b0947188 137
lixianyu 2:6cd3b0947188 138 // no free slots found
lixianyu 2:6cd3b0947188 139 return -1;
lixianyu 2:6cd3b0947188 140 }
lixianyu 2:6cd3b0947188 141
lixianyu 2:6cd3b0947188 142
lixianyu 2:6cd3b0947188 143 int SimpleTimer::setTimer(int d, timer_callback f, int n)
lixianyu 2:6cd3b0947188 144 {
lixianyu 2:6cd3b0947188 145 int freeTimer;
lixianyu 2:6cd3b0947188 146
lixianyu 2:6cd3b0947188 147 freeTimer = findFirstFreeSlot();
lixianyu 2:6cd3b0947188 148 if (freeTimer < 0) {
lixianyu 2:6cd3b0947188 149 return -1;
lixianyu 2:6cd3b0947188 150 }
lixianyu 2:6cd3b0947188 151
lixianyu 2:6cd3b0947188 152 if (f == NULL) {
lixianyu 2:6cd3b0947188 153 return -1;
lixianyu 2:6cd3b0947188 154 }
lixianyu 2:6cd3b0947188 155
lixianyu 2:6cd3b0947188 156 delays[freeTimer] = d;
lixianyu 2:6cd3b0947188 157 callbacks[freeTimer] = f;
lixianyu 2:6cd3b0947188 158 maxNumRuns[freeTimer] = n;
lixianyu 2:6cd3b0947188 159 enabled[freeTimer] = true;
lixianyu 2:6cd3b0947188 160 prev_millis[freeTimer] = elapsed();
lixianyu 2:6cd3b0947188 161
lixianyu 2:6cd3b0947188 162 numTimers++;
lixianyu 2:6cd3b0947188 163
lixianyu 2:6cd3b0947188 164 return freeTimer;
lixianyu 2:6cd3b0947188 165 }
lixianyu 2:6cd3b0947188 166
lixianyu 2:6cd3b0947188 167
lixianyu 2:6cd3b0947188 168 int SimpleTimer::setInterval(int d, timer_callback f)
lixianyu 2:6cd3b0947188 169 {
lixianyu 2:6cd3b0947188 170 return setTimer(d, f, RUN_FOREVER);
lixianyu 2:6cd3b0947188 171 }
lixianyu 2:6cd3b0947188 172
lixianyu 2:6cd3b0947188 173
lixianyu 2:6cd3b0947188 174 int SimpleTimer::setTimeout(int d, timer_callback f)
lixianyu 2:6cd3b0947188 175 {
lixianyu 2:6cd3b0947188 176 return setTimer(d, f, RUN_ONCE);
lixianyu 2:6cd3b0947188 177 }
lixianyu 2:6cd3b0947188 178
lixianyu 2:6cd3b0947188 179
lixianyu 2:6cd3b0947188 180 void SimpleTimer::deleteTimer(int timerId)
lixianyu 2:6cd3b0947188 181 {
lixianyu 2:6cd3b0947188 182 if (timerId >= MAX_TIMERS) {
lixianyu 2:6cd3b0947188 183 return;
lixianyu 2:6cd3b0947188 184 }
lixianyu 2:6cd3b0947188 185
lixianyu 2:6cd3b0947188 186 // nothing to delete if no timers are in use
lixianyu 2:6cd3b0947188 187 if (numTimers == 0) {
lixianyu 2:6cd3b0947188 188 return;
lixianyu 2:6cd3b0947188 189 }
lixianyu 2:6cd3b0947188 190
lixianyu 2:6cd3b0947188 191 // don't decrease the number of timers if the
lixianyu 2:6cd3b0947188 192 // specified slot is already empty
lixianyu 2:6cd3b0947188 193 if (callbacks[timerId] != NULL) {
lixianyu 2:6cd3b0947188 194 callbacks[timerId] = 0;
lixianyu 2:6cd3b0947188 195 enabled[timerId] = false;
lixianyu 2:6cd3b0947188 196 toBeCalled[timerId] = DEFCALL_DONTRUN;
lixianyu 2:6cd3b0947188 197 delays[timerId] = 0;
lixianyu 2:6cd3b0947188 198 numRuns[timerId] = 0;
lixianyu 2:6cd3b0947188 199
lixianyu 2:6cd3b0947188 200 // update number of timers
lixianyu 2:6cd3b0947188 201 numTimers--;
lixianyu 2:6cd3b0947188 202 }
lixianyu 2:6cd3b0947188 203 }
lixianyu 2:6cd3b0947188 204
lixianyu 2:6cd3b0947188 205
lixianyu 2:6cd3b0947188 206 // function contributed by code@rowansimms.com
lixianyu 2:6cd3b0947188 207 void SimpleTimer::restartTimer(int numTimer)
lixianyu 2:6cd3b0947188 208 {
lixianyu 2:6cd3b0947188 209 if (numTimer >= MAX_TIMERS) {
lixianyu 2:6cd3b0947188 210 return;
lixianyu 2:6cd3b0947188 211 }
lixianyu 2:6cd3b0947188 212
lixianyu 2:6cd3b0947188 213 prev_millis[numTimer] = elapsed();
lixianyu 2:6cd3b0947188 214 }
lixianyu 2:6cd3b0947188 215
lixianyu 2:6cd3b0947188 216
lixianyu 2:6cd3b0947188 217 bool SimpleTimer::isEnabled(int numTimer)
lixianyu 2:6cd3b0947188 218 {
lixianyu 2:6cd3b0947188 219 if (numTimer >= MAX_TIMERS) {
lixianyu 2:6cd3b0947188 220 return false;
lixianyu 2:6cd3b0947188 221 }
lixianyu 2:6cd3b0947188 222
lixianyu 2:6cd3b0947188 223 return enabled[numTimer];
lixianyu 2:6cd3b0947188 224 }
lixianyu 2:6cd3b0947188 225
lixianyu 2:6cd3b0947188 226
lixianyu 2:6cd3b0947188 227 void SimpleTimer::enable(int numTimer)
lixianyu 2:6cd3b0947188 228 {
lixianyu 2:6cd3b0947188 229 if (numTimer >= MAX_TIMERS) {
lixianyu 2:6cd3b0947188 230 return;
lixianyu 2:6cd3b0947188 231 }
lixianyu 2:6cd3b0947188 232
lixianyu 2:6cd3b0947188 233 enabled[numTimer] = true;
lixianyu 2:6cd3b0947188 234 }
lixianyu 2:6cd3b0947188 235
lixianyu 2:6cd3b0947188 236
lixianyu 2:6cd3b0947188 237 void SimpleTimer::disable(int numTimer)
lixianyu 2:6cd3b0947188 238 {
lixianyu 2:6cd3b0947188 239 if (numTimer >= MAX_TIMERS) {
lixianyu 2:6cd3b0947188 240 return;
lixianyu 2:6cd3b0947188 241 }
lixianyu 2:6cd3b0947188 242
lixianyu 2:6cd3b0947188 243 enabled[numTimer] = false;
lixianyu 2:6cd3b0947188 244 }
lixianyu 2:6cd3b0947188 245
lixianyu 2:6cd3b0947188 246
lixianyu 2:6cd3b0947188 247 void SimpleTimer::toggle(int numTimer)
lixianyu 2:6cd3b0947188 248 {
lixianyu 2:6cd3b0947188 249 if (numTimer >= MAX_TIMERS) {
lixianyu 2:6cd3b0947188 250 return;
lixianyu 2:6cd3b0947188 251 }
lixianyu 2:6cd3b0947188 252
lixianyu 2:6cd3b0947188 253 enabled[numTimer] = !enabled[numTimer];
lixianyu 2:6cd3b0947188 254 }
lixianyu 2:6cd3b0947188 255
lixianyu 2:6cd3b0947188 256
lixianyu 2:6cd3b0947188 257 int SimpleTimer::getNumTimers()
lixianyu 2:6cd3b0947188 258 {
lixianyu 2:6cd3b0947188 259 return numTimers;
lixianyu 2:6cd3b0947188 260 }