└── SimpleTimer ├── README.md ├── SimpleTimer.cpp ├── SimpleTimer.h ├── example ├── SimpleTimer │ └── SimpleTimer.ino └── SimpleTimerPlus │ └── SimpleTimerPlus.ino └── tests ├── SetInterval └── SetInterval.ino ├── TestEnableDisable └── TestEnableDisable.ino ├── TestFillTimerTable └── TestFillTimerTable.ino └── UnitTests └── UnitTests.ino /SimpleTimer/README.md: -------------------------------------------------------------------------------- 1 | # SimpleTimer 2 | 3 | This is (yet another) simple library to launch timed actions. 4 | 5 | It's based on millis(), thus it has 1 ms resolution. 6 | 7 | It uses polling, so no guarantee can be made about the exact time when a callback is fired. For example, if you setup the library so that it calls a function every 2ms, but this function requires 5ms to complete, then you'll have an invocation every 5ms. 8 | 9 | For applications where non-strict timing is enough, not using interrupts avoids potential problems with global variables shared between the interrupt service routine and the main program, and doesn't consume a hardware timer. 10 | 11 | There's also a fork of SimpleTimer which also supports std::function or lambda-expressions known from C++11. See: https://github.com/schinken/SimpleTimer 12 | 13 | # Library page on Arduino.cc 14 | 15 | http://playground.arduino.cc/Code/SimpleTimer 16 | -------------------------------------------------------------------------------- /SimpleTimer/SimpleTimer.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | * SimpleTimer.cpp 3 | * 4 | * SimpleTimer - A timer library for Arduino. 5 | * Author: mromani@ottotecnica.com 6 | * Copyright (c) 2010 OTTOTECNICA Italy 7 | * 8 | * Callback function parameters added & compiler warnings 9 | * removed by Bill Knight 20March2017 10 | * 11 | * This library is free software; you can redistribute it 12 | * and/or modify it under the terms of the GNU Lesser 13 | * General Public License as published by the Free Software 14 | * Foundation; either version 2.1 of the License, or (at 15 | * your option) any later version. 16 | * 17 | * This library is distributed in the hope that it will 18 | * be useful, but WITHOUT ANY WARRANTY; without even the 19 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 20 | * PARTICULAR PURPOSE. See the GNU Lesser General Public 21 | * License for more details. 22 | * 23 | * You should have received a copy of the GNU Lesser 24 | * General Public License along with this library; if not, 25 | * write to the Free Software Foundation, Inc., 26 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 27 | */ 28 | 29 | 30 | #include "SimpleTimer.h" 31 | 32 | 33 | // Select time function: 34 | //static inline unsigned long elapsed() { return micros(); } 35 | static inline unsigned long elapsed() { return millis(); } 36 | 37 | 38 | SimpleTimer::SimpleTimer() { 39 | unsigned long current_millis = elapsed(); 40 | 41 | for (int i = 0; i < MAX_TIMERS; i++) { 42 | memset(&timer[i], 0, sizeof (timer_t)); 43 | timer[i].prev_millis = current_millis; 44 | } 45 | 46 | numTimers = 0; 47 | } 48 | 49 | 50 | void SimpleTimer::run() { 51 | int i; 52 | unsigned long current_millis; 53 | 54 | // get current time 55 | current_millis = elapsed(); 56 | 57 | for (i = 0; i < MAX_TIMERS; i++) { 58 | 59 | timer[i].toBeCalled = DEFCALL_DONTRUN; 60 | 61 | // no callback == no timer, i.e. jump over empty slots 62 | if (timer[i].callback != NULL) { 63 | 64 | // is it time to process this timer ? 65 | // see http://arduino.cc/forum/index.php/topic,124048.msg932592.html#msg932592 66 | 67 | if ((current_millis - timer[i].prev_millis) >= timer[i].delay) { 68 | 69 | // update time 70 | timer[i].prev_millis += timer[i].delay; 71 | 72 | // check if the timer callback has to be executed 73 | if (timer[i].enabled) { 74 | 75 | // "run forever" timers must always be executed 76 | if (timer[i].maxNumRuns == RUN_FOREVER) { 77 | timer[i].toBeCalled = DEFCALL_RUNONLY; 78 | } 79 | // other timers get executed the specified number of times 80 | else if (timer[i].numRuns < timer[i].maxNumRuns) { 81 | timer[i].toBeCalled = DEFCALL_RUNONLY; 82 | timer[i].numRuns++; 83 | 84 | // after the last run, delete the timer 85 | if (timer[i].numRuns >= timer[i].maxNumRuns) { 86 | timer[i].toBeCalled = DEFCALL_RUNANDDEL; 87 | } 88 | } 89 | } 90 | } 91 | } 92 | } 93 | 94 | for (i = 0; i < MAX_TIMERS; i++) { 95 | if (timer[i].toBeCalled == DEFCALL_DONTRUN) 96 | continue; 97 | 98 | if (timer[i].hasParam) 99 | (*(timer_callback_p)timer[i].callback)(timer[i].param); 100 | else 101 | (*(timer_callback)timer[i].callback)(); 102 | 103 | if (timer[i].toBeCalled == DEFCALL_RUNANDDEL) 104 | deleteTimer(i); 105 | } 106 | } 107 | 108 | 109 | // find the first available slot 110 | // return -1 if none found 111 | int SimpleTimer::findFirstFreeSlot() { 112 | // all slots are used 113 | if (numTimers >= MAX_TIMERS) { 114 | return -1; 115 | } 116 | 117 | // return the first slot with no callback (i.e. free) 118 | for (int i = 0; i < MAX_TIMERS; i++) { 119 | if (timer[i].callback == NULL) { 120 | return i; 121 | } 122 | } 123 | 124 | // no free slots found 125 | return -1; 126 | } 127 | 128 | 129 | int SimpleTimer::setupTimer(unsigned long d, void* f, void* p, boolean h, unsigned n) { 130 | int freeTimer; 131 | 132 | freeTimer = findFirstFreeSlot(); 133 | if (freeTimer < 0) { 134 | return -1; 135 | } 136 | 137 | if (f == NULL) { 138 | return -1; 139 | } 140 | 141 | timer[freeTimer].delay = d; 142 | timer[freeTimer].callback = f; 143 | timer[freeTimer].param = p; 144 | timer[freeTimer].hasParam = h; 145 | timer[freeTimer].maxNumRuns = n; 146 | timer[freeTimer].enabled = true; 147 | timer[freeTimer].prev_millis = elapsed(); 148 | 149 | numTimers++; 150 | 151 | return freeTimer; 152 | } 153 | 154 | 155 | int SimpleTimer::setTimer(unsigned long d, timer_callback f, unsigned n) { 156 | return setupTimer(d, (void *)f, NULL, false, n); 157 | } 158 | 159 | int SimpleTimer::setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n) { 160 | return setupTimer(d, (void *)f, p, true, n); 161 | } 162 | 163 | int SimpleTimer::setInterval(unsigned long d, timer_callback f) { 164 | return setupTimer(d, (void *)f, NULL, false, RUN_FOREVER); 165 | } 166 | 167 | int SimpleTimer::setInterval(unsigned long d, timer_callback_p f, void* p) { 168 | return setupTimer(d, (void *)f, p, true, RUN_FOREVER); 169 | } 170 | 171 | int SimpleTimer::setTimeout(unsigned long d, timer_callback f) { 172 | return setupTimer(d, (void *)f, NULL, false, RUN_ONCE); 173 | } 174 | 175 | int SimpleTimer::setTimeout(unsigned long d, timer_callback_p f, void* p) { 176 | return setupTimer(d, (void *)f, p, true, RUN_ONCE); 177 | } 178 | 179 | 180 | void SimpleTimer::deleteTimer(unsigned timerId) { 181 | if (timerId >= MAX_TIMERS) { 182 | return; 183 | } 184 | 185 | // nothing to delete if no timers are in use 186 | if (numTimers == 0) { 187 | return; 188 | } 189 | 190 | // don't decrease the number of timers if the 191 | // specified slot is already empty 192 | if (timer[timerId].callback != NULL) { 193 | memset(&timer[timerId], 0, sizeof (timer_t)); 194 | timer[timerId].prev_millis = elapsed(); 195 | 196 | // update number of timers 197 | numTimers--; 198 | } 199 | } 200 | 201 | 202 | // function contributed by code@rowansimms.com 203 | void SimpleTimer::restartTimer(unsigned numTimer) { 204 | if (numTimer >= MAX_TIMERS) { 205 | return; 206 | } 207 | 208 | timer[numTimer].prev_millis = elapsed(); 209 | } 210 | 211 | 212 | boolean SimpleTimer::isEnabled(unsigned numTimer) { 213 | if (numTimer >= MAX_TIMERS) { 214 | return false; 215 | } 216 | 217 | return timer[numTimer].enabled; 218 | } 219 | 220 | 221 | void SimpleTimer::enable(unsigned numTimer) { 222 | if (numTimer >= MAX_TIMERS) { 223 | return; 224 | } 225 | 226 | timer[numTimer].enabled = true; 227 | } 228 | 229 | 230 | void SimpleTimer::disable(unsigned numTimer) { 231 | if (numTimer >= MAX_TIMERS) { 232 | return; 233 | } 234 | 235 | timer[numTimer].enabled = false; 236 | } 237 | 238 | 239 | void SimpleTimer::toggle(unsigned numTimer) { 240 | if (numTimer >= MAX_TIMERS) { 241 | return; 242 | } 243 | 244 | timer[numTimer].enabled = !timer[numTimer].enabled; 245 | } 246 | 247 | 248 | unsigned SimpleTimer::getNumTimers() { 249 | return numTimers; 250 | } 251 | -------------------------------------------------------------------------------- /SimpleTimer/SimpleTimer.h: -------------------------------------------------------------------------------- 1 | /* 2 | * SimpleTimer.h 3 | * 4 | * SimpleTimer - A timer library for Arduino. 5 | * Author: mromani@ottotecnica.com 6 | * Copyright (c) 2010 OTTOTECNICA Italy 7 | * 8 | * Modifications by Bill Knight 18March2017 9 | * 10 | * This library is free software; you can redistribute it 11 | * and/or modify it under the terms of the GNU Lesser 12 | * General Public License as published by the Free Software 13 | * Foundation; either version 2.1 of the License, or (at 14 | * your option) any later version. 15 | * 16 | * This library is distributed in the hope that it will 17 | * be useful, but WITHOUT ANY WARRANTY; without even the 18 | * implied warranty of MERCHANTABILITY or FITNESS FOR A 19 | * PARTICULAR PURPOSE. See the GNU Lesser General Public 20 | * License for more details. 21 | * 22 | * You should have received a copy of the GNU Lesser 23 | * General Public License along with this library; if not, 24 | * write to the Free Software Foundation, Inc., 25 | * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 26 | * 27 | */ 28 | 29 | 30 | #ifndef SIMPLETIMER_H 31 | #define SIMPLETIMER_H 32 | 33 | #if defined(ARDUINO) && ARDUINO >= 100 34 | #include 35 | #else 36 | #include 37 | #endif 38 | 39 | typedef void (*timer_callback)(void); 40 | typedef void (*timer_callback_p)(void *); 41 | 42 | class SimpleTimer { 43 | 44 | public: 45 | // maximum number of timers 46 | const static int MAX_TIMERS = 10; 47 | 48 | // setTimer() constants 49 | const static int RUN_FOREVER = 0; 50 | const static int RUN_ONCE = 1; 51 | 52 | // constructor 53 | SimpleTimer(); 54 | 55 | // this function must be called inside loop() 56 | void run(); 57 | 58 | // Timer will call function 'f' every 'd' milliseconds forever 59 | // returns the timer number (numTimer) on success or 60 | // -1 on failure (f == NULL) or no free timers 61 | int setInterval(unsigned long d, timer_callback f); 62 | 63 | // Timer will call function 'f' with parameter 'p' every 'd' milliseconds forever 64 | // returns the timer number (numTimer) on success or 65 | // -1 on failure (f == NULL) or no free timers 66 | int setInterval(unsigned long d, timer_callback_p f, void* p); 67 | 68 | // Timer will call function 'f' after 'd' milliseconds one time 69 | // returns the timer number (numTimer) on success or 70 | // -1 on failure (f == NULL) or no free timers 71 | int setTimeout(unsigned long d, timer_callback f); 72 | 73 | // Timer will call function 'f' with parameter 'p' after 'd' milliseconds one time 74 | // returns the timer number (numTimer) on success or 75 | // -1 on failure (f == NULL) or no free timers 76 | int setTimeout(unsigned long d, timer_callback_p f, void* p); 77 | 78 | // Timer will call function 'f' every 'd' milliseconds 'n' times 79 | // returns the timer number (numTimer) on success or 80 | // -1 on failure (f == NULL) or no free timers 81 | int setTimer(unsigned long d, timer_callback f, unsigned n); 82 | 83 | // Timer will call function 'f' with parameter 'p' every 'd' milliseconds 'n' times 84 | // returns the timer number (numTimer) on success or 85 | // -1 on failure (f == NULL) or no free timers 86 | int setTimer(unsigned long d, timer_callback_p f, void* p, unsigned n); 87 | 88 | // destroy the specified timer 89 | void deleteTimer(unsigned numTimer); 90 | 91 | // restart the specified timer 92 | void restartTimer(unsigned numTimer); 93 | 94 | // returns true if the specified timer is enabled 95 | boolean isEnabled(unsigned numTimer); 96 | 97 | // enables the specified timer 98 | void enable(unsigned numTimer); 99 | 100 | // disables the specified timer 101 | void disable(unsigned numTimer); 102 | 103 | // enables the specified timer if it's currently disabled, 104 | // and vice-versa 105 | void toggle(unsigned numTimer); 106 | 107 | // returns the number of used timers 108 | unsigned getNumTimers(); 109 | 110 | // returns the number of available timers 111 | unsigned getNumAvailableTimers() { return MAX_TIMERS - numTimers; }; 112 | 113 | private: 114 | // deferred call constants 115 | const static int DEFCALL_DONTRUN = 0; // don't call the callback function 116 | const static int DEFCALL_RUNONLY = 1; // call the callback function but don't delete the timer 117 | const static int DEFCALL_RUNANDDEL = 2; // call the callback function and delete the timer 118 | 119 | // low level function to initialize and enable a new timer 120 | // returns the timer number (numTimer) on success or 121 | // -1 on failure (f == NULL) or no free timers 122 | int setupTimer(unsigned long d, void* f, void* p, boolean h, unsigned n); 123 | 124 | // find the first available slot 125 | int findFirstFreeSlot(); 126 | 127 | typedef struct { 128 | unsigned long prev_millis; // value returned by the millis() function in the previous run() call 129 | void* callback; // pointer to the callback function 130 | void* param; // function parameter 131 | boolean hasParam; // true if callback takes a parameter 132 | unsigned long delay; // delay value 133 | unsigned maxNumRuns; // number of runs to be executed 134 | unsigned numRuns; // number of executed runs 135 | boolean enabled; // true if enabled 136 | unsigned toBeCalled; // deferred function call (sort of) - N.B.: only used in run() 137 | } timer_t; 138 | 139 | timer_t timer[MAX_TIMERS]; 140 | 141 | // actual number of timers in use 142 | unsigned numTimers; 143 | }; 144 | 145 | #endif 146 | -------------------------------------------------------------------------------- /SimpleTimer/example/SimpleTimer/SimpleTimer.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // the timer object 4 | SimpleTimer timer; 5 | 6 | // a function to be executed periodically 7 | void repeatMe() { 8 | Serial.print("Uptime (s): "); 9 | Serial.println(millis() / 1000); 10 | } 11 | 12 | void setup() { 13 | Serial.begin(9600); 14 | timer.setInterval(1000, repeatMe); 15 | } 16 | 17 | void loop() { 18 | timer.run(); 19 | } 20 | -------------------------------------------------------------------------------- /SimpleTimer/example/SimpleTimerPlus/SimpleTimerPlus.ino: -------------------------------------------------------------------------------- 1 | /* 2 | * SimpleTimerAlarmExample.ino 3 | * 4 | * Based on usage example for Time + TimeAlarm + SimpleTimer libraries 5 | * 6 | * A timer is called every 15 seconds 7 | * Another timer is called once only after 10 seconds 8 | * A third timer is called 10 times. 9 | * Toggle an IO pin 100mSec LOW, 900mSec HIGH 10 | * 11 | */ 12 | 13 | #include 14 | 15 | // There must be one global SimpleTimer object. 16 | // More SimpleTimer objects can be created and run, 17 | // although there is little point in doing so. 18 | SimpleTimer timer; 19 | 20 | // Pin to toggle 21 | const unsigned int PIN = 13; 22 | 23 | // function to be called repeatedly 24 | void RepeatTask(void) { 25 | Serial.println("15 second timer"); 26 | } 27 | 28 | // function to be called just once 29 | void OnceOnlyTask(void) { 30 | Serial.println("This timer only triggers once"); 31 | } 32 | 33 | // function to be called exactly 10 times 34 | void TenTimesTask(void) { 35 | static int k = 0; 36 | k++; 37 | Serial.print("called "); 38 | Serial.print(k); 39 | Serial.println(" / 10 times."); 40 | } 41 | 42 | // print current arduino "uptime" on the serial port 43 | void DigitalClockDisplay(void) { 44 | int h,m,s; 45 | s = millis() / 1000; 46 | m = s / 60; 47 | h = s / 3600; 48 | s = s - m * 60; 49 | m = m - h * 60; 50 | Serial.print(h); 51 | printDigits(m); 52 | printDigits(s); 53 | Serial.println(); 54 | } 55 | 56 | // 57 | // utility function for digital clock display: 58 | // prints preceding colon and leading 0 59 | // 60 | void printDigits(int digits) { 61 | Serial.print(":"); 62 | if(digits < 10) 63 | Serial.print('0'); 64 | Serial.print(digits); 65 | } 66 | 67 | // This callback function takes an arg. The arg can be cast to a value 68 | // as in this example or cast to a pointer to a structure or even a 69 | // function. If a structure, it must be present in memory when the 70 | // callback fuction is called. In other words it must be a global or 71 | // declared 'static' and not a structure local to the function that 72 | // created the timer such as setup() or loop(). 73 | void setPin(void* args) 74 | { 75 | int state = (int)args; 76 | unsigned long duration; 77 | 78 | if (state == LOW) 79 | { 80 | digitalWrite(PIN, LOW); 81 | state = HIGH; // set the pin high 82 | duration = 100; // after 100 mSec 83 | } 84 | else 85 | { 86 | digitalWrite(PIN, HIGH); 87 | state = LOW; // set the pin low 88 | duration = 900; // after 900 mSec 89 | } 90 | 91 | timer.setTimeout(duration, setPin, (void *)state); 92 | } 93 | 94 | void setup() { 95 | Serial.begin(9600); 96 | 97 | // welcome message 98 | Serial.println("SimpleTimer Example"); 99 | Serial.println("One timer is triggered every 15 seconds"); 100 | Serial.println("Another timer is set to trigger only once after 10 seconds"); 101 | Serial.println("Another timer is set to trigger 10 times"); 102 | Serial.println(); 103 | 104 | // timed actions setup 105 | timer.setInterval(15000, RepeatTask); 106 | timer.setTimeout(10000, OnceOnlyTask); 107 | timer.setInterval(1000, DigitalClockDisplay); 108 | timer.setTimer(1200, TenTimesTask, 10); 109 | pinMode(PIN, OUTPUT); 110 | digitalWrite(PIN, LOW); 111 | // Set the pin HIGH after 100 mSec 112 | timer.setTimeout(100, setPin, (void *)HIGH); 113 | } 114 | 115 | void loop() { 116 | // this is where the "polling" occurs 117 | timer.run(); 118 | } 119 | -------------------------------------------------------------------------------- /SimpleTimer/tests/SetInterval/SetInterval.ino: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | // the timer object 4 | SimpleTimer timer; 5 | 6 | unsigned int counter = 0; 7 | 8 | boolean pass = true; 9 | 10 | // a function to be executed periodically 11 | void repeatMe() { 12 | counter++; 13 | Serial.print("Uptime (s): "); 14 | Serial.println(millis() / 1000); 15 | } 16 | 17 | void checkResult(void* param) { 18 | unsigned int expected = (unsigned int)param; 19 | 20 | Serial.print("Checking param = "); 21 | Serial.println(expected); 22 | Serial.print("counter = "); 23 | Serial.println(counter); 24 | 25 | if (expected == counter) { 26 | Serial.println("OK"); 27 | } 28 | else { 29 | Serial.println("ERROR"); 30 | pass = false; 31 | } 32 | } 33 | 34 | void start() { 35 | Serial.println("Test start"); 36 | } 37 | 38 | void stopSketch() { 39 | Serial.println("Test stop"); 40 | Serial.println(pass ? "PASS" : "FAIL"); 41 | while(true); 42 | } 43 | 44 | void setup() { 45 | Serial.begin(9600); 46 | timer.setTimeout(100, start); 47 | timer.setInterval(500, repeatMe); 48 | timer.setTimeout(550, checkResult, 1); 49 | timer.setTimeout(1050, checkResult, 2); 50 | timer.setTimeout(1550, checkResult, 3); 51 | timer.setTimeout(2000, stopSketch); 52 | } 53 | 54 | void loop() { 55 | timer.run(); 56 | } 57 | -------------------------------------------------------------------------------- /SimpleTimer/tests/TestEnableDisable/TestEnableDisable.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // if when calling disable(), the timer callback doesn't get executed. 5 | 6 | // the timer object 7 | SimpleTimer timer; 8 | 9 | bool all_done = false; 10 | 11 | int counter = 0; 12 | 13 | void callMeOnce() { 14 | Serial.print("callMeOnce: counter="); 15 | counter++; 16 | Serial.println(counter); 17 | } 18 | 19 | void setup() { 20 | Serial.begin(9600); 21 | 22 | for (int i = 0; i < timer.MAX_TIMERS; i++) { 23 | int id = timer.setTimer(10, callMeOnce, 1); 24 | assertNotEqual(id, -1); 25 | } 26 | 27 | int id = timer.setTimer(10, callMeOnce, 1); 28 | assertEqual(id, -1); 29 | 30 | timer.disable(4); 31 | 32 | assertEqual(timer.getNumTimers(), timer.MAX_TIMERS); 33 | } 34 | 35 | void loop() { 36 | timer.run(); 37 | 38 | if (counter == (timer.MAX_TIMERS - 1)) { 39 | Serial.println("Tests finished."); 40 | while (true); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /SimpleTimer/tests/TestFillTimerTable/TestFillTimerTable.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // the timer object 5 | SimpleTimer timer; 6 | 7 | bool all_done = false; 8 | 9 | int counter = 0; 10 | 11 | void callMeOnce() { 12 | Serial.print("callMeOnce: counter="); 13 | counter++; 14 | Serial.println(counter); 15 | } 16 | 17 | void setup() { 18 | Serial.begin(9600); 19 | 20 | for (int i = 0; i < timer.MAX_TIMERS; i++) { 21 | int id = timer.setTimer(10, callMeOnce, 1); 22 | assertNotEqual(id, -1); 23 | } 24 | 25 | int id = timer.setTimer(10, callMeOnce, 1); 26 | assertEqual(id, -1); 27 | assertEqual(timer.getNumTimers(), timer.MAX_TIMERS); 28 | } 29 | 30 | void loop() { 31 | timer.run(); 32 | 33 | if (counter == timer.MAX_TIMERS) { 34 | Serial.println("Tests finished."); 35 | while (true); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /SimpleTimer/tests/UnitTests/UnitTests.ino: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | // the timer object 5 | SimpleTimer timer; 6 | 7 | unsigned int c1 = 0; 8 | unsigned int c2 = 0; 9 | 10 | bool all_done = false; 11 | 12 | void callMeOnce() { 13 | Serial.println("callMeOnce"); 14 | c1++; 15 | } 16 | 17 | void callMeTwice() { 18 | Serial.println("callMeTwice"); 19 | c2++; 20 | } 21 | 22 | void checkResults() { 23 | Serial.println("checkResults"); 24 | assertEqual(c1, 1); 25 | assertEqual(c2, 2); 26 | 27 | all_done = true; 28 | } 29 | 30 | void setup() { 31 | Serial.begin(9600); 32 | 33 | assertEqual(timer.getNumTimers(), 0); 34 | 35 | timer.setTimer(10, callMeOnce, 1); 36 | timer.setTimer(10, callMeTwice, 2); 37 | timer.setTimeout(50, checkResults); 38 | 39 | assertEqual(timer.getNumTimers(), 3); 40 | } 41 | 42 | void loop() { 43 | timer.run(); 44 | 45 | if (all_done) { 46 | unsigned int remaining = timer.getNumAvailableTimers(); 47 | const unsigned int MAX = timer.MAX_TIMERS; 48 | assertEqual(remaining, MAX); 49 | Serial.println("Tests finished."); 50 | while (true); 51 | } 52 | } 53 | --------------------------------------------------------------------------------