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
- Avoid blocking calls such as delay() or wait loops.
- Identify the parallel tasks
- For each task have two methods, setup_task_x() and loop_task_x().
- 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();
...
}