PC Services


PC Services (Electronics)

Co-operative Run to completion Scheduler

Tel: 0118 946 3634

linked-in profile facebook profile

   The Company 
   Resources / Examples 
     Simple Scheduler 

Arduino Task Scheduler

Often in your system you need to perform tasks at regular intervals, or at varying time intervals, or have some event (interrupt, command or similar) trigger a series of tasks to be done. One alternative is to make lots of complicated code to work out when to do things and put in lots of delays but this stops other things happening. The better way is to structure your individual tasks into small chunks or work and have a scheduler call it at regular time intervals, so that any delay time can be used by the other tasks.

For a brief introduction to scheduling read this document.

There are various ways to do this, and for Arduino environment there are many about, but as libraries. The problem with libraries is you end up having to use add and remove tasks dynamically using up memory and potentially causing heap fragmentation. Many of the implementations use large data structures, linked list management and other overheads.

For small microprocessor environments like Arduino, it is more economical to have a compile time not run time tasklist (list of tasks to run) which are either in running or stopped state. Especially as ALL the possible tasks are known at compile time, and no new tasks can be loaded from other media while your program is running.

One issue with all schedulers, is getting statistics and status of all tasks, to know what is set to run and when, how long they took last time and most important what was the worst case run time.

Scheduler Development

Board running a test scheduler application Having evaluated other solutions, then developed a solution which is a suite of files to add to a sketch (project), for minimal footprint and helper functions to make this easier. The details of the functions and installation are described in the instructions file and more details are described in the introduction document.

One of the tests for the scheduler was to create an application that run on a Due based DMX controller hardware, using

  • LCD to show a menu using four buttons as interrupts
  • A pot being read on analog pin, to control a PWM output for LCD backlight brightness
  • TWO LEDs used to flash at different rates - one continuous at 4Hz, the second when triggered runs at 10Hz for 2 seconds

The tasks running at different rates are -

  • Read a pot and adjust PWM to mtach level
  • LED Flash at 4Hz
  • On demand (switch press) flash LED at 10Hz for 2 seconds
  • Every pass of tasklist checksum 16 kB of RAM
  • On demand (switch press) output checksum HEX result to LCD
  • On demand (switch press) output to serial either log (copy of last tasklist run) or statistics

Example Application Results

So running this application, I was able to get statistics from the application. The first output was having run the Initialisation of the tasklist in setup() this particular example outputs to serial port, the tasklist status showing they have been initialised and how long they took and other details as below -

Current time - 121 ID Next Took Max Status Inter Ran 0 221 3 3 1 100 1 1 246 3 3 2 125 1 2 0 33 33 0 50 1 3 131 3 3 2 10 1 4 0 7 7 0 10 1 5 0 16 16 0 100 1


  • Current time, and columns Next and Inter are in milli-seconds
  • Columns Took and Max are in micro-seconds
  • Tasks with ID 2 and 4 have a status of 0 as in stopped, so they have only been initialised and are awaiting execution, in this case extra tasks initiated by other switches.

Having run for a while pressing buttons on the board in question outputs the tasklist copy to serial and the statistics. Below is example of tasklist then the statistics being output twice, this shows the statistics for some variables like Maximum Execution time is reset after reading to get a new maximum task time on second run. What this shows in this example is that the task to output the statistics (task ID 5) takes 4652 micro seconds (4.652 milli seconds) to output the tasklist copy and 619 micro seconds to output the statistics. Most of this time is the time waiting for serial buffer on a DUE with size of 128 bytes to become available.

Current time - 72871 ID Next Took Max Status Inter Ran 0 72921 6 50 2 100 0 1 72916 31 31 2 125 0 2 0 33 33 0 50 1 3 72871 563 564 2 10 1 4 0 7 7 0 10 1 5 72871 2 16 2 100 0 Statistics Finish 84031 Start 84031 Diff = 0 Task Run - 1 Overdue by - 0 Max - 0 Avg - 0 Max exec - 4652 by - 5 Longest Loop Time 5 Statistics Finish 86691 Start 86691 Diff = 0 Task Run - 1 Overdue by - 0 Max - 0 Avg - 0 Max exec - 619 by - 5 Longest Loop Time 1

The tasklist copy shows what ran in that pass of the tasklist, and the statistics show what the longest total execution time is for longest task and longest tasklist loop time. As you know what the schedule loop time is, it is then possible to work out how long the application is idle (if at all).

Obtaining Scheduler and Other Details

This scheduler template and documents including an example is available from Github repository.

Whilst working on scheduler, it was discovered that the standard LiquidCrystal library was excessive on time delays and was blocking other tasks. This library was reviewed and some results and updates are discussed in Next Section on LiquidCrystal library.

Interested in something similar contact sales.

© 2016 onwards by PC Services, Reading UK Last Updated: 11th April 2016
If you encounter problems with this page please email your comments to webmaster