ВНИМАНИЕ! На форуме началось голосование в конкурсе - астрофотография месяца АПРЕЛЬ!
0 Пользователей и 1 Гость просматривают эту тему.
Попробуем. Если что, новичковую тему можно отдельно отрезать.
volatile bool pin2trigger, pin3trigger;void interruptCallback2() { pin2trigger = true;}void interruptCallback3() { pin3trigger = true;}void setup() { attachInterrupt(2, interruptCallback2, RISING); attachInterrupt(3, interruptCallback3, RISING);}void loop() { if (pin2trigger) { pin2trigger= false; // do something with interrupt } if (pin3trigger) { pin3trigger = false; // do something }}
TASK SomeTask(int *state){ int a = 0; print(a++); YIELD; //! print(a++);}
TASK SomeTask(int *state){ { int a = 1; print(a); } YIELD; //! { int b = 2; print(b); } YIELD; print("Finished");}
struct TaskData {TASK_STATE;int a; int b;};TASK(SomeTask){ INIT_TASK(TaskData); for (data->a = 0; data->a < 100; ++data->a) { print(data->a); YIELD; } TASK_END;}
int main(){ struct Scheduler scheduler; struct TaskData data = {0, 0}; AddTask(&scheduler, SomeTask, &data); RunTasks(&scheduler);}
#define TASK(CALLBACK) int CALLBACK(int* _state, void* _data)#define TASK_STATE int _state;#define INIT_TASK(DATA) struct DATA *data = (struct DATA*)_data;
struct Task{ int _state; virtual bool Step() = 0;}class SomeTask : private Task{ int a; virtual bool Step() override { for (a = 0; a < 100; ++a) { print(a); YIELD; } }public: SomeTask() : a(){}}
int main(){ Scheduler scheduler; SomeTask task; scheduler << task; scheduler.Run();}
class SomeTask : private TaskBase{ virtual bool TaskFunc() override { switch (_state) { case 0: // step 1; _state = __LINE__; return false; case __LINE__: // step 2 _state = __LINE__; return false; case __LINE__: // step 3 _state = __LINE__; return false; case __LINE__: // step 4 default: _state = -1; return true; } }}
DECLARE_TASK(SomeTask) CAN_SLEEPint count;bool IsPressed() { return digitalRead(BUTTON_PIN); }BEGIN_TASK count = 0; pinMode(BUTTON_PIN, INPUT); ALWAYS { YIELD_WHILE(!IsPressed()); Serial.println(++count); YIELD_WHILE(IsPressed()); SLEEP(500); }END_TASK
#define DECLARE_TASK(T) class T : private TaskBase {#define BEGIN_TASK private: virtual bool Step() override { \ switch (_state) { \ case 0:#define YIELD _state = __LINE__; return false; case __LINE__:#define ALWAYS for(;;)#define YIELD_WHILE(cond) case __LINE__: if (cond) {_state = __LINE__; return false;}#define END_TASK default: _state = -1; return true; }}}; // завершить switch, метод Step и класс
#define CAN_SLEEP unsigned long _sleep;#define SLEEP(time) _sleep = millis() + (time); case __LINE__: if (millis() < _sleep) return false;
Планировщик предназначен для планирования выполнения задач. Рассмотрим самый простой вариант планирования - циклическое. Планировщик по очереди выбирает задачи и передаёт им управление. Можно рассмотреть два варианта организации последовательности задач: фиксированный массив и двусвязный динамический список.#ifndef MAX_TASKS#define MAX_TASKS 16#endif class Scheduler{ TaskBase* tasks[MAX_TASKS]; byte usedTasks; void AddTask(TaskBase* task) { if (usedTasks < MAX_TASKS) { tasks[usedTasks++] = task; } } void RemoveTask(TaskBase* task) { for (byte i = 0; i < usedTasks; ++i) { if (task == tasks[i]) // найдена задача на удаление { RemoveTask(i); break; } } } void RemoveTask(byte taskIndex) { for (int i = taskIndex + 1; i < usedTasks; ++i) { tasks[i - 1] = task[i]; } --usedTasks; }public: Scheduler() : usedTasks() {} Scheduler& operator<<(TaskBase* task) { AddTask(task); return *this; } void Run() { byte activeTask = 0; while (usedTasks) { if (tasks[activeTask].Step()) { RemoveTask(activeTask); } else { ++activeTask; } if (activeTask >= usedTasks) { activeTask = 0; } } }}
template<typename T>T& CreateInstance(){ static T obj; return obj;}
template<typename T, int N = 0>T& CreateInstance(){ static T obj; return obj;}
template<typename T, int N, typename ...Args>T& CreateInstance(Args... args){ static T obj(args...); return obj;}
template<typename T, int N = 0>struct Activator{ template<typename ...Args> static T& CreateInstance(Args... args) { static T obj(args...); return obj; }}MyClass& m = Activator<MyClass>::CreateInstance(1, "Hello", 3.14f);
template<typename T, int N = 0>struct Activator{ template<typename ...Args> static T& CreateInstance(Args... args) { static byte obj[sizeof(T)]; static byte initialized; if (initialized == 0) { initialized = 1; return *(new (obj)T(args...)); } return *(T*)obj; }}MyClass& m = Activator<MyClass>::CreateInstance(1, "Hello", 3.14f);
inline void* operator new (unsigned size, void* ptr) noexcept{ return ptr;}
#include "Multitasking/Multitasking.h"DECLARE_TASK(BlinkerTask) CAN_SLEEP byte pin; int delay; bool state;public: BlinkerTask(byte pin, int period) : pin(pin), state(), delay(period/2) {}BEGIN_TASK pinMode(pin, OUTPUT); FOREVER { digitalWrite(pin, state = !state); SLEEP(delay); }END_TASKvoid setup(){ (Instance<Scheduler<4>>::CreateNoGuard() << Instance<BlinkerTask, 1>::CreateNoGuard(13, 1000) << Instance<BlinkerTask, 2>::CreateNoGuard(12, 2000) << Instance<BlinkerTask, 3>::CreateNoGuard(11, 4000) ).Run();}void loop(){}
#include "U8glib.h"U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_DEV_0 | U8G_I2C_OPT_FAST);int my;String ser;void setup(void) { Serial.begin(9600);}void draw(void) { u8g.setFont(u8g_font_unifont); u8g.setPrintPos(0, 20); u8g.print("FFF"); u8g.print(ser);}void loop(void) { if (Serial.available()) { ser = Serial.readString(); my = ser.toInt(); u8g.firstPage(); do { draw(); } while ( u8g.nextPage() ); }}