blynk & neopixelring & w7500

Fork of WIZwiki-7500_Blynk by IOP

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers BlynkTimer.cpp Source File

BlynkTimer.cpp

00001 /*
00002  * SimpleTimer.cpp
00003  *
00004  * SimpleTimer - A timer library for Arduino.
00005  * Author: mromani@ottotecnica.com
00006  * Copyright (c) 2010 OTTOTECNICA Italy
00007  *
00008  * Callback function parameters added & compiler warnings
00009  * removed by Bill Knight <billk@rosw.com> 20March2017
00010  *
00011  * This library is free software; you can redistribute it
00012  * and/or modify it under the terms of the GNU Lesser
00013  * General Public License as published by the Free Software
00014  * Foundation; either version 2.1 of the License, or (at
00015  * your option) any later version.
00016  *
00017  * This library is distributed in the hope that it will
00018  * be useful, but WITHOUT ANY WARRANTY; without even the
00019  * implied warranty of MERCHANTABILITY or FITNESS FOR A
00020  * PARTICULAR PURPOSE.  See the GNU Lesser General Public
00021  * License for more details.
00022  *
00023  * You should have received a copy of the GNU Lesser
00024  * General Public License along with this library; if not,
00025  * write to the Free Software Foundation, Inc.,
00026  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
00027  */
00028 
00029 
00030 #include "Blynk/BlynkTimer.h"
00031 #include <string.h>
00032 #include "BlynkApiMbed.h "
00033 
00034 // Select time function:
00035 //static inline unsigned long elapsed() { return micros(); }
00036 static inline unsigned long elapsed() { return millis(); }
00037 
00038 
00039 SimpleTimer::SimpleTimer()
00040     : numTimers (-1)
00041 {
00042 }
00043 
00044 void SimpleTimer::init() {
00045     unsigned long current_millis = elapsed();
00046 
00047     for (int i = 0; i < MAX_TIMERS; i++) {
00048         memset(&timer[i], 0, sizeof (timer_t));
00049         timer[i].prev_millis = current_millis;
00050     }
00051 
00052     numTimers = 0;
00053 }
00054 
00055 
00056 void SimpleTimer::run() {
00057     int i;
00058     unsigned long current_millis;
00059 
00060     // get current time
00061     current_millis = elapsed();
00062 
00063     for (i = 0; i < MAX_TIMERS; i++) {
00064 
00065         timer[i].toBeCalled = DEFCALL_DONTRUN;
00066 
00067         // no callback == no timer, i.e. jump over empty slots
00068         if (timer[i].callback != NULL) {
00069 
00070             // is it time to process this timer ?
00071             // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592
00072 
00073             if ((current_millis - timer[i].prev_millis) >= timer[i].delay) {
00074 
00075                 // update time
00076                 timer[i].prev_millis += timer[i].delay;
00077 
00078                 // check if the timer callback has to be executed
00079                 if (timer[i].enabled) {
00080 
00081                     // "run forever" timers must always be executed
00082                     if (timer[i].maxNumRuns == RUN_FOREVER) {
00083                         timer[i].toBeCalled = DEFCALL_RUNONLY;
00084                     }
00085                     // other timers get executed the specified number of times
00086                     else if (timer[i].numRuns < timer[i].maxNumRuns) {
00087                         timer[i].toBeCalled = DEFCALL_RUNONLY;
00088                         timer[i].numRuns++;
00089 
00090                         // after the last run, delete the timer
00091                         if (timer[i].numRuns >= timer[i].maxNumRuns) {
00092                             timer[i].toBeCalled = DEFCALL_RUNANDDEL;
00093                         }
00094                     }
00095                 }
00096             }
00097         }
00098     }
00099 
00100     for (i = 0; i < MAX_TIMERS; i++) {
00101         if (timer[i].toBeCalled == DEFCALL_DONTRUN)
00102             continue;
00103 
00104         if (timer[i].hasParam)
00105             (*(timer_callback_p)timer[i].callback)(timer[i].param);
00106         else
00107             (*(timer_callback)timer[i].callback)();
00108 
00109         if (timer[i].toBeCalled == DEFCALL_RUNANDDEL)
00110             deleteTimer(i);
00111     }
00112 }
00113 
00114 
00115 // find the first available slot
00116 // return -1 if none found
00117 int SimpleTimer::findFirstFreeSlot() {
00118     // all slots are used
00119     if (numTimers >= MAX_TIMERS) {
00120         return -1;
00121     }
00122 
00123     // return the first slot with no callback (i.e. free)
00124     for (int i = 0; i < MAX_TIMERS; i++) {
00125         if (timer[i].callback == NULL) {
00126             return i;
00127         }
00128     }
00129 
00130     // no free slots found
00131     return -1;
00132 }
00133 
00134 
00135 int SimpleTimer::setupTimer(unsigned long d, void* f, void* p, bool h, unsigned n) {
00136     int freeTimer;
00137 
00138     if (numTimers < 0) {
00139         init();
00140     }
00141 
00142     freeTimer = findFirstFreeSlot();
00143     if (freeTimer < 0) {
00144         return -1;
00145     }
00146 
00147     if (f == NULL) {
00148         return -1;
00149     }
00150 
00151     timer[freeTimer].delay = d;
00152     timer[freeTimer].callback = f;
00153     timer[freeTimer].param = p;
00154     timer[freeTimer].hasParam = h;
00155     timer[freeTimer].maxNumRuns = n;
00156     timer[freeTimer].enabled = true;
00157     timer[freeTimer].prev_millis = elapsed();
00158 
00159     numTimers++;
00160 
00161     return freeTimer;
00162 }
00163 
00164 
00165 int SimpleTimer::setTimer(unsigned long d, timer_callback f, unsigned n) {
00166   return setupTimer(d, (void *)f, NULL, false, n);
00167 }
00168 
00169 int SimpleTimer::setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n) {
00170   return setupTimer(d, (void *)f, p, true, n);
00171 }
00172 
00173 int SimpleTimer::setInterval(unsigned long d, timer_callback f) {
00174     return setupTimer(d, (void *)f, NULL, false, RUN_FOREVER);
00175 }
00176 
00177 int SimpleTimer::setInterval(unsigned long d, timer_callback_p f, void* p) {
00178   return setupTimer(d, (void *)f, p, true, RUN_FOREVER);
00179 }
00180 
00181 int SimpleTimer::setTimeout(unsigned long d, timer_callback f) {
00182     return setupTimer(d, (void *)f, NULL, false, RUN_ONCE);
00183 }
00184 
00185 int SimpleTimer::setTimeout(unsigned long d, timer_callback_p f, void* p) {
00186   return setupTimer(d, (void *)f, p, true, RUN_ONCE);
00187 }
00188 
00189 bool SimpleTimer::changeInterval(unsigned numTimer, unsigned long d) {
00190     if (numTimer >= MAX_TIMERS) {
00191         return false;
00192     }
00193 
00194     // Updates interval of existing specified timer
00195     if (timer[numTimer].callback != NULL) {
00196         timer[numTimer].delay = d;
00197         timer[numTimer].prev_millis = elapsed();
00198         return true;
00199     }
00200     // false return for non-used numTimer, no callback
00201     return false;
00202 }
00203 
00204 void SimpleTimer::deleteTimer(unsigned timerId) {
00205     if (timerId >= MAX_TIMERS) {
00206         return;
00207     }
00208 
00209     // nothing to delete if no timers are in use
00210     if (numTimers == 0) {
00211         return;
00212     }
00213 
00214     // don't decrease the number of timers if the
00215     // specified slot is already empty
00216     if (timer[timerId].callback != NULL) {
00217         memset(&timer[timerId], 0, sizeof (timer_t));
00218         timer[timerId].prev_millis = elapsed();
00219 
00220         // update number of timers
00221         numTimers--;
00222     }
00223 }
00224 
00225 
00226 // function contributed by code@rowansimms.com
00227 void SimpleTimer::restartTimer(unsigned numTimer) {
00228     if (numTimer >= MAX_TIMERS) {
00229         return;
00230     }
00231 
00232     timer[numTimer].prev_millis = elapsed();
00233 }
00234 
00235 
00236 bool SimpleTimer::isEnabled(unsigned numTimer) {
00237     if (numTimer >= MAX_TIMERS) {
00238         return false;
00239     }
00240 
00241     return timer[numTimer].enabled;
00242 }
00243 
00244 
00245 void SimpleTimer::enable(unsigned numTimer) {
00246     if (numTimer >= MAX_TIMERS) {
00247         return;
00248     }
00249 
00250     timer[numTimer].enabled = true;
00251 }
00252 
00253 
00254 void SimpleTimer::disable(unsigned numTimer) {
00255     if (numTimer >= MAX_TIMERS) {
00256         return;
00257     }
00258 
00259     timer[numTimer].enabled = false;
00260 }
00261 
00262 void SimpleTimer::enableAll() {
00263     // Enable all timers with a callback assigned (used)
00264     for (int i = 0; i < MAX_TIMERS; i++) {
00265         if (timer[i].callback != NULL && timer[i].numRuns == RUN_FOREVER) {
00266             timer[i].enabled = true;
00267         }
00268     }
00269 }
00270 
00271 void SimpleTimer::disableAll() {
00272     // Disable all timers with a callback assigned (used)
00273     for (int i = 0; i < MAX_TIMERS; i++) {
00274         if (timer[i].callback != NULL && timer[i].numRuns == RUN_FOREVER) {
00275             timer[i].enabled = false;
00276         }
00277     }
00278 }
00279 
00280 void SimpleTimer::toggle(unsigned numTimer) {
00281     if (numTimer >= MAX_TIMERS) {
00282         return;
00283     }
00284 
00285     timer[numTimer].enabled = !timer[numTimer].enabled;
00286 }
00287 
00288 
00289 unsigned SimpleTimer::getNumTimers() {
00290     return numTimers;
00291 }