The PQRST library: Priority Queue for Running Simple Tasks

This is a library, initially targeted at the Arduino, to provide simple ‘thread’ support (very much in scare-quotes). This is version 1.0, 2018 August 18 (rev 35be58e470c3).

The software is Copyright 2017–18, Norman Gray, and is available under the terms of the 2-clause BSD licence. It is therefore perfectly happy to disappear into your source tree.

The code is available at bitbucket. The code should still be regarded as beta; but it is stable, and used in production.


This module implements a Priority Queue for Running Simple Tasks. It is intended to support a simple but very flexible threading framework for Arduino tasks.

When code uses this module, it should declare one or more subclasses of the Task class, and in each of those declare and implement at least the run method (overriding Task::run. These can then be queued using the Task::start method. There is a pre-existing subclass called LoopTask, which is a task which automatically re-queues itself at a specified cadence.

The main loop of the program should then call TaskQueue::run_ready when it has nothing else to do, which will run any task which has become due.

Although the module is currently targeted at the Arduino, it has only a rather loose dependence on the Arduino framework (it uses the Serial object for some non-essential debugging and the PROGMEM type for a version string in Flash). It could therefore be ported to a different framework without much difficulty. In particular, the library does not depend on the Arduino millis() function.


For example, here is the Arduino ‘blink’ program, implemented with a task loop:

#include "pqrst.h"

class BlinkTask : public LoopTask {
    int my_pin_;
    bool light_on_p_;
    BlinkTask(int pin, ms_t cadence);
    void run(ms_t) override;

BlinkTask::BlinkTask(int pin, ms_t cadence)
    : LoopTask(cadence),
    // empty
void BlinkTask::run(ms_t t)
    light_on_p_ = !light_on_p_;
    digitalWrite(my_pin_, light_on_p_);

// flash LED at a 500ms cadence
BlinkTask flasher(LED_BUILTIN, 500);

void setup()
    flasher.start(2000);  // start after 2000ms (=2s)

void loop()

The code has compile-time options for

Use and documentation

To use, drop the files pqrst.cpp and pqrst.h into your source tree.

To run the unit tests, run make check in the distribution directory.

The main documentation, currently, is the class and function documentation, generated by Doxygen.

Norman Gray
2018 August 18