BlogA basic timer for the Arduino

The following errors were encountered: Please rectify them and try again.

For one of my Sonoff switches I'm using a timer to ping my PC so it switches everything off with my PC (see code). Originally, for the sake of time (forgive the pun), I ripped code from this page. However, it was a bit more complicated to use that I anticipated and resetting the timer interval didn't always work (I don't know if it ever did, tbh). So I wrote my own, with significantly fewer lines. The only major disadvantage is that you can't register multiple timers under one loop method.

Anyway, here it is:

  1. #ifndef _TIMER_h
  2. #define _TIMER_h
  3.  
  4. #if defined(ARDUINO) && ARDUINO >= 100
  5. #include "arduino.h"
  6. #else
  7. #include "WProgram.h"
  8. #endif
  9. #include <functional>
  10.  
  11. class Timer
  12. {
  13. protected:
  14. int _interval;
  15. std::function<void()> _callback;
  16. unsigned long _lastRunTime;
  17. bool _enabled;
  18. void constructor(int interval, std::function<void()> callback, bool startImmediately);
  19.  
  20. public:
  21. Timer(int interval, std::function<void()> callback);
  22. Timer(int interval, std::function<void()> callback, bool startImmediately);
  23. void loop();
  24. void start();
  25. void stop();
  26. bool enabled();
  27. void reset(int interval);
  28. };
  29.  
  30. #endif

  1. #include "Timer.h"
  2.  
  3. void Timer::constructor(int interval, std::function<void()> callback, bool startImmediately) {
  4. _interval = interval;
  5. _callback = callback;
  6. _enabled = false;
  7. if (startImmediately)
  8. start();
  9. }
  10.  
  11. Timer::Timer(int interval, std::function<void()> callback) {
  12. constructor(interval, callback, false);
  13. }
  14.  
  15. Timer::Timer(int interval, std::function<void()> callback, bool startImmediately) {
  16. constructor(interval, callback, startImmediately);
  17. }
  18.  
  19. void Timer::loop() {
  20. if (!_enabled)
  21. return;
  22.  
  23. if (millis() - _lastRunTime >= _interval) {
  24. _callback();
  25. _lastRunTime = millis();
  26. }
  27. }
  28.  
  29. void Timer::start() {
  30. _enabled = true;
  31. _lastRunTime = millis();
  32. }
  33.  
  34. void Timer::stop() {
  35. _enabled = false;
  36. }
  37.  
  38. bool Timer::enabled() {
  39. return _enabled;
  40. }
  41.  
  42. void Timer::reset(int interval) {
  43. stop();
  44. _interval = interval;
  45. start();
  46. }

As you can see, there are two constructors; one for the setup and one for the setup as well as defining if it should start immediately. It's got a simple stop and start and you can reset the interval. Just call Timer.loop() in your loop() method to keep it running.

Here's the example code from what I used to develop it:

  1. #include "Timer.h"
  2. #include "Led.h"
  3. #include "Button.h"
  4.  
  5. void resetTimer();
  6. void toggleTimer();
  7.  
  8. Led led(13);
  9. auto ledToggle = std::bind(&Led::toggle, &led);
  10. Timer timer(1000, ledToggle, true);
  11. Button button(0, toggleTimer, resetTimer);
  12. bool shortReset = false;
  13.  
  14. void toggleTimer() {
  15. if (timer.enabled())
  16. timer.stop();
  17. else
  18. timer.start();
  19. }
  20.  
  21. void resetTimer() {
  22. if (shortReset)
  23. timer.reset(250);
  24. else
  25. timer.reset(1000);
  26. shortReset = !shortReset;
  27. }
  28.  
  29. void setup() {
  30. }
  31.  
  32. void loop() {
  33. timer.loop();
  34. button.loop();
  35. }

Posted on Saturday the 25th of February 2017