Здравствуйте, разбираюсь с ПИД регулятором, нашел на просторах интернета простой код, который в принципе работает, за исключением одного, он не работает на упреждение, то есть получается что на терморегуляторе начинает снижаться мощность только когда температура достигла нужной в итоге идет заскок температуры, это происходит с любыми коэфициентами, возможно подправить код чтобы он работал правильно?
//ПИД РЕГУЛЯТОР
// (вход, установка, п, и, д, период в секундах, мин.выход, макс. выход)
float computePID(float input, float setpoint, float kp, float ki, float kd, float dt, int minOut, int maxOut) {
float err = setpoint - input;
static float integral = 0, prevErr = 0;
integral = constrain(integral + (float)err * dt * ki, minOut, maxOut);
float D = (err - prevErr) / dt;
prevErr = err;
return (float)constrain(err * kp + integral + D * kd, minOut, maxOut);
}
//Вызов раз в секунду
float computePID(30,40, 1, 0.2, 0.5, 1, 0, 255);
Вы имеете в виду стандартную библиотеку?
В данном коде я так понимаю не верно считается дифференциальная составляющая, но как ее изменить не могу понять, скорее всего нужно использовать массив показаний за какой-то промежуток времени, пока четкого понимания у меня к сожалению нет
Это общая трудность при регулировании по значению величины, получить более подходящее управление можно, включив в систему величину скорости изменения регулируемой величины. Тогда составляется линейная комбинация обеих величин и при правильном подборе коэффициентов, успех. Читайте учебники по системам регулирования.
не знаю о каком стандарте Вы говорите, но на “домашнем сайте” проекта Arduino описана готовая библиотека и спросил, чем она Вас не устроила, что Вы кинулись искать по всему интернету всякие надписи на заборах.
Диф. составляющая это просто разница входного сигнала к предыдущему, то есть скорость его изменения: Диф=Тек-Пред.
Довольно капризная и если её доля слишком велика приводит к мощным колебаниям на выходе. На чем-то тормозном лучше ее вообще не вводить зачастую, ну будет медленно по асимптоте подходить к заданному.
Значит есть подозрение, что оно работает так, просто Вы не понимаете как оно должно работать (я имею в виду, как должен работать этот метод регулирования)
Пид не является каким-то волшебным идеальным регулятором. Если хочешь уменьшить перескок, то задавай профиль прогрева, чтобы не было резких скачков точки установки, и чтобы система поспевала за этим профилем. Но неточности регулировки всё равно будут.
Допустим целевая температура:120°. ТЭН непрерывно включаешь до 100°(разгон), затем задействуешь регулятор. Технология настройки примерно такая- все коэф. выставляешь в ноль, D - немного увеличиваешь и смотришь на реакцию системы, запоминаешь, увеличиваешь еще немного, добиваясь состояния, максимально близкого к желаемому. Плоттер здесь - очень желателен. Когда ты поймешь как реагирует твоя система на дифференциацию, начинай понемногу добавлять коэф. P. Этим ты еще немного приблизишь состояние системы к идеальному. И напоследок, когда наиграешься с P, очень по малу добавляй I. После огромного количества попыток у тебя начнет появляться “чуйка” какой параметр, как влияет на процесс. В идеале, подобрав коэф. I ты выведешь систему в максимально приемлемый режим. Но процесс этот ппц какой не быстрый, потому, что универсального лекарства нет и каждая система индивидуальна по своим свойствам и значениям PID.
Разгон желателен для того, чтобы коэф. I не набирал слишком большого значения, которое в последствии придется очень долго гасить.
Коэффициенты ПИД зависят от постоянной времени системы. У систем с нагревом постоянные времени нагрева и охлаждения разные. Соответственно и идеальные коэффициенты на нагрев и охлаждение могут отличаться. На старом форуме была огромная лекция на тему ПИД регулятора и большое обсуждение. Там можно найти много ответов.
Почитал еще разные статьи, так же на этом сайте https://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/etyudy-dlya-pesochnitsy-teoriya-upravleniya-i-regulyatory
Посмотрел код, а так же эмулятор на сайте оригинале статьи, в итоге что я выложил код, что находится в статье, за одним исключением что в коде приведённом мною время между регулировкой задается вручную и по нему происходит расчет, в коде из статьи, а так же в коде библиотеки с arduino.com используется millis(), так вот я вижу что на графике все хорошо плавно достигается заданное значение (заранее снижается управляющий сигнал), как в приведенном скрине, но я не могу найти в коде, то что может обеспечить выделенный участок на скрине