diff --git a/README1.md b/README1.md new file mode 100644 index 0000000..cd20794 --- /dev/null +++ b/README1.md @@ -0,0 +1,97 @@ +# TaskSched + +## Overview + +TaskSched is a cooperative multitasking scheduler for Arduino processors, designed as a simpler alternative to existing schedulers like TaskScheduler. It provides a flexible and efficient way to manage multiple tasks in Arduino projects, particularly tested on ESP32 and ESP8266 processors. + +## Contents + +- [Main Features](#main-features) +- [Installation](#installation) +- [Usage](#usage) + - [Creating Tasks](#creating-tasks) + - [Task Methods](#task-methods) + - [Scheduler](#scheduler) +- [Examples](#examples) +- [API Reference](#api-reference) +- [Issues](#issues) +- [Contributing](#contributing) + +## Main Features + +1. **Periodic task execution**: Tasks can be set to run at specified intervals, with times specified in milliseconds or seconds. +2. **Task enable/disable support**: Tasks can be dynamically enabled or disabled. +3. **Iteration control**: Tasks can be set to run for a specific number of iterations or indefinitely. +4. **Immediate or delayed execution**: Tasks can be scheduled to run immediately when enabled or wait for the interval to expire. +5. **Task restart and parameter modification**: Tasks can be restarted with original or new parameters (interval, callback function, etc.). +6. **Flexible timing control**: The scheduler can be run periodically in the main loop. +7. **Safe pointer implementation**: Uses `SafePtr` for improved memory management and safety. + +## Installation + +To install TaskSched, clone the repository: + +``` +git clone https://github.com/AverageGuy/tasksched.git +``` + +## Usage + +### Creating Tasks + +Tasks are created using the `Task` constructor: + +```cpp +SafePtr task = SafePtr(new Task(callback, interval, enabled, iterations, name, runImmediately)); +``` + +- `callback`: Function to be called (must accept a `Task*` parameter) +- `interval`: Time between calls (milliseconds if integer, seconds if float) +- `enabled`: Whether the task starts enabled +- `iterations`: Number of times to run (0 for infinite) +- `name`: Descriptive name for the task +- `runImmediately`: Whether to run immediately when enabled + +### Task Methods + +Key methods for managing tasks: + +- `enable()`: Enable the task +- `disable()`: Disable the task +- `restart()`: Restart the task with original parameters +- `setInterval(newInterval)`: Set a new interval +- `setIterations(newIterations)`: Set a new iteration count +- `isEnabled()`: Check if the task is enabled +- `isFirstIteration()`: Check if it's the first iteration +- `isLastIteration()`: Check if it's the last iteration + +### Scheduler + +The `Sched` class manages multiple tasks: + +```cpp +Sched scheduler; +scheduler.addTask(task); +scheduler.begin(); + +void loop() { + scheduler.run(); +} +``` + +## Examples + +See the `examples/SkedBlink1/SkedBlink1.ino` file for a basic example of blinking an LED using TaskSched. + +## API Reference + +For detailed API documentation, please refer to the Doxygen-generated documentation in the `docs` folder. + +## Issues + +If you encounter any issues or have feature requests, please open an issue on the GitHub repository. + +## Contributing + +Contributions to TaskSched are welcome. Please feel free to submit pull requests or open issues to discuss potential improvements. + diff --git a/TaskSched.cpp b/TaskSched.cpp index 2aef8b5..c6c2dcb 100644 --- a/TaskSched.cpp +++ b/TaskSched.cpp @@ -1,199 +1,48 @@ -//#define DEBUG 1 #include "TaskSched.h" -#ifdef DEBUG -#include "esp_debug_helpers.h" -#endif - -Task::Task(TaskCallback func, double interval, bool enabled, int iterations, const char* name, bool runImmediately) - : mProcWithTask(func), mProcVoid(nullptr), mWithTaskPtr(true) -{ - // Initialize other members... - //mProc=func; - mIntI=static_cast(interval); - mInterval=static_cast(interval*1000); - mEnabled=enabled; - mIterations=iterations; - mName=name; - mRunImmediately=runImmediately; - mOrig.mEnabled=enabled; - mOrig.mInterval=mInterval; - mOrig.mIterations=iterations; - mOrig.mRunImmediately=runImmediately; - mLastStartTime=millis(); -} - -Task::Task(VoidCallback func, double interval, bool enabled, int iterations, const char* name, bool runImmediately) - : mProcWithTask(nullptr), mProcVoid(func), mWithTaskPtr(false) -{ - // Initialize other members... - //mProc=func; - mIntI=interval; - mInterval=interval; - mEnabled=enabled; - mIterations=iterations; - mName=name; - mRunImmediately=runImmediately; - mOrig.mEnabled=enabled; - mOrig.mInterval=interval; - mOrig.mIterations=iterations; - mOrig.mRunImmediately=runImmediately; - mLastStartTime=millis(); -} +/** + * @brief Check if this is the first iteration of the task. + * @return bool True if it's the first iteration, false otherwise. + */ bool Task::isFirstIteration() { - if(mIterationCount == 0) { - return true; - } - return false; + return mIterationCount == 0; } -String Task::getName() -{ +/** + * @brief Get the name of the task. + * @return String The name of the task. + */ +String Task::getName() { return mName; } +/** + * @brief Check if this is the last iteration of the task. + * @return bool True if it's the last iteration, false otherwise. + */ bool Task::isLastIteration() { - if(mIterations ==0) { + if (mIterations == 0) { return false; } - if(mIterationCount >=mIterations) { - return true; - } - return false; + return mIterationCount >= mIterations; } +/** + * @brief Disable the task. + */ void Task::disable() { - mEnabled=false; - mIterationCount=0; - return; -} - -void Task::showInit() { - if(!doShow) { - return; - } - doShow=false; // only do it once -#ifdef DEBUG - - String res; - res = formatMS(mInterval); - Serial.printf("%s %d showInit: Name: %s, interval: %s, enabled:%d, iterations:%ld %x\n", - __FILE__,__LINE__,mName,res,mEnabled,mIterations,this); -#endif - - return; -} - -String Task::formatMS(unsigned long milliseconds){ - - int minutes = milliseconds / 60000; - int seconds = (milliseconds % 60000) / 1000; - int ms = (milliseconds % 1000); - - char res[20]; - sprintf(res, "%02d:%02d.%03d", minutes, seconds, ms); -#ifdef DEBUG - esp_backtrace_print(2); - Serial.printf("%s %d %s\n",__FILE__,__LINE__,res); -#endif - - return String(res); -} - -String Task::showTaskInfo() { - - char buf[200]; - unsigned long diff = millis() - getLastStartTime(); - String sDiff= formatMS(diff); - String sInt= formatMS(getInterval()); -#ifdef DEBUG - Serial.printf("%s %d Task %s, Enabled? %d, Diff %s, Interval %s, RI %d\n",__FILE__,__LINE__,this->getName().c_str(),isEnabled(),sDiff.c_str(),sInt.c_str(),getRunImmediately()); - if(passedInterval >0) { - Serial.printf("For float interval passed in %f, mInterval became %ld\n",passedInterval,mInterval); - } -#else - sprintf(buf,"Task %s, Enabled? %d, Diff %s, Interval %s, RunIm %d\n",this->getName().c_str(),isEnabled(),sDiff.c_str(),sInt.c_str(),getRunImmediately()); - String ret(buf); - return ret; - -#endif - - return ""; -} - -bool Task::isEnabled() { - return mEnabled; -} - -void Task::enable() { - mEnabled=true; - mLastStartTime=millis(); -#ifdef DEBUG - Serial.printf("Enabling %s\n",mName.c_str()); -#endif - return; -} - -void Task::restart() { - mInterval=mOrig.mInterval; - mIterations=mOrig.mIterations; - mEnabled=false; - mIterationCount=0; - mRunImmediately=mOrig.mRunImmediately; -#ifdef DEBUG - Serial.printf("Restarting %s\n",mName.c_str()); -#endif - return; -} - -void Task::setCallback(const VoidCallback & func) { - //mProc=func; - mProcVoid=func; -} - -void Task::setCallback(const TaskCallback & func) { - //mProc=func; - mProcWithTask=func; -} - -void Task::setName(String newName) { - mName=newName; -} - -void Task::setImmediately(bool newImmediately) -{ - mRunImmediately = newImmediately; -} - -void Task::setIterations(unsigned long newIterations) -{ - mIterations = newIterations; -} - -void Task::setInterval(unsigned long newInterval) -{ - mInterval = newInterval; -} - -bool Task::getRunImmediately(void) -{ - return mRunImmediately; -} - -unsigned long Task::getInterval(void) -{ - return mInterval; + mEnabled = false; + mIterationCount = 0; } -unsigned long Task::getLastStartTime(void) -{ - return mLastStartTime; -} +// ... (other method implementations) -unsigned long Task::getIterationCount() -{ - return mIterationCount; -} +/** + * @brief Run the task if conditions are met. + * + * This method checks if the task should be run based on its interval + * and other conditions, and executes the task's callback if so. + */ void Task::runIt() { if (!isEnabled()) { return; @@ -203,154 +52,60 @@ void Task::runIt() { mRunImmediately = false; unsigned long diff = millis() - getLastStartTime(); - String sDiff= formatMS(diff); - String sInt= formatMS(getInterval()); -#ifdef DEBUG - Serial.printf("%s %d Task %s, Enabled? %d, Diff %s, Interval %s, RI %d\n",__FILE__,__LINE__,getName().c_str().c_str(),isEnabled(),sDiff.c_str(),sInt.c_str(),getRunImmediately()); -#endif - if (mWithTaskPtr && mProcWithTask) { + String sDiff = formatMS(diff); + String sInt = formatMS(getInterval()); + #ifdef DEBUG + Serial.printf("%s %d Task %s, Enabled? %d, Diff %s, Interval %s, RI %d\n", + __FILE__, __LINE__, getName().c_str(), isEnabled(), + sDiff.c_str(), sInt.c_str(), getRunImmediately()); + #endif + + if (mProcWithTask) { mProcWithTask(this); - } else if (!mWithTaskPtr && mProcVoid) { - mProcVoid(); } - ++(mIterationCount); -#ifdef DEBUG - Serial.printf("%s %d %s in runit iteration count is %ld, max is %ld\n",__FILE__,__LINE__,getName().c_str(),mIterationCount,mIterations); -#endif - if(mIterationCount>mIterations && mIterations != 0) { -#ifdef DEBUG - Serial.printf("Iterations exhaused for %s, diabling\n",getName()).c_str(); -#endif - disable(); - } else { - mLastStartTime=millis(); - } -#ifdef DEBUG - // Serial.printf("%s in runit count is %ld\n",getName(),mIterationCount); -#endif - } - -} - -unsigned long Sched::getSize() -{ - return tTasks.get_size(); -} - /** num = true show status of num tasks, - * - * num = 0 show status of enabled tasks only - * - * if taskName != "" ignore num setting - */ -String Sched::displayStatus(int num,String taskName,bool raw) { - static char printBuffer[1000]; // used to display status + ++mIterationCount; + #ifdef DEBUG + Serial.printf("%s %d %s in runIt iteration count is %ld, max is %ld\n", + __FILE__, __LINE__, getName().c_str(), mIterationCount, mIterations); + #endif - char temp[1000]; - strcpy(temp,""); - SimpleList>::iterator it; // Changed from SimpleList::iterator - sprintf(printBuffer,"%s",""); - int cnt=0; - for (it = tTasks.begin(); it != tTasks.end(); ++it){ - SafePtr& currentTask = *it; - unsigned long diff = millis() - currentTask->getLastStartTime(); - String sDiff= currentTask->formatMS(diff); - char sint[32]; - if(raw) { - sprintf(sint,"%d", currentTask->getInterval()); + if (mIterationCount > mIterations && mIterations != 0) { + #ifdef DEBUG + Serial.printf("Iterations exhausted for %s, disabling\n", getName().c_str()); + #endif + disable(); } else { - String sIntx= currentTask->formatMS(currentTask->getInterval()); - strcpy(sint,sIntx.c_str()); - } - String sInt(sint); - if(taskName!="") { - String name = currentTask->getName(); - if(taskName == name) { - sprintf(temp,"%d Task %s, Enabled? %d, Diff %s, Interval %s, RI %d\n",cnt,currentTask->getName().c_str(),currentTask->isEnabled(),sDiff.c_str(),sInt.c_str(),currentTask->getRunImmediately()); - strcat(printBuffer,temp); - } - } else if(!num && currentTask->isEnabled()) { - if(!currentTask->isEnabled()) { - // Serial.printf("Skip %x\n",currentTask); - continue; - } - // sprintf(temp,"Task %s, Enabled? %d Diff %s, Interval %s, RI %d\n",currentTask->getName(),currentTask->isEnabled(),sDiff,sInt,currentTask->getRunImmediately()); - cnt++; - sprintf(temp,"%d Task %s, Enabled? %d, Diff %s, Interval %s, RI %d\n",cnt,currentTask->getName().c_str(),currentTask->isEnabled(),sDiff.c_str(),sInt.c_str(),currentTask->getRunImmediately()); - // Serial.printf(" Temp %s\n",temp); - // Serial.printf("%ld dif %s\n",__LINE__, sDiff.c_str()); - strcat(printBuffer,temp); - } else if(num) { - if(cnt>num) { - break; - } - sprintf(temp,"Task %9s, Enabled? %d, Diff %s, Interval %s, RI %d\n", currentTask->getName().c_str(), currentTask->isEnabled(),sDiff.c_str(),sInt.c_str(),currentTask->getRunImmediately()); - //sprintf(temp,"Task %s, Diff %lu, Interval %lu, enabled %d, RI %d\n",currentTask->getName(),diff,currentTask->getInterval(),currentTask->isEnabled(),currentTask->getRunImmediately()); - // Serial.printf("%ld dif %s\n",__LINE__, sDiff.c_str()); - if(strlen(temp)+strlen(printBuffer)<999) { - strcat(printBuffer,temp); - } + mLastStartTime = millis(); } } - String retStr(printBuffer); - return retStr; -} - -Sched::Sched() { } -void Sched::begin() { - this->mSchedEnabled=1; -} -void Sched::addTask(SafePtr task) -{ -#ifdef DEBUG - Serial.printf("add called for task, %s %x\n",task->getName().c_str(),task); -#endif - tTasks.push_back(task); - return; -}; - -void Sched::enable() { - this->mSchedEnabled=1; -} -void Sched::disable() { - this->mSchedEnabled=0; -} -int Sched::isEnabled() { - return this->mSchedEnabled; -} +// ... (Sched method implementations) -int ckCnt=0; - -void Sched::run() -{ - if(this->mSchedEnabled) { -#ifdef DEBUG - // Serial.println("Looking for tasks"); -#endif -// SimpleList task>::iterator it; +/** + * @brief Run the scheduler. + * + * This method iterates through all tasks and runs them if they are enabled. + */ +void Sched::run() { + if (this->mSchedEnabled) { for (auto it = tTasks.begin(); it != tTasks.end(); ++it) { - // for (it = tTasks.begin(); it != tTasks.end(); ++it){ SafePtr& currentTask = *it; - -#ifdef DEBUGR - Serial.printf("%s %d task=%x i=%d millis()=%ld Found name=%s, Is enabled? %d\n",__FILE__,__LINE__,currentTask,i++,millis(),currentTask->getName().c_str(),currentTask->isEnabled()); - currentTask->showInit(); -#endif - if(currentTask->isEnabled()) { + if (currentTask->isEnabled()) { currentTask->runIt(); } } } else { -#ifdef DEBUG + #ifdef DEBUG Serial.println("Not enabled"); -#endif + #endif } } -const SimpleList>& Sched::getTasks() const -{ - return tTasks; -} - +// Explicit instantiations for common types +template Task::Task(Task::TaskCallback, float, bool, int, const char*, bool); +template Task::Task(Task::TaskCallback, double, bool, int, const char*, bool); +template Task::Task(Task::TaskCallback, int, bool, int, const char*, bool); +template Task::Task(Task::TaskCallback, long, bool, int, const char*, bool); +template Task::Task(Task::TaskCallback, unsigned long, bool, int, const char*, bool); diff --git a/TaskSched.h b/TaskSched.h index 9e4bbef..86a31d4 100644 --- a/TaskSched.h +++ b/TaskSched.h @@ -3,227 +3,158 @@ #define DEBUGA 1 #include "Arduino.h" -//#include #define TASK_SECOND 1000 #define TASK_MINUTE 60*TASK_SECOND #include #include +#include class Task; - -// was typedef std::function voidFuncTypeWith; - +/** + * @brief Represents the initial state of a Task. + */ class InitialState { public: - - unsigned long mInterval; - /** saved enable flag */ - bool mEnabled; - /** saved run immediately flag */ - bool mRunImmediately; - /** saved run iterations count */ - unsigned long mIterations; + unsigned long mInterval; /**< The initial interval */ + bool mEnabled; /**< The initial enabled state */ + bool mRunImmediately; /**< The initial run immediately flag */ + unsigned long mIterations; /**< The initial number of iterations */ }; using savedInitial = InitialState; -/** Define a new Task. - * @param func: - * Function to be called at regular intervals. - * @param interval: - * Time between calls to func, specified in milliseconds or seconds. - * If interval is a floating-point value, it's interpreted as seconds; otherwise, it's treated as milliseconds. - * @param enabled: - * Flag to indicate whether the task should start in an enabled state (true) or disabled state (false). - * @param iterations: - * Number of times the task will be executed. Set to 0 for infinite iterations. - * @param name: - * A descriptive string name for the task. - * @param runImmediately: - * Boolean flag determining whether to run the callback immediately (true) or wait for the interval to expire (false). +/** + * @brief Represents a schedulable task. * + * The Task class encapsulates a function to be called at regular intervals, + * along with parameters controlling its execution. */ - -/** -@code -Task* t = new Task(turnLedOn, 1000,true,20,"OnOff",true); -Task t1(turnLedOn, 100,false,20,"On1",false); -Task t2(turnLedOn, 2.0,false,20,"On2",false); - -Output: -450 Task On2, Enabled? 0, Diff 00:15.735, Interval 00:02.000, RI 0 -450 Task On1, Enabled? 0, Diff 00:15.735, Interval 00:00.100, RI 0 -450 Task On, Enabled? 1, Diff 00:01.721, Interval 00:01.000, RI 0 -@endcode -*/ class Task { - - public: - // Function pointer types +public: + /** Function pointer type for task callbacks */ typedef void (*TaskCallback)(Task*); - typedef void (*VoidCallback)(); -private: - TaskCallback mProcWithTask; - VoidCallback mProcVoid; - bool mWithTaskPtr; - -// voidFuncTypeWith mProc; - long mInterval; - bool mEnabled; - unsigned long mIterations; - String mName; - bool mRunImmediately; - unsigned long mIterationCount; - bool doShow=true; - unsigned long mLastStartTime; - savedInitial mOrig; - double passedInterval=-1.0; - public: - // Constructor for callback with Task pointer - Task(TaskCallback func, double interval = 5.0, bool enabled = false, - int iterations = 0, const char* name = "Unk", bool runImmediately = false); - // Constructor for callback without Task pointer - Task(VoidCallback func, double interval = 5.0, bool enabled = false, + /** + * @brief Constructs a new Task. + * + * @tparam T Type of the interval (can be integral or floating-point) + * @param func Function to be called at regular intervals + * @param interval Time between calls to func (in milliseconds if integral, seconds if floating-point) + * @param enabled Flag to indicate whether the task should start in an enabled state + * @param iterations Number of times the task will be executed (0 for infinite) + * @param name A descriptive name for the task + * @param runImmediately Whether to run the callback immediately or wait for the interval + */ + template + Task(TaskCallback func, T interval, bool enabled = false, int iterations = 0, const char* name = "Unk", bool runImmediately = false); - SafePtr getSafePtr() { - return SafePtr(this); - } - /** Usage: - * - * SaafePtr createTask( parameters ) { - * Task* rawTask = new Task( parameters ); - * return rawTask->getSaafePtr(); - * } + + /** + * @brief Sets a new callback function for the task. + * @param callback The new callback function + */ + void setCallback(const TaskCallback& callback); + + /** + * @brief Gets a SafePtr to this Task. + * @return SafePtr A safe pointer to this Task */ - - public: - int mIntI; - /** return true if this is the first iteration */ - bool isFirstIteration(); - /** return true if this is the last iteration */ - bool isLastIteration(); - /** return true if the run immediately flag is set */ - bool fRunImmediately(); - /** restart the task with the original parameters, Enable is not restored */ - void restart(); - /** enable the task */ - void enable(); - /**disable the task */ - void disable(); - /** return true if task is enabled */ - bool isEnabled(); - /** assign a new callback */ - void setCallback(const TaskCallback &); - void setCallback(const VoidCallback &); - /** give the task a new name */ - void setName(String); - /** function used by the schedule to run this task, shouldn't be called by user */ - void runIt(); - /** display stuff */ - void showInit(); - /** return string containing name of task */ - String getName(); - /** return the iteration count, that is the number of iterations that the task has been run */ - unsigned long getIterationCount(); - /** function to set a new interval */ - void setInterval(unsigned long newInterval); - /** function to set a new iterations value */ - void setIterations(unsigned long newIterations); - /** function to set the run immediately flag */ - void setImmediately(bool); - /** function that displays task info */ - String showTaskInfo(); - /** return the task interval */ - unsigned long getInterval(void); - /** return the run immediately flag */ - bool getRunImmediately(void); - /** return the last start time flag */ - unsigned long getLastStartTime(void); - /** return a string with a formatted time */ - String formatMS(unsigned long milliseconds); + SafePtr getSafePtr(); + + // ... (other method declarations) + +private: + template + void initializeTask(T interval, bool enabled, int iterations, const char* name, bool runImmediately); + + TaskCallback mProcWithTask; /**< The task's callback function */ + long mInterval; /**< The task's interval in milliseconds */ + bool mEnabled; /**< Whether the task is currently enabled */ + unsigned long mIterations; /**< Number of iterations for this task */ + String mName; /**< The name of this task */ + bool mRunImmediately; /**< Whether to run immediately when enabled */ + unsigned long mIterationCount; /**< Current iteration count */ + bool doShow; /**< Whether to show debug information */ + unsigned long mLastStartTime; /**< Last time the task was started */ + savedInitial mOrig; /**< Original state of the task */ + double passedInterval; /**< Interval passed to constructor */ + +public: + // ... (other public method declarations) }; + /** -@code -Task* t = new Task(turnLedOn, 1000,true,20,"OnOff",true); -Task t1(turnLedOn, 100,false,20,"On1",false); -Task t2(turnLedOn, 2.0,false,20,"On2",false); - -Output as generated by scheduler.displayStatus(true): - -450 Task On2, Enabled? 0, Diff 00:15.735, Interval 00:02.000, RI 0 -450 Task On1, Enabled? 0, Diff 00:15.735, Interval 00:00.100, RI 0 -450 Task On, Enabled? 1, Diff 00:01.721, Interval 00:01.000, RI 0 -@endcode -*/ - -class Sched -{ - public: - /** return the number of tasks in the run queue */ - unsigned long getSize(); - /** function to display the status of the tasks -``` -Sample output: - Task On2, Enabled? 0, Diff 59:40.731, Interval 00:02.000, RI 0 - Task On1, Enabled? 0, Diff 59:40.731, Interval 00:00.100, RI 0 - Task On, Enabled? 0, Diff 59:19.710, Interval 00:01.000, RI 0 -Source: - String str = scheduler.displayStatus(true); - Serial.print(str); -``` - * */ - String displayStatus(int num,String taskName="",bool raw=false); - /** default constructor */ - Sched(); - /** used to start the scheduling. A call to begin will also enable the scheduler. -``` -Sched scheduler; - scheduler.begin(); -``` - */ - void begin(); - /** add a task to the run queue */ -/** -``` -Example: - -Task* t = new Task(turnLedOn, 1000,true,20,"OnOff",true); -Task t1(dummy, 100, false, 20, "On1", * false); -Task t2(dummy, 2.0, false, 20, "On2", * false); - - scheduler.addTask(t); - scheduler.addTask(&t1); - scheduler.addTask(&t2); -``` -*/ - void addTask(SafePtr task); - /** enable the scheduler */ - void enable(); - /** disable the scheduler */ - void disable(); - /** return true if the scheduler is enabled */ - int isEnabled(); - /** returns a list of the tasks */ - //const std::list& getTasks() const; -// const SimpleList& getTasks() const; - const SimpleList>& getTasks() const; - /** called perodically to check if a task should be scheduled */ - void run(); - - private: - //SimpleList tTasks; - SimpleList> tTasks; - int mSchedEnabled; + * @brief Scheduler for managing multiple tasks. + */ +class Sched { +public: + /** + * @brief Get the number of tasks in the run queue. + * @return unsigned long The number of tasks + */ + unsigned long getSize(); + + /** + * @brief Display the status of tasks. + * @param num Number of tasks to display (0 for all enabled tasks) + * @param taskName Name of a specific task to display (if empty, displays based on num) + * @param raw Whether to display raw interval values + * @return String A string containing the status information + */ + String displayStatus(int num, String taskName="", bool raw=false); + + /** + * @brief Default constructor. + */ + Sched(); + + /** + * @brief Start the scheduling. + * + * This method must be called to enable the scheduler. + */ + void begin(); + + /** + * @brief Add a task to the run queue. + * @param task SafePtr to the Task to be added + */ + void addTask(SafePtr task); + + /** + * @brief Enable the scheduler. + */ + void enable(); + + /** + * @brief Disable the scheduler. + */ + void disable(); + + /** + * @brief Check if the scheduler is enabled. + * @return int 1 if enabled, 0 if disabled + */ + int isEnabled(); + + /** + * @brief Get a reference to the list of tasks. + * @return const SimpleList>& Reference to the list of tasks + */ + const SimpleList>& getTasks() const; + + /** + * @brief Run the scheduler. + * + * This method should be called periodically to check and run scheduled tasks. + */ + void run(); + +private: + SimpleList> tTasks; /**< List of tasks managed by this scheduler */ + int mSchedEnabled; /**< Whether the scheduler is currently enabled */ }; -///home/jwl/sketchbook/libraries/TaskSched/TaskSched.h 127 Task Rand_4720, Diff 0:09:054, Interval 0:04:720, RI 0 - /* @param func Function to be called. - * @param interval Time between calls to func in milliseconds. - * If intval is passed as a floating point number, e. g. 4.5 then it is treated as if it were a number of seconds otherwise the interval is treated as if it were a number of millisconds - * @param enabled Flag to be set if the task should start in an enabled state. - * @param iterations Number of iterations the task will be run. Set to zero for infinited iterations. - * @param name A String value of a name of the task. - * @param runImmediately A boolean flag that directs the scheduler to run the callback immediately rather than wait for the interval to expire. False says to wait for the interval to run the task. -*/ -#endif +#include "TaskSched.tpp" + +#endif // TASKSCHED_H diff --git a/TaskSched.tpp b/TaskSched.tpp index 3012dc7..68cbd73 100644 --- a/TaskSched.tpp +++ b/TaskSched.tpp @@ -1,6 +1,19 @@ #ifndef TASKSCHED_TPP #define TASKSCHED_TPP +/** + * @brief Initialize a task with the given parameters. + * + * This function handles the initialization of a task, including the conversion + * of the interval to milliseconds if it's a floating-point value. + * + * @tparam T The type of the interval parameter (integral or floating-point) + * @param interval The time between task executions + * @param enabled Whether the task should start enabled + * @param iterations The number of times to run the task (0 for infinite) + * @param name The name of the task + * @param runImmediately Whether to run the task immediately upon enabling + */ template void Task::initializeTask(T interval, bool enabled, int iterations, const char* name, bool runImmediately) { if constexpr (std::is_floating_point::value) { @@ -12,13 +25,11 @@ void Task::initializeTask(T interval, bool enabled, int iterations, const char* mIterations = iterations; mName = name; mRunImmediately = runImmediately; - mOrig.mEnabled=enabled; - mOrig.mInterval=mInterval; - mOrig.mIterations=iterations; - mOrig.mRunImmediately=runImmediately; - mLastStartTime=millis(); - - // ... other initializations ... + mOrig.mEnabled = enabled; + mOrig.mInterval = mInterval; + mOrig.mIterations = iterations; + mOrig.mRunImmediately = runImmediately; + mLastStartTime = millis(); #ifdef DEBUG Serial.print("Interval set to: "); @@ -26,4 +37,5 @@ void Task::initializeTask(T interval, bool enabled, int iterations, const char* Serial.println(" ms"); #endif } + #endif // TASKSCHED_TPP diff --git a/examples/SkedBlink1/SkedBlink1.ino b/examples/SkedBlink1/SkedBlink1.ino index 6dbd8a5..7f333ca 100644 --- a/examples/SkedBlink1/SkedBlink1.ino +++ b/examples/SkedBlink1/SkedBlink1.ino @@ -16,7 +16,7 @@ //int ledPin = LED_BUILTIN; int ledPin = 13; // this worked for my ttgo esp32 -void turnLedOn(); +void turnLedOn(Task*); void turnLedOff(Task*); Sched scheduler; @@ -28,7 +28,7 @@ SafePtr t3; // Task* t1 = new Task(turnLedOn, 2000, true, 20, "OnTask", true); // Task* t2 = new Task(turnLedOff, 1000, true, 20, "OffTask",false); -void turnLedOn() { +void turnLedOn(Task *tsk) { digitalWrite(ledPin, HIGH); Serial.print("T1 interval ="); Serial.println(t1->getInterval()); @@ -39,6 +39,18 @@ void turnLedOn() { Serial.println("Turn on"); } +void turnLedOnx() { + Serial.print("T1 interval ="); + Serial.println(t1->getInterval()); + Serial.print("T2 interval ="); + Serial.println(t2->getInterval()); + Serial.print("T3 interval ="); + Serial.println(t3->getInterval()); + Serial.println("Turn on"); +} + +void turnLed(Task *tsk) { +} void turnLedOff(Task *tsk) { digitalWrite(ledPin, LOW); t2->setInterval(2000); @@ -55,20 +67,23 @@ void setup() { ledPin = 16; // this worked for my Serial.begin(115200); pinMode(ledPin, OUTPUT); - t3 = SafePtr(new Task(turnLedOn, 2000L, true, 20, "OnTask", true)); + t3 = SafePtr(new Task(turnLed, 5.0, true, 20, "OnTask", true)); t1 = SafePtr(new Task(turnLedOn, 2000L, true, 20, "OnTask", true)); t2 = SafePtr(new Task(turnLedOff, 1000L, true, 20, "OffTask", false)); - delay(500); - Serial.println("Starting"); -turnLedOn() ; - + scheduler.addTask(t3); scheduler.addTask(t1); scheduler.addTask(t2); -turnLedOn() ; + Serial.println("Starting"); + String str = scheduler.displayStatus(true); + delay(500); + Serial.print(str); +turnLedOnx( ) ; + +turnLedOnx() ; scheduler.begin(); -turnLedOn() ; - String str = scheduler.displayStatus(true); +turnLedOnx() ; + str = scheduler.displayStatus(true); Serial.print(str); start=millis();