-
Notifications
You must be signed in to change notification settings - Fork 5
Application Design
Go back Home - Go back to the previous step: Project Repository and Workspace Preparations
With the just cloned skeleton project you get an empty Sketch with the typical Arduino stub functions setup() and loop(). Additionally the Timer library component is made ready to be used:

You will add some functionality to the Blink Sketch now in order to create a blinking LED application. The following class diagram depicts the application design:

In the Eclipse IDE open the file arduino_blink.cpp, this is our Blink Sketch where we add our code.
-
let's start with including the
Timerlibrary, add the following line just after the existing#includeline.#include "Timer.h"
-
copy the Event Processing function into the Sketch right after the include lines:
void toggleLed(int ledPin) { bool isLedOn = digitalRead(ledPin); digitalWrite(ledPin, !isLedOn); }
This function reads the LED pin's state using the Arduino's built in
digitalRead()and writes the inverse state back with the Arduino's functiondigitalWrite(). -
declare a
blinkTimerinstance variable and initialize it to zero (NULL pointer):Timer* blinkTimer = 0; -
define the interval time
const unsigned int BLINK_TIME_MILLIS = 500;
-
define and implement the Timer Event callback adapter, calling the Event Processing function:
class BlinkTimerAdapter : public TimerAdapter { public: void timeExpired() { toggleLed(LED_BUILTIN); } };
-
in the
setup()function (this gets called once after startup):-
configure the LED pin as output (
LED_BUILTINis an Arduino constant, for most Arduino board types this is set to 13) -
instantiate a
Timerobject, inject aBlinkTimerAdapterobject, make theTimerrecurring and set the intervalvoid setup() { pinMode(LED_BUILTIN, OUTPUT); blinkTimer = new Timer(new BlinkTimerAdapter(), Timer:: IS_RECURRING, BLINK_TIME_MILLIS); }
-
-
in the
loop()function (this gets repeatedly called forever right aftersetup()has finished):-
trigger the scheduler by calling the
yield()function:void loop() { yield(); }
-
Please find the example Sketch source implementation here: https://github.com/ERNICommunity/arduino-blink/blob/example/src/arduino_blink.cpp
The following sequence diagram shows the principle of how the application works:

In the setup() the BlinkTimerAdapter and the blinkTimer are created, and the BlinkTimerAdapter object gets injected into the blinkTimer object. On creation of the Timer this fetches an instance of the TimerContext singleton and attaches itself to it.
The first time the loop() function runs after setup() is finished, the yield() function implemented by the Timer library runs and the TimerContext instance is fetchted in order to run handleTick() on it. This calls tick() on the first attached Timer object in the list of TimerContext. With this the blinkTimer object's time expiration event will be evaluated. This time the event is not yet due, so nothing happens. The linked list of timers has no more elements, so the handleTick() method terminates and the control is given back to the loop() function.
The second time the loop() function runs, the expiry time has been reached and the blinkTimer calls out the adapter's timeExpired() method which finally toggles the LED.
So all in all making a fuss of toggling a dull LED!? you might say. Well, this is an embedded Hello World program (these all just blink a LED), being a simple example to demonstrate the concept with the Timer library, which will help you to build much more complex applications with different timed and other events from outside the system, triggering multiple processes running in parallel.
Imagine the case where you will have more recurring events, all with different intervals triggering several processes. With the Timer library you can abstract all the time evaluations and the organisation of the several different timers. You just have to focus on your processing code and you can create loosely coupled components.
And: with this Timer library you are even able to use the Arduino's built-in delay() function. While the caller gets kept busy waiting, the yield() function will be steadily called (as it is implemented by the Arduino environment) and the timers get evaluated in the meanwhile.
In order to demonstrate how you can get two processes work in paralell, the Blink with Timer example shall be enhanced.
The interval of the timer shall be made controllable by certain characters received on the serial interface with the help from a new BlinkTimerControl class:
- beside the
toggleLed()action, the time expired event also triggers the blink timer interval control process - after each timer expired event, the timer shall be restarted with the new interval, if changed
- the interval can be altered by certain received characters on the serial interface:
- on an 'i', the timer interval shall be incremented
- on a 'd', the timer interval shall be decremented

Copy the class files BlinkTimerControl.{h|cpp} from here:
- https://github.com/ERNICommunity/arduino-blink/blob/example2/src/BlinkTimerControl.cpp
- https://github.com/ERNICommunity/arduino-blink/blob/example2/src/BlinkTimerControl.h
.. into the folder C:\git\arduino-projects\arduino-blink\src
In the Eclipse IDE select the arduino_blink project and press F5. This will refresh the source file list in the project tree and the new class will appear.
In the Blink Sketch file arduino_blink.cpp, add the following code fragments:
-
start with adding the
BlinkTimerControldependency inclusion:#include "BlinkTimerControl.h"
-
go ahead with adding the global variable definition for the
BlinkTimerControlobject instance:// global variable definition BlinkTimerControl* blinkTimerControl = 0;
-
within the existing
BlinkTimerAdaptertimeExpired()method, add the following call out after the one fortoggleLed():if (0 != blinkTimerControl) { blinkTimerControl->timeExpired(); }
-
insert the new function
serialEvent():/* SerialEvent occurs whenever new data comes in from the hardware serial RX. This routine is run between each time loop() runs, so using delay inside loop can delay response. Multiple bytes of data may be available. */ void serialEvent() { while (Serial.available()) { // get the new byte: char inChar = ( char)Serial.read(); if (0 != blinkTimerControl) { if ('d' == inChar) { blinkTimerControl->decrementBlinkTime(); } else if ('i' == inChar) { blinkTimerControl->incrementBlinkTime(); } } } }
-
replace the existing
setup()function implementation by the following one:void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); BlinkTimerAdapter* blinkTimerAdapter = new BlinkTimerAdapter (); blinkTimerControl = new BlinkTimerControl(blinkTimerAdapter, BLINK_TIME_MILLIS); //blinkTimer = new Timer(new BlinkTimerAdapter(), Timer::IS_RECURRING, BLINK_TIME_MILLIS); }
Please find the example code with the controllable Timer: https://github.com/ERNICommunity/arduino-blink/blob/example2/src/arduino_blink.cpp
Go to Top - Go back Home - Go back to the previous step: Project Repository and Workspace Preparations