СИСТЕМА РЕАЛЬНОГО ВРЕМЕНИ ДЛЯ ARDUINO
RTOS – (Real Time Operating System) система реального времени – концепция построения программы, в которой создаются задачи, настраивается период их вызова, и всё! Между вызовами задач микроконтроллер спит и потребляет минимум энергии.
БИБЛИОТЕКА GYVERRTOS
Система реального времени для Arduino: максимальное энергосбережение и мультизадачность
- Для функционирования системы нужна библиотека Low-Power, скачать можно вот тут
- Во время сна функция millis() не работает, вместо неё используется переменная mainTimer, которая автоматически увеличивается при каждом пробуждении на время сна (SLEEP_PERIOD) В ХОЛОСТОМ РЕЖИМЕ
- Выполнение функций занимает время, поэтому ЕСЛИ ВЫПОЛНЯЕТСЯ ЗАДАЧА, время выполнения тоже автоматически суммируется в mainTimer
- МЫ создаём несколько функций с разным периодом выполнения (задачи)
- Настраиваем период пробуждения системы (минимально 15 мс) Далее всё автоматически:
- Рассчитывается время до выполнения самой “ближней” задачи
- Система периодически просыпается и считает таймеры
- При наступлении времени выполнения ближайшей задачи, она выполняется. После этого снова выполняется расчёт времени до новой ближайшей задачи
Как итог: Ардуино спит (в зависимости от периодов) 99.999% времени, просыпаясь только для проверки флага и расчёта таймера СМОТРИ ПРИМЕР
Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции)
ПРИМЕРЫ
/* Пример выполнения нескольких задач с уходом в сон между задачами Что умеет GyverRTOS, особенности: - Во время сна функция millis() не работает, вместо неё используется переменная mainTimer, которая автоматически увеличивается при каждом пробуждении на время сна (SLEEP_PERIOD) В ХОЛОСТОМ РЕЖИМЕ - Выполнение функций занимает время, поэтому ЕСЛИ ВЫПОЛНЯЕТСЯ ЗАДАЧА, время выполнения тоже автоматически суммируется в mainTimer - МЫ создаём несколько функций с разным периодом выполнения (задачи) - Настраиваем период пробуждения системы (минимально 15 мс) Далее всё автоматически: - Рассчитывается время до выполнения самой "ближней" задачи - Система периодически просыпается и считает таймеры - При наступлении времени выполнения ближайшей задачи, она выполняется. После этого снова выполняется расчёт времени до новой ближайшей задачи - Как итог: Ардуино спит (в зависимости от периодов) 99.999% времени, просыпаясь только для проверки флага и расчёта таймера */ #include "GyverRTOS.h" #include "LowPower.h" #define SLEEP_PERIOD SLEEP_15MS // период пробуждения (из списка ниже!) /* SLEEP_15MS - 15 ms sleep SLEEP_30MS - 30 ms sleep SLEEP_60MS - 60 ms sleep SLEEP_120MS - 120 ms sleep SLEEP_250MS - 250 ms sleep SLEEP_500MS - 500 ms sleep SLEEP_1S - 1 s sleep SLEEP_2S - 2 s sleep SLEEP_4S - 4 s sleep SLEEP_8S - 8 s sleep */ GRTOS myRTOS; // создаём систему Gtask task1, task2, task3; // создаём задачи uint32_t buf, mainTimer; // ВАЖНЫЕ переменные!!! (не трогать) void setup() { Serial.begin(115200); // подключаются фунцкии, ставится период их работы в миллисекундах task1.attachTask(action1, 5000); task2.attachTask(action2, 3000); task3.attachTask(action3, 1000); // ставится период работы системы согласно WDT (avr/sleep.h) myRTOS.setPeriod(SLEEP_PERIOD); // подключается список задач на выполнение myRTOS.attachList(myList); } // -------------- НАШИ ФУНКЦИИ --------------- void action1() { Serial.println("action1!"); } void action2() { Serial.println("action2!"); } void action3() { Serial.println("action3!"); } void myList() { // проверяются таймеры заданий, задания выполняются, // выполняется поиск самой "скорой" задачи и запоминание таймера task1.tick(&buf, &mainTimer); task2.tick(&buf, &mainTimer); task3.tick(&buf, &mainTimer); //delay(30); // задержка для вывода текста (имитация задачи) } // -------------- НАШИ ФУНКЦИИ --------------- void loop() { // проверка таймеров задач, выполнение задач, расчёт времён // время до самой ближней задачи хранится в buf myRTOS.check(&buf); // спим, библиотека LOW-POWER LowPower.powerDown(SLEEP_PERIOD, ADC_OFF, BOD_OFF); // проснулись, посчитали таймеры, разрешили выполнение задач // расчёт mainTimer ведётся с учётом сна и времени прохода loop! myRTOS.wake(&buf, &mainTimer); }
#include "GyverRTOS.h" #include "LowPower.h" #define SLEEP_PERIOD SLEEP_15MS /* SLEEP_15MS - 15 ms sleep SLEEP_30MS - 30 ms sleep SLEEP_60MS - 60 ms sleep SLEEP_120MS - 120 ms sleep SLEEP_250MS - 250 ms sleep SLEEP_500MS - 500 ms sleep SLEEP_1S - 1 s sleep SLEEP_2S - 2 s sleep SLEEP_4S - 4 s sleep SLEEP_8S - 8 s sleep */ Gtask task1, task2, task3; GRTOS myRTOS; uint32_t buf, mainTimer; void setup() { Serial.begin(115200); task1.attachTask(action1, 5000); task2.attachTask(action2, 3000); task3.attachTask(action3, 1000); myRTOS.setPeriod(SLEEP_PERIOD); myRTOS.attachList(myList); } void action1() { Serial.println("action1!"); } void action2() { Serial.println("action2!"); } void action3() { Serial.println("action3!"); } void myList() { task1.tick(&buf, &mainTimer); task2.tick(&buf, &mainTimer); task3.tick(&buf, &mainTimer); // задержка для вывода текста (имитация задачи) delay(30); } void loop() { myRTOS.tick(&buf); LowPower.powerDown(SLEEP_PERIOD, ADC_OFF, BOD_OFF); myRTOS.wake(&buf, &mainTimer); }
#include "GyverRTOS.h" #include "LowPower.h" // для более точной настройки режимов энергосбережения ковырять тут: // GyverRTOS.h, строка 89 #define SLEEP_PERIOD SLEEP_15MS /* SLEEP_15MS - 15 ms sleep SLEEP_30MS - 30 ms sleep SLEEP_60MS - 60 ms sleep SLEEP_120MS - 120 ms sleep SLEEP_250MS - 250 ms sleep SLEEP_500MS - 500 ms sleep SLEEP_1S - 1 s sleep SLEEP_2S - 2 s sleep SLEEP_4S - 4 s sleep SLEEP_8S - 8 s sleep */ Gtask task1, task2, task3; GRTOS myRTOS; uint32_t buf, mainTimer; void setup() { Serial.begin(115200); task1.attachTask(action1, 5000); task2.attachTask(action2, 3000); task3.attachTask(action3, 1000); myRTOS.setPeriod(SLEEP_PERIOD); myRTOS.attachList(myList); } void action1() { Serial.println("action1!"); } void action2() { Serial.println("action2!"); } void action3() { Serial.println("action3!"); } void myList() { task1.tick(&buf, &mainTimer); task2.tick(&buf, &mainTimer); task3.tick(&buf, &mainTimer); // задержка для вывода текста (имитация задачи) delay(30); } void loop() { myRTOS.tickAndSleep(&buf, &mainTimer, SLEEP_PERIOD); }
УСТАНОВКА БИБЛИОТЕКИ
Если вы не знаете, как установить библиотеку – читайте отдельный урок по работе с библиотеками!
БАГИ И ОШИБКИ
Если вы нашли баг или ошибку в исходнике или примерах, или у вас есть идеи по доработке библиотеки – пишите пожалуйста на почту alex@alexgyver.ru. В комментарии на страницах я заглядываю очень редко, на форум – ещё реже.
ОСТАЛЬНЫЕ БИБЛИОТЕКИ

У меня есть ещё очень много всего интересного! Смотрите полный список библиотек вот здесь.