View Categories

Релейный регулятор

Релейное управление – самое простое из возможных, ведь у нас есть только два состояния – вкл и выкл. В этом уроке рассмотрим алгоритмы, которые сделают регулирование более плавным, позволят сохранить "здоровье" реле и повысят точность управления. Начнём с самого простого и очевидного - порог переключения.

Порог переключения #

Здесь всё просто: если текущее значение (value) меньше заданного (setpoint) - включить реле, если больше - выключить:

// "нагрев"
if (value < setpoint) relayOn();
else relayOff();

Это в случае прямого управления (нагреватель). Для обратного (холодильник, вентилятор) логика будет обратная, т.е.

// "охлаждение"
if (value > setpoint) relayOn();
else relayOff();

Условный пример для Arduino, нагрев до 50 градусов:

void loop() {
    float temp = 0; // получили с датчика

    if (temp < 50.0) digitalWrite(relayPin, HIGH);
    else digitalWrite(relayPin, LOW);

    // или просто
    // digitalWrite(relayPin, temp < 50.0);
}

Дребезг #

Если вызывать данный код со скоростью loop, как в примере - получим жуткий дребезг в момент включения и выключения реле, так как шумы измерений будут постоянно менять результат условия вокруг порогового значения:

Зелёный график - как раз состояние реле. Ужас! Значения "температуры" надо фильтровать, это сильно увеличит стабильность системы. Фильтры мы подробно разбирали в уроке про фильтры.

Даже если входной сигнал отфильтрован и меняется плавно, частый опрос приведёт к частым переключениям реле около порогового значения, особенно если система "быстрая". Такая система будет стараться удерживать температуру как можно точнее к заданной, даже если она колеблется в диапазоне +-0.001 градус - недостижимая и избыточная точность, такую даже не получится измерить термометром:

Если реле обычное электромагнитное, то оно имеет ресурс на количество переключений. Такой регулятор очень быстро износит реле.

Период опроса #

Самым простым шагом к созданию более стабильного релейного регулятора является период работы - его можно реализовать как задержкой, так и таймером на миллис. Период 1 секунда:

void loop() {
    float temp = 0;  // получили с датчика
    digitalWrite(relayPin, temp < 50.0);
    delay(1000);
}

Ситуация в корне изменится: реле станет принудительно переключаться реже, соответственно ухудшится точность регулирования и появятся более видимые колебания, но реле будет меньше щёлкать и проживёт дольше:

Пример для Arduino:

uint32_t tmr;

void loop() {
    if (millis() - tmr >= 1000) {
        tmr = millis();
        float temp = 0;  // получили с датчика
        digitalWrite(relayPin, temp < 50.0);
    }
}

Гистерезис #

Второй способ – гистерезис, тоже позволяет уменьшить количество переключений, но без периода опроса - это повышает скорость реакции системы на изменения, сохранив при этом хорошую устойчивость к помехам. Гистерезис имеет два порога переключения, которые разделяют область значения на 3 зоны:

  • Ниже (порог - гистерезис)
  • Между (порог - гистерезис, порог + гистерезис)
  • Выше (порог + гистерезис)

Логика работы такова, что мы включаем ниже нижнего порога и выключаем выше верхнего. То есть образуется область, внутри которой система движется по инерции от последнего переключения и меняет состояние только при выходе из этой области. Понятное дело, что добавление гистерезиса сильно уменьшает не только количество переключений, но и точность - мы буквально задаём область, точность внутри которой нам безразлична (как и шумы измерения):

В коде гистерезис можно реализовать так:

if (value < setpoint - hyster) relayOn();
else if (value > setpoint + hyster) relayOff();

Отлично! Теперь нам не страшны шумы и износ реле, система реагирует быстро, но мы фактически "раскачали" систему, заставляя её включаться чуть ниже заданной температуры, а выключаться - чуть выше. Пример для Arduino:

// порог 50, гистерезис 2
void loop() {
    float temp = 0;  // получили с датчика
    if (temp < 50 - 2) digitalWrite(relayPin, HIGH);
    else if (temp > 50 + 2) digitalWrite(relayPin, LOW);
}

Алгоритм с опережением #

Для увеличения стабильности системы с гистерезисом можно ввести предсказывание значения на основе скорости его изменения. Это позволит удерживать значение более точно и лучше реагировать на внезапные изменения, а также использовать релейный регулятор для управления более сложными и быстрыми процессами. Например, подобный алгоритм используется в космических аппаратах: задача такой системы - включать двигатели ориентации максимально редко и эффективно, избегая перерегулирования, которое неизбежно при обычном гистерезисе. Т.е. такой регулятор выключит реле заранее и регулируемое значение уже по инерции дойдёт до заданного, в идеале не превышая его.

Реализуется это довольно просто - в алгоритме с гистерезисом нужно сравнивать не текущее значение, а предсказанное, которое получается как текущее + скорость изменения значения, умноженная на некоторый коэффициент. Этот коэффициент и будет задавать вес предсказания в сравнении - значение подбирается экспериментально от 0, максимальное зависит от конкретной системы:

// dt - время между измерениями в секундах
rate = (value - prev) / dt;     // производная (скорость)
prev = value;                   // предыдущее значение
signal = value + rate * k;      // предсказанное значение

// обычный гистерезис
if (signal < setpoint - hyster) relayOn();
else if (signal > setpoint + hyster) relayOff();

Пример для Arduino:

const int relayPin = 2;  // пин реле
const int period = 100;  // период опроса в мс

float k = 0.5;        // коэффициент
float setpoint = 30;  // уставка
float hyster = 2;     // гистерезис (в одну сторону)
float prev = 0;       // пред. значение

void loop() {
    float temp = 0;  // прочитать температуру

    float rate = (temp - prev) / (period / 1000.0);  // скорость
    prev = temp;
    float signal = temp + rate * k;  // предсказанное значение
    if (signal < setpoint - hyster) digitalWrite(relayPin, HIGH);
    else if (signal > setpoint + hyster) digitalWrite(relayPin, LOW);

    delay(period);
}

При правильной настройке гистерезиса и коэффициента данный алгоритм работает гораздо лучше, чем просто порог по таймеру. Особенно хорошо это становится заметно при наличии непостоянного внешнего воздействия: розовая линия на графиках ниже - условная "внешняя температура", которая влияет на процесс нагрева. Регулятор с моделью опережения (второй график) удерживает температуру гораздо лучше, чем просто порог по таймеру (первый график), имея +- такое же количество переключений:

Видео #

Дополнительно #

Дополнительный контент доступен владельцам набора GyverKIT и по подписке, подробнее читай здесь. Блок содержит:

  • Интерактивный график

Полезные страницы #

5 1 голос
Рейтинг статьи
Подписаться
Уведомить о
guest

0 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх