РЕЛЕЙНЫЙ РЕГУЛЯТОР НА ARDUINO

Это библиотека не для модулей реле (им не нужны библиотеки), это библиотека для релейного регулятора, т.е. реализация релейного закона регулирования с гистерезисом и обратной связью по скорости изменения величины через коэффициент усиления. Что позволяет делать релейный регулятор:

  • Управлять какой-то величиной, включая и выключая орган управления (температура – обогреватель или холодильник, влажность – увлажнитель, и так далее)
  • Гистерезис – “окно” вокруг установленного значения, чтобы уменьшить количество включений/выключений реле (управляющего устройства)
  • Обратная связь (ОС) по изменению – в библиотеку встроено автоматическое вычисление производной измеряемой величины. Подобрав коэффициент усиления ОС можно добиться максимальной стабильности и точности удержания заданной величины: обратная связь по изменению позволяет отключать управляющее устройство до перехода через заданную величину снизу, и заранее включать при приближении к ней сверху

БИБЛИОТЕКА GYVERRELAY

Библиотека классического релейного регулятора для Arduino

  • Обратная связь по скорости изменения величины
  • Настройка гистерезиса, коэффициента усиления ОС, направления регулирования
  • Возвращает результат по встроенному таймеру или в ручном режиме

Поддерживаемые платформы: все Arduino (используются стандартные Wiring-функции)

ДОКУМЕНТАЦИЯ


Инициализация

Можно создать объект с указанием направления регулирования

GyverRelay regulator(REVERSE);

Можно просто

GyverRelay regulator;

Настройка

Основные параметры регулятора можно читать и изменять напрямую как члены класса:

  • input – входная величина, например температура
  • setpoint – установка (к чему регулятор будет стремиться привести входную величину)
  • output – выход (0 или 1) для управления реле (например через digitalWrite()). Менять его не нужно, этим занимается библиотека!

Настроечные параметры:

  • hysteresis – ширина окна (петли) гистерезиса. Гистерезис уменьшает количество переключений реле, но дестабилизирует систему.
  • k – коэффициент обратной связи по скорости (по первой производной), подбирается вручную (0.01 ~ 100). При нулевом значении ОС отключается. ОС по скорости изменения позволяет стабилизировать систему, см. картинку в начале статьи.
  • dT – время итерации для режима работы по встроенному таймеру.
  • setDirection(dir) – установить направление работы регулятора: NORMAL – включаем нагрузку при переходе через значение снизу (пример: охлаждение), REVERSE – включаем нагрузку при переходе через значение сверху (пример: нагрев).

Управление

Библиотека имеет три функции для расчёта состояния реле, все функции возвращают состояние 0 или 1, а также изменяют состояние output, которое можно использовать в коде для чтения:

  • compute(dt) – моментальный расчёт. Принимает dt в секундах для режима с ОС. Можно не передавать dt, тогда ОС не будет работать
  • getResult() – моментальный расчёт. Встроенный таймер для режима с ОС
  • getResultTimer() – расчёт по встроенному таймеру
GyverRelay(boolean direction = REVERSE);
// NORMAL - включаем нагрузку при переходе через значение снизу (пример: охлаждение)
// REVERSE - включаем нагрузку при переходе через значение сверху (пример: нагрев)
	
// расчёт возвращает состояние для управляющего устройства (реле, транзистор) (1 вкл, 0 выкл)
boolean compute(float dt = 0);    // моментальный расчёт. Принимает dt в секундах для режима с ОС
boolean getResult();              // моментальный расчёт. Встроенный таймер для режима с ОС
boolean getResultTimer();         // расчёт по встроенному таймеру

void setDirection(boolean dir);	  // направление регулирования (NORMAL, REVERSE)
	
float input = 0;                  // сигнал с датчика (например температура, которую мы регулируем)
float setpoint = 0;               // заданная величина, которую должен поддерживать регулятор (температура)
boolean output = 0;               // выход регулятора (0 или 1)
	
float hysteresis = 0;             // ширина окна гистерезиса
float k = 0;                      // коэффициент усиления по скорости (по умолч. 0)	
int16_t dT = 1000;                // время итерации, мс (по умолч. секунда)

ПРИМЕРЫ


/*
Пример работы релейного регулятора в автоматическом режиме по встроенному таймеру
Давайте представим, что на 3 пине у нас спираль нагрева, подключенная через реле
И есть какой то абстрактный датчик температуры, на который влияет спираль
*/
#include "GyverRelay.h"
// установка, гистерезис, направление регулирования
GyverRelay regulator(REVERSE);
// либо GyverRelay regulator(); без указания направления (будет REVERSE)
void setup() {
pinMode(3, OUTPUT);         // пин реле
regulator.setpoint = 40;    // установка (ставим на 40 градусов)
regulator.hysteresis = 5;   // ширина гистерезиса
regulator.k = 0.5;          // коэффициент обратной связи (подбирается по факту)
//regulator.dT = 500;       // установить время итерации для getResultTimer
}
// вариант с delay
void loop() {
int temp;                 // например читаем с датчика температуру
regulator.input = temp;   // сообщаем регулятору текущую температуру
// getResult возвращает значение для управляющего устройства
digitalWrite(3, regulator.getResult());  // отправляем на реле (ОС работает по своему таймеру)
delay(100);
}
/*
// вариант со встроенным таймером
void loop() {
int temp;                 // например читаем с датчика температуру
regulator.input = temp;   // сообщаем регулятору текущую температуру
// getResult возвращает значение для управляющего устройства
digitalWrite(3, regulator.getResultTimer());  // отправляем на реле
// также можно получить значение с выхода регулятора
// regulator
}
*/
/*
// вариант со своим таймером
void loop() {
static uint32_t myTimer = 0;
if (millis() - myTimer > 2000) {    // свой таймер на миллис, 2 секунды
myTimer = millis();
int temp;                 // например читаем с датчика температуру
regulator.input = temp;   // сообщаем регулятору текущую температуру
// getResult возвращает значение для управляющего устройства
digitalWrite(3, regulator.compute(2));  // отправляем на реле. Время передаём вручную, у нас 2 секунды
}
}
*/
/*
Симуляция работы реле. Обнули k и увидишь, как регулятор
перестанет справляться с инерционной системой
*/
#include "GyverRelay.h"
GyverRelay regulator(REVERSE);
void setup() {
Serial.begin(9600);
regulator.setpoint = 40;
regulator.hysteresis = 5;
regulator.k = 0.5;
}
boolean state = 0;
float value = 0;
void loop() {
process();
regulator.input = value;
state = regulator.getResult();
Serial.print(value);
Serial.print(' ');
Serial.print(regulator.setpoint - 5 / 2);
Serial.print(' ');
Serial.print(regulator.setpoint + 5 / 2);
Serial.print(' ');
Serial.println(regulator.setpoint);
delay(100);
}
void process() {
static float coef = 0;
coef += state ? 0.3 : -0.6;
if (coef > 2.0) coef = 2.0;
if (coef < -3.0) coef = -3;
value += coef;
}

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

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