How to avoid delay() – create a custom Arduino class – Part 2
In the previous blog post we learned how to avoid delay() if necessary. It would be very convenient when we are able to add a layer of abstraction to this code so when can easily reuse it if we need it.
Before we can begin creating a custom Arduino class, we need to create these files:
- SCAsyncTimer.cpp ( = the implementation, this is where the most of the code goes)
- SCAsyncTimer.h ( = the header, this is some kind of a “table of contents” for our class)
- keywords.txt ( = optional the keywords, here we can specify the keywords which then get colored in the IDE)
Create these files either in your sketch directory (so its only available in this sketch – restart the IDE so the compiler recognizes it) or follow this documentation how to install custom classes/libraries: Libraries
Please note that if the class goes into the global Arduino libraries folder (so its accessible for all sketches) needs to be named exactly as the class itself. In our case SCAsyncTimer.
The Header – SCAsyncTimer.h
Below you can find the Arduino SCAsyncTimer header-file:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
/* Timer class to do asynchronous things */ #ifndef SCAsyncTimer_h #define SCAsyncTimer_h #include "Arduino.h" enum TimeUnit{ UNIT_MILLISECONDS, UNIT_SECONDS, UNIT_MINUTES, UNIT_HOURS }; class SCAsyncTimer { public: SCAsyncTimer(unsigned long intervall,TimeUnit unit); bool isTriggered(); void isActive(bool active); void setIntervall(unsigned long intervall, TimeUnit unit); unsigned long getTimeLeft(); TimeUnit timeUnit; private: unsigned long _intervall; unsigned long _lastEvent; bool _active; }; #endif |
The Implementation – SCAsyncTimer.cpp
Here is the implementation of the class itself:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
#include "Arduino.h" #include "SCAsyncTimer.h" SCAsyncTimer::SCAsyncTimer(unsigned long intervall,TimeUnit unit) { setIntervall(intervall,unit); _active = true; timeUnit = unit; } void SCAsyncTimer::setIntervall(unsigned long intervall, TimeUnit unit) { if(unit == UNIT_MILLISECONDS) { _intervall = intervall; } if(unit == UNIT_SECONDS) { _intervall = intervall*1000; } if(unit == UNIT_MINUTES) { _intervall = intervall*60*1000; } if(unit == UNIT_HOURS) { _intervall = intervall*60*60*1000; } } bool SCAsyncTimer::isTriggered() { if(_active) { if(millis()-_lastEvent >= _intervall) { _lastEvent = millis(); return true; } else { return false; } } else { return false; } } void SCAsyncTimer::isActive(bool active) { _active = active; } unsigned long SCAsyncTimer::getTimeLeft() { unsigned long val = millis()-_lastEvent-_intervall; return val; } |
The Keywords – keywords.txt
The basic keywords file looks like this:
1 2 3 4 5 |
SCAsyncTimer KEYWORD1 setIntervall KEYWORD2 isTriggered KEYWORD2 isActive KEYWORD2 getTimeLeft KEYWORD2 |
Usage
Then we can just use the class like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
#include "SCAsyncTimer.h" SCAsyncTimer myTimer(10,UNIT_MINUTES); void setup() { } void loop() { if(myTimer.isTriggered()) { doSomething(); } } |
The cool thing is that is does some math for use if we do not want to calculate with milliseconds all the time. There is an enum (TimeUnit) that takes care of the calculations to minutes, seconds, hours etc.
You can download the full class here: SCAsyncTimer
Have fun!
Pingback: Arduino and how to avoid delay() – Part 1 | Electronics Scriblab