Threading in Arduino

Often times in programming we run into scenarios where one task can “block” execution, resulting in other tasks to wait for the “blocking” task to finish execution. For example, you might have a situation where you have to read sensors, flip switches, and write information to a display at the same time.

Arduino does not natively support multiple threads, but there is a way to get threaded programming to work on these micro-controllers. This can be done by using protothreads. 1 Designed for severely memory constrained systems, protothreads are extremely lightweight and stackless threads.

Making use of protothreads on Arduino hardware is very easy. Download and install the library to your Arduino Libraries directory.

The following example will show you how to thread execution of two different LEDs, one flashing every 500 milliseconds (half of a second) and the other flashing every 1000 milliseconds (one second).
First, include the library

#include 

Next, assign pin 4 and 5 to the LEDs, and give each LED a time-out. Also create two Protothread variables: pt1, and pt2.

static int LED_1 = 5;
static int LED_2 = 4;

static long LED_1_BLINK =  500; //500 milliseconds
static long LED_2_BLINK = 1000; //1 Second

static struct pt pt1, pt2;

Create a function that will toggle the state of the LED. It reads the current state, and writes the opposite state.

void led_toggle( int led )
{
  digitalWrite( led, !digitalRead( led ) );
}

This is where the magic happens: Create two functions, one called thread1 and another called thread2. Each function will take 3 parameters:

  1. pt: A reference to the Protothread variable.
  2. led: The LED you want to use with this thread.
  3. timeout: The length of time before the LED will change state.

First, you have to declare the start of the thread, using PT_BEGIN.
Second, block the execution and wait until a condition is true, using PT_WAIT_INTIL. In this case, (millis – previous millis) > timeout.
Third, run the code once the previous condition resulted in true.
And finally, signal the end of the thread, using PT_END.

static int thread1( struct pt *pt, int led, long timeout ) {
  static long t1 = 0;
  PT_BEGIN( pt );
  while(1) {
    PT_WAIT_UNTIL( pt, (millis() - t1) > timeout );
    led_toggle( led );
    t1 = millis();
  }
  PT_END( pt );
}

static int thread2( struct pt *pt, int led, long timeout ) {
  static long t2 = 0;
  PT_BEGIN( pt );
  while(1) {
    PT_WAIT_UNTIL( pt, (millis() - t2) > timeout );
    led_toggle( led );
    t2 = millis();
  }
  PT_END( pt );
}

In the setup function, initialise a protothread using PT_INIT and a pointer to the thread variable.

void setup() {
  pinMode( LED_1, OUTPUT );
  pinMode( LED_2, OUTPUT );
  PT_INIT( &pt1 );
  PT_INIT( &pt2 );
}

The loop function will call the thread functions created above. It will pass a pointer to the thread variable, the LED to toggle, and the time to delay the thread.

void loop() {
  thread1( &pt1, LED_1, LED_1_BLINK );
  thread2( &pt2, LED_2, LED_2_BLINK );
}

Protothreads has an API that consists of more than what was listed above. Hopefully this is enough to get you started.

Below is an example of the code above, running on an ADK with two LEDs:

Share:

Notes:

  1. http://www.sics.se/~adam/pt/about.html

2 thoughts on “Threading in Arduino

  1. Tharanga

    Thanks for the article. I’m new to Arduino yet not for programming. I was wondering if I can read several sensors simultaneously and run the logic accordingly. This was it. Thank you

Leave a Reply