Maker Pro
Maker Pro

Multitasking an Arduino

This may be the dumbest question ever posted here. An Arduino controller can obviously monitor a variable, and post serial data to a display, or light a light, whatever. There are libraries for most sensors, but my question is, can the controller do more than one job?
For example, can it access a RTC chip, write the date and time to a display, while also comparing the time to a schedule so it can activate relays at preprogrammed times, monitor keyboard input to alter the schedule, and sound an alarm if a parameter gets out of bounds? This is pretty standard stuff for a PLC, but on a simple Arduino, do you just program the tasks in succession, one after the other, in a single program, and then put a return to start at the end? Alternately, can there be a separate routine for each job, that gets called from a master program as needed? I have developed programs for high level controllers, but have never had any experience with a microcontroller. There are lots of Arduino programming examples posted, but they all seem to do just one basic task.
 
The way that the Arduino programming works is a linear loop, so it goes from the top to the bottom, then back again, so programming just this way will lead to only doing one task at a time.

Libraries, knowledgeable programming and the clever use of interrupts can lead to what seems like multitasking.

For your example (which sounds to be on the end of what the Arduino would be capable of) I would first off set the parameter with the alarm on an interrupt, so that if the state changes to the alarm parameter it will jump to the function, change the alarm output, then jump right back into your program while throwing an alarm.
There are libraries that will read and output the date and time at given intervals, as well as libraries that will take keyboard input into a "buffer" of sorts. Then you would just have to set up the steps so that it doesn't have delays, it just constantly loops through everything looking at everything checking to see if anything has changed.
 
Well, I got two good answers, that more accurately describe the two methods I speculated on in my original question. We have used state machine programming in our high level PLCs, which have control blocks (or statements) which make it very easy.
Using precisely that process for a MCU is something I had not arrived at, but the article cited makes the method very clear.
I thank you all for your quick and insightful answers. Great to have a resource like this forum on-line.
My application is a relatively simple dispenser for animal feed, but it incorporates sensors to detect and alarm malfunctions [if any :D] .
Even an inexpensive dedicated PLC would have been overkill for this, so i thought it was time to investigate the Arduino.
Thanks!
j.w.
 
Any microcontroller can only do one thing at any time, but it can be made to do those things so fast that it looks like it is doing several things at the same time.

I've made many such systems or programs during my worklife. One really important this to remember i such a system, is that you can't wait for things to happen, you need to use semaphores to indicate that things are ready to be processed, and use interrupt routines wherever it is possible to enhance the reaction speed for external in- and outputs.
I normally use what is called a round-robin main routine that call the different sections of your program as fast as it can run around, and only process the the section if there is anything to do.
A good timer system is more or less necessary to manage all the different 'processes'.

If a section is heavy to process, you need to chunk it up in smaller pieces to let other sections to be processed in between.

You should also remember that you can't do more than the microcontroller allow you, and that the bandwidth of the processing speed manage. Whenever you put in fancy overhead to 'let you do more in the same time' you just fool your self.

The idea is to make the system as light in overhead as possible. The proverb 'less is more' is very much a truth in this context.
 
I know I could not do true "multitasking". I just was not sure about the best way to get several things done in one MCU. This application really has no critical timing. When we do a MMI, we have found that when a human pushes a (real) pushbutton, the push has to be recognized in not more than 300 milliseconds. If it takes longer, the human will see it as a malfunction. Not much of a problem anymore, as remote I/O processors and their communication buss are now very fast. As you say, keeping things simple is the way to go here, and if something does need to be recognized immediately, an interrupt can be generated to get the processors attention.
When I get this thing running, maybe I can "You Tube" video it, and send you all the URL. Probably be pretty funny!
Thanks for the help,
j.
 
Last edited:
As far as I understand your requirements the only time critical task would be recognizing and handling the keyboard input. As you say, you must react to a button press in well under 300mS. If you can get around everything in the round-robin scheduler fast enough worst case then you can also handle the keyboard that way. Otherwise I would either create an interrupt whenever a key was pressed or poll the keys from a timer driven interrupt task.
 

KrisBlueNZ

Sadly passed away in 2015
Good advice Steve, but there's probably little point posting on threads that are over a month old.
 
Thanks Steve,
I always welcome new input. Whatever I have done in the past can probably be done better in the future if I keep learning.
I kind of "cheated" in my application. I added a selector switch labeled, "input - run". Depending on the position, I can either "input" a new schedule with everything else on hold, or switch, and "run" the process, which reads the RTC, compares, activated outputs, counts cycles, and alarms a failed cycle, by monitoring a optical limit switch (and jumps around the keyboard service routine). One advantage is, I do not need to worry about a partially entered or incorrectly entered value initiating an unintended cycle or alarm. I can check the values on the display, and make sure I am happy with them before I move the switch from input back to run.
 
If you look at some of the Microchip examples, like their implementation of a webserver on a PIC, it demonstrates nicely a concept called 'cooperative multitasking'. Each task is programmed in a separate function or multiple functions that do less each. The main loop then calls each of these functions in turn. Critical sections are implemented relying on interrupts. The interrupts don't actually process the events, but handles the interrupt and raise them for processing in the main loop.

It is also possible to implement time-slicing, which is quite a bit more complicated. This was/is still used on many single processor systems. A timer interrupt is set up. At interrupt time. state of the running task is saved and control is given to the next task that is ready to run, after re-instating state. Tasks either have to request all I/O through the controller or mark their own entry as 'waiting I/O' or 'ready to run' in the task table (in its simplest form).

The main problem for PICs is that they do not run an operating system that takes care of task switching, CPU usage monitoring and I/O, the programmer of the PIC has to implement it. The benefit of this approach is that realtime processing is possible.
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
Good advice Steve, but there's probably little point posting on threads that are over a month old.

Steve, we say this because whenever we do, the original poster seems to come back to make a fool of us. :D At one point we had someone replying to threads that were years old. The term "necroposting" was used to describe his activity. However, one day the original poster showed up in one of these threads again and thanked him for solving the still outstanding problem.

I guess to summarise this thread I would say that you
  • do it fast,
  • do it often
  • don't code a delay.
If you plan on using a state machine, there is no reason you can't have multiple state machines running on the same processor with interleaved processing. As also mentioned, you can use interrupts to catch external events, but even then, you might just set a flag and have your code poll that flag regularly to determine when to actually process the event.
 
One trick when you use an interrupt timer routine, is to use a counter instead of a single flag. That way you will know if your state machine is executing too slow, and you will always run the correct number of timer ticks.
 

KrisBlueNZ

Sadly passed away in 2015
The main problem for PICs is that they do not run an operating system that takes care of task switching, CPU usage monitoring and I/O, the programmer of the PIC has to implement it.
The main problem with proper multi-tasking on the small PICs (PIC10, PIC12 and PIC16) is that it's impossible to do a stack switch! Even cooperative multitasking can't be implemented properly. This is one of the biggest weaknesses in the small PIC architecture; even the AVR can be stack-switched (apart from the ancient AT90S1200 which doesn't even have a stack IIRC!)
 
I am truly sorry if I've done the wrong thing by posting on an old thread. I didn't even notice the creation date when I looked for open threads that I could contribute to. The reason I wanted to add to this one is because I've been designing embedded controller products for the best part of 30 years and I know just how important it is to build fast, responsive devices.

Time slice type multitasking is great for multi-purpose, multi-user systems where every task must be kept independent of all others. Not so much for microcontrollers where you are in control of all aspects of every task. Time slicing would be an unnecessary burden.
 

(*steve*)

¡sǝpodᴉʇuɐ ǝɥʇ ɹɐǝɥd
Moderator
I am truly sorry if I've done the wrong thing by posting on an old thread.

You haven't done anything wrong. It's often more productive to reply to newer and current threads, but if you want to reply to any thread where you can provide useful input we're certainly not going to hold it against you.
 
Time slice type multitasking is great for multi-purpose, multi-user systems where every task must be kept independent of all others. Not so much for microcontrollers where you are in control of all aspects of every task. Time slicing would be an unnecessary burden.

I mentioned it for sake of completeness.
The code is too complex (for proper time-slicing) for the smaller PICs in any event. But a form of time slicing can be implemented by running different tasks a different number of times in a cycle - this is not true time slicing, but it does mean some tasks get more CPU then others. For example. you might only need to update a display once every 5 seconds, but have to monitor a temperature sensor all the time for a critical value.
The nature of PICs is such that most applications will use a combination of co-operative multi-tasking and interrupts to achieve to goal of the application.
 
Top