QP state machine framework for Arduino
Author:  Quantum Leaps
Contact: info@quantum-leaps.com


QP framework QP logo and books about QP


 4.5.03 2013-06-02: Updated for QP 4.5.03/QM 2.3.2 and Arduino-1.5.2
 4.5.03 2013-06-02: Updated for QP 4.5.03/QM 2.3.2 and Arduino-1.0.4
 4.5.02 2012-12-20: Added video "Getting started with QP/QM on Arduino"
 4.5.02 2012-08-25: Updated for QP 4.5.02/QM 2.2.02 and Arduino-1.0.1
 4.3.00 2011-12-16: Updated for QP 4.3.00 and Arduino-1.0
 4.2.04 2011-09-25: Updated for QP 4.2.04 and QM 2.0.00
 4.1.06 2011-02-04: Initial Release for Arduino


QP is a lightweight, open source, state machine framework for microcontrollers such as Arduino. QP enables you to build well-structured and power-efficient event-driven programs as systems of concurrently executing state machines (active objects, a.k.a. actors). You can think of QP as a modern real-time operating system (RTOS) specifically designed for executing concurrent state machines. The QP framework does everything you can expect from a traditional RTOS, including fully preemptive multitasking, plus many things an RTOS can't do at all.

QP is also an excellent target for automatic code generation. To this end, QP is now supported by the the free graphical QM modeling tool, which can automatically generate complete Arduino sketches from state diagrams. Thus QP is your entry into graphical programming for Arduino.

QP improves productivity, because your programs stay responsive to new events as you keep adding them. You also no longer need to struggle with convoluted if-else logic, because this "spaghetti" code is replaced with elegant state machines. And you get a powerful multitasking support, without worrying about semaphores and other such low-level mechanisms typically found in RTOSes. Instead, you can work at a higher level of abstraction of events, state machines, and active objects.


Traditionally, Arduino programs are written in a sequential manner, which means that whenever an Arduino program needs to synchronize with some external event, such as a button press, arrival of a character through the serial port, or a time delay, it explicitly waits in-line for the occurrence of the event. Waiting in-line means that the Arduino processor spends all of its cycles constantly checking for some condition in a tight loop (called the polling loop).

Although this approach is functional in many situations, it doesn't work very well when there are multiple possible sources of events whose arrival times and order you cannot predict and where it is important to handle the events in a timely manner. The fundamental problem is that while a sequential program is waiting for one kind of event (e.g., a button press), it is not doing any other work and is not responsive to other events (e.g., characters from the serial port).

Another big problem with the sequential program structure is wastefulness in terms of power dissipation. Regardless of how much or how little actual work is being done, the Arduino processor is always running at top speed, which drains the battery quickly and prevents you from making truly long-lasting battery-powered devices.

For these and other reasons experienced programmers turn to the long-know design strategy called event-driven programming, which requires a distinctly different way of thinking than conventional sequential programs. All event-driven programs are naturally divided into the application, which actually handles the events, and the supervisory event-driven infrastructure (framework), which waits for events and dispatches them to the application. The control resides in the event-driven framework, so from the application standpoint, the control is inverted compared to a traditional sequential program.

It turns out that the QP state machine framework beautifully complements the Arduino platform and provides everything you need to build responsive, robust, and power-efficient Arduino programs based on modern hierarchical state machines. Enjoy!

Download and Installation

Download latest version of QP for Arduino from SourceForge.net

The content of the qp_arduino_1.5.x.zip file is shown below:

 +-doc/                 - documentation
 | +-AN_Event-Driven_Arduino.pdf – this document
 | +-AN_DPP.pdf         – Dining Philosopher Problem example application
 | +-AN_PELICAN.pdf     – PEdestrian LIght CONtrolled (PELICAN) crossing example
 | +-arduino/
 | | +-avr/             - Libraries for AVR-based Arduinos
 | | | +-libraries/     ==> goes to <Arduino>/hardware/arduino/avr/libraries/ folder
 | | | | +-QP/           - QP library for AVR-based Arduinos
 | | | | | | +-examples/ - Examples for the QP library
 | | | | | | | +-blinky/     – Very simple “blinky” example
 | | | | | | | | +-.blinky   - The QM session file for the Blinly project
 | | | | | | | | +-blinky.qm - The QM model of the Blinky application
 | | | | | | | +-dpp_qk/     – DPP-QK example with preemptive QK kernel (Section 7)
 | | | | | | | | +-.dpp      - The QM session file for the DPP project
 | | | | | | | | +-dpp.qm    - The QM model of the DPP application
 | | | | | | | +-pelican/    – PEdestrian LIght CONtrolled (PELICAN) crossing example
 | | | | | | | | +-.pelican  - The QM session file for the PELICAN project
 | | | | | | | | +-pelican.qm- The QM model of the PELCIAN crossing application
 | | | | | | |
 | | | | | | +-COPYING.txt   - terms of copying this code
 | | | | | | +-GPL2.TXT      - GPL version 2 open source license
 | | | | | | +-qp.cpp        - QP/C++ platform-independent implementation
 | | | | | | +-qp_port.cpp   - QP/C++ port for Arduino implementation
 | | | | | | +-qp_port.h     - QP/C++ port for Arduino interface
 +-tools/             ==> goes to the <Arduino>/tools/ folder
 | +-qtools/            - tools contributed Quantum Leaps
 | | +-COPYING.txt      - terms of copying this code
 | | +-GPL2.TXT         - GPL version 2 open source license
 | | +-avrmake.tcl      – Generic TCL script for building Arduino/AVR sketches
 | | +-arduiniodude.exe – Arduino programming utility (calls avrdude.exe)
 | | +-rm.exe           – Command-line utility for removing files (cleanup)

Installation of QP for Arduino consists of simply expanding the ZIP archive into the same directory, into which you've installed the standard Arduino software.


The qp_arduino-1.5.x.zip file contains the following documentation in the folder doc\.

Application Note: Event-Driven Arduino Programming with QP describes the main concepts and how to build QP applications for Arduino.

Application Note: Dining Philosopher Problem describes the DPP example application (see Examples below).

Application Note: PEdestrian LIght CONtrolled (PELICAN) Crossing describes the PELICAN crossing example application (see Examples below).


Starting with QM 2.3.x, you can build, upload, and run the Arduino projects directly from the QM tool, without the need to launch the standard Arduino IDE (although the standard Arduino software must be installed, because the compiler, linker, and other tools from it are used in the build process.)

Blinky Example

The Blinky example demonstrates a simple 2-state state machine to blink the LED of Arduino UNO board once a second.

The Blinky QM model file is located in <Arduino>\hardware\arduino\avr\libraries\qp\examples\blinky\blinky.qm.

PEdestrian LIght CONtrolled (PELICAN) Crossing

The PELICAN crossing example demonstrates a non-trivial hiererchical state machine.

The PELICAN QM model file is located in <Arduino>\hardware\arduino\avr\libraries\qp\examples\pelican\pelican.qm.

To see the output from the PELICAN crossing example, you need to launch a serial terminal program, which runs outside the QM tool. The tools pre-configured in the provided examples, use the TeraTerm serial terminal, which can be downloaded freely from the Internet.

The PELICAN crossing example requires you to inject events to the application by sending key strokes via the Serial Monitor:

  • 'p' for PEDS_WAITING,
  • 'f' for OFF (to switch the crossing OFF for maintenance),
  • 'o' for ON (to switch the crossing back online).

Dining Philosopher Problem (DPP) Example with Preemptive QK Kernel

The DPP-QK example demonstrates multiple state machines running on top of a preemptive QK kernel.

The DPP-QK QM model file is located in <Arduino>\hardware\arduino\avr\libraries\qp\examples\dpp_qk\dpp_qk.qm.

More Information and Resources

Last Modified: December 29, 2014, at 01:44 PM
By: Quantum Leaps