СИСТЕМА РЕАЛЬНОГО ВРЕМЕНИ ДЛЯ 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);
}

ОСТАЛЬНЫЕ БИБЛИОТЕКИ

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