Multitasking/multithreading in C on Arduino

Doing multitasking/multithreading on Arduino has an advantage, it’s give the possibility to read multiple captors, blink led and start a motor at virtually the same time. This is done by cycling rapidly (faster as the Arduino can) witting all the functions. I made up this code to execute many functions in the default cycling loop function on the Arduino. In the sample, the starting functions are hard coded, but The program offer the advantage of starting and stopping functions at run time. In a more complex program I’m doing it by adding a serial communication ability to the code, so I can call only the functions I need.

// By kevin@playwithmyled.com - 2009-10-17.
// 2010-05-11: Better and lighter.

// Define a function pointer and initialize to NULL.
typedef void (*FunctionPointer) ();

// Declare looping actions function names, declared lower.
FunctionPointer xActions[] = {loopActionA,loopActionB,loopActionC};
// Define actions status flags. Set to 1 to auto execute a start.
int xActionsFlags[] = {0,0,0}; 

int xActionsCount = sizeof(xActions);

void xActionTrigger(int id=0, int action=0) {
  // The id represent it's position in the flags array.
  // Action 1 = executed, 0 not.
  xActionsFlags[id] = action;
}

// LOOPING FUNCTIONS

void loopActionA() {
        // Do something...
}

void loopActionB() {
	// Do something...
}

void loopActionC() {
	// Do something...
}

// Exectute all loop functions.
void xDoActions() {
	// Execute all looped function.
	for(unsigned int j=0; j < xActionsCount; j++) {
		if( xActionsFlags[j] == 1 ) { // Execute the action if.
			xActions[j](); // Call the related loop action.
		}
	}
}

void setup() {
        xActionTrigger(0,1); // First action.
        xActionTrigger(2,1); // Third action.
}

void loop() {
	xDoActions();
}

8 thoughts on “Multitasking/multithreading in C on Arduino

  1. I don’t get the point of your piece of code. This is actually not a multithreading program is it ?

    Specificly here : xActions[xActionsFlags[j]]();
    if xActionsFlags[j] can be 1 or 0, how can you call your loopActionC function ? Did you mean xActions[j](); ?

    Considering you wait the task to finish (because you just call it but don’t abort it), this has nothing to do with realtime or multithreading software !

    Can you explain what did you try to do when you wrote this code ?

  2. @Brewal Renault. I have made some improvement to this code, but the principle is about the same. What I wanted there, is a program that can flag ON or OFF a function to be called. So a button can activate the flag of a function and when it’s ON, the function is automatically called in the main loop. Maybe it’s not true multitasking, but the objective of running multiple tasks at virtually the same time is met. I wanted a program that can make a stepper run (each step at a time) while the program continue to check other stuff like buttons. I know I can do some of that with interrupt too. Indeed, called functions must not take the loop and too much time to execute their task. So like for spinning a stepper, I use timer and static variable in the function and I don’t loop in the function. Each time the function is called from the main loop, I check if the motor is ready to move a step, if yes I do it and return. I hope I make me understandable. If you have betters idea, I am really open to it!

  3. Ok, I see what you are doing ! This script is indeed quite interesting. But, if you want your system to operate so, you can use an RTOS. You can use DuinOS, an RTOS based on FreeRTOS. This OS is easy to use, but you should take a look at the FreeRTOS website in order to understand how it runs.
    I used it for a project, and it works like a charm !

    But your script has the advantage of being robust and convenient for small specific applications.

  4. You look like an expert on Arduino multi-tasking, i’m struggling with Serial communication and multitasking. I programmed a piece of code that read serial commands and executes it, such as “Turn LED ON”, “Turn LED off”, etc… but i’m not sure how to do something like “BLINK LED ON”, “BLINK LED OFF”…. the minute i get into the blink led loop, i’m unable to send a serial command… Any ideas?

  5. Thank you, but I am no expert. I’m just doing my best. You can’t use the delay function in your program. This function makes everything else, like the serial connection, hang until the delay is past. You must use the time in your loop. When the right time is reach, you tell your function to do what you need. Else you let the program continue. Take a look at the motorSpin function in my stepper motor controller program for an example.

  6. Thank you for the sample.
    I have found a little error in xDoActions() :

    change row
    xActions[xActionsFlags[j]]();

    in
    xActions[j]();

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>