TaskScheduler
TaskScheduler copied to clipboard
Defined tasks not working depending on files alphabetical order
Based on: TaskScheduler/examples/Scheduler_example16_Multitab/Scheduler_example16_Multitab.ino It says that Arduino IDE plays some dirty tricks on main sketch file and it rearranges #includes, blindly creates forward definitions. However, developing in PlatformIO I faced the bug that the blank .ino file workaround didn't help and one of my tasks which was defined in file didn't want to execute. After couple of hours on trying to narrow down the issue, found that if I simply rename the file where my task is to make it appear alphabetically earlier than main.cpp, then it fixes the issue.
Example: ultrasound.cpp & ultrasound.h -> contains Task loopUltrasound which periodically invokes itself; main.cpp -> defines Scheduler runner; setup() and loop() with runner.execute();
Workaround Fix:
- rename main.cpp to zzmain.cpp
Alternative workaround Fix:
- rename file ultrasound to aUltrasound
Not sure why it behaves such way, but I hope it helps to narrow down the issue.
As usual, need to see the source code to be able to attempt to help.
Source code: https://github.com/vvinjj/TaskShedulerAbcIssue
Unfortunately, I do not use Platform.io, but on the surface of things: why not include the external reference to scheduler into aTaks.h file since you need it to create a task in aTask.cpp?
Perhaps you misunderstood the issue as TaskA is working anyway, but TaskZ is not (but is structurally identical, only file name is different). Refactored example to be compatible with Arduino IDE: https://github.com/vvinjj/ArduinoTaskSchedulerAbcIssue If you rename taskZ.cpp to taskB.cpp, close IDE and re-open (as IDE has some cache related bug) then compile, you will see that both tasks starts working.
Indeed, it does not work, probably because of the sequence of declarations. I am not using CPP/HPP files for Arduino, so never saw this issue. As a workaround this works:
header.hpp:
#include <TaskSchedulerDeclarations.h>
//Let the runner object be a global, single instance shared between object files.
extern Scheduler runner;
extern Task taskA;
extern Task taskZ;
aTask.cpp:
#include <Arduino.h>
#include "header.hpp"
void printTaskA();
Task taskA(TASK_SECOND, TASK_ONCE, &printTaskA);
void printTaskA() {
Serial.println("taskA is working as appears alphabetically earlier than main.cpp");
taskA.restartDelayed(TASK_SECOND);
}
zTask.cpp:
#include <Arduino.h>
#include "header.hpp"
void printTaskZ();
Task taskZ(TASK_SECOND, TASK_ONCE, &printTaskZ);
void printTaskZ() {
Serial.println("taskZ is NOT working as appears alphabetically later than main.cpp");
taskZ.restartDelayed(TASK_SECOND);
}
main.cpp:
#include <Arduino.h>
#include "header.hpp"
Scheduler runner; //Let the scheduler live here, in the main file
void setup() {
Serial.begin(115200);
Serial.setDebugOutput(true);
runner.addTask(taskA);
runner.addTask(taskZ);
runner.enableAll();
}
void loop() {
runner.execute();
}
Please let me know if you find a more elegant solution.
I think in your solution you can remove from header.hpp: extern Scheduler runner; as not needed anymore. As I mentioned initially I was trying to utilize the example taken from: TaskScheduler/examples/Scheduler_example16_Multitab/ which uses the CPP/HPP files. So, the only thing I can suggest is to either update the example to make it a bit clear about such potential issue or add the current example for guidance. More generally I think the only way to prevent the issue from happening would require non-backwards compatible library code change to initialize the runner differently in relation to its tasks. Thanks for your library anyway.
I am using PlatformIO too and I have the same issue, where frusting I changed main.cp to zzzmain.cpp according the workaround from @vvinjj
@arkhipenko It will usefull to put this information clearly somewhere to prevent people to looking for a bug in their own code And perhaps found a solution to prevent that...
Very usefull lib, thanks