I was in need for a task switching thingy, too. So I took the above code as an inspiration. I changed the following:
- longest wait time now unsigned long (longer wait than 32s)
- removed the sorting of the task list
(is it really needed to have a sorted list? is it faster than looking up?
qsort costs about 1,5k, so I think: no)
- changed task indexer to byte
- appendTask does not add to many tasks...
- at least handle the millis()-overflow somehow
So I got a small little piece of code that lives well in a IDE-TAB and can be compiled with only adding one line of code (due to some Arduino IDE limitations).
Now it would be a good idea to optimize the wait-while-loop. Something like "let it sleep" or so.
Comments welcome.
#define maxtasks 10
// Die Task-Struktur
struct Task {
unsigned long time;
unsigned long (*func)();
};
struct Task tasks[maxtasks];
byte tasksLen = 0;
void appendTask(unsigned long (*func)()) {
if (tasksLen<maxtasks) {
tasks[tasksLen] = (struct Task) {
millis(), func
};
tasksLen++;
}
// und wie kriegt man mit, dass es zu viele Tasks sind?
}
void runNextTask() {
byte t;
static unsigned long lastmillis = 0;
// overrun detect
if (lastmillis>millis()) {
// reset all times.
for (byte i=0;i<tasksLen;i++) {
tasks[i].time=0;
}
}
lastmillis=millis();
if (tasksLen > 0) {
t=0;
for (byte i=0;i<tasksLen;i++) {
if (tasks[i].time<tasks[t].time) {
t=i;
}
}
while (tasks[t].time > millis()) {
// pass
}
tasks[t].time = tasks[t].func();
tasks[t].time += millis();
}
}
Blink looks like this
const int ledPin = 13;
// this should not be needed and been catched by Arduino... but it isn't.
void appendTask(unsigned long (*func)());
unsigned long blink() {
digitalWrite(ledPin, ! digitalRead(ledPin));
return 1000;
}
void setup() {
pinMode(ledPin, OUTPUT);
appendTask(blink);
}
void loop() {
runNextTask();
}