Blynk library for embedded hardware. Works with Arduino, ESP8266, Raspberry Pi, Intel Edison/Galileo, LinkIt ONE, Particle Core/Photon, Energia, ARM mbed, etc. http://www.blynk.cc/

Dependents:   Blynk_RBL_BLE_Nano Blynk_MicroBit Blynk_Serial Blynk_RBL_BLE_Nano

Committer:
Volodymyr Shymanskyy
Date:
Sun Apr 09 14:50:30 2017 +0300
Revision:
13:ed6276c0afb7
Child:
14:76d8fd871a4d
Update version

Who changed what in which revision?

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