СИСТЕМА РЕАЛЬНОГО ВРЕМЕНИ ДЛЯ 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. В комментарии на страницах я заглядываю очень редко, на форум – ещё реже.

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

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