Multi tasking with no RTOS and multi threading

Forking from another thread.

The high level goals are

  • Using a single thread (Arduino style)
  • Having multiple tasks performed in parallel.
  • Efficient, modular and readable code.

My general approach is

  1. Avoid blocking calls such as delay() or wait loops.
  2. Identify the parallel tasks
  3. For each task have two methods, setup_task_x() and loop_task_x().
  4. Call the tasks setup and loop methods from the main setup() and loop().

An example, a task that allows the user to toggle led blinking rate with button clicks, with proper switch debouncing. (This is pseudo code, you will need to tweak it to compile)

#include "button.h"
#include "elpased.h"

bool high_speed = false;  // True if the led should blink at high rate
Elpased timer1;  // Timer to time the blinking period
bool led_state = true;  // The current state of the led
Button my_button(button pin);  // Button input, with debouncing and event detection

setup_task1() {
  // Init LED
  Setup led as output
  digital_write(led, led_state);
}

loop_task1() {
  // Process button.
  if (button.update() == EVENT_SHORT_CLICK) {
    high_speed = !high_speed;  // Toggle rare.
  }

  // Process LED.
  int rate_millis = high_speed ? 100, 300;
  if (timer1.elpased_millis() >= rate_millis) {
    led_state = !led_state;  // Toggle state
    digital_write(led, led_state);  // Update LED
    timer1.reset();  // start counting time again.
  }
}

Sample files

I also use C++ namespaces to separate between the tasks for this is optional. E.g.

namepsace task1 {
  void setup();
  void loop();
  ...
}