Посоветуйте как лучше реализовать мертвую зону на утиловском для регулирования температуры задвижкой.
1.
pid();
if abs(SP-PV) < deadband then
pid.Y := 0; // чтобы задвижка стояла на месте
end_if
2.
pid();
if abs(SP-PV) < deadband then
SP:=PV;
end_if
3.
pid();
if abs(SP-PV) < deadband then
SP:=PV;
pid.Y := 0;
end_if
Можете предложить свой вариант.
Ни один из этих вариантов у вас работать не будет. В первом варианте вы не сможете присвоить выходу значение. Во втором варианте у вас уставка будет постоянно "следовать" за переменной, как только переменная попадет в зону нечувствительности. Только если PV изменится резко, чтобы выскочить из зоны, только тогда ПИД заработает.
Ну а третий вариант это сумма двух первых.
if Pid.Pv>=Pid.Sv-Dead_band OR Pid.Pv<=Pid.Sv+Dead_band THEN
Pid.Pv:=Pid.Sv;
end_if;
...
...
...
Pid();
Т.е вариант№2 товарища стартера, именно этого не хватает в "заводской" комплектации утильного ПИД регулятора, проверено десятками стабильно работающих реализаций. Тут еще кто-то пургу мел про Tn="многим тысячам"...,так вот то именно пурга(или бред). Зырьте формулу,для этого даже код открывать не надо.
Как то так...
З.Ы Вы тут такую пургу метете... Господа!Пришлите мне того-же, что вы курите.
Последний раз редактировалось Sergey666; 26.11.2018 в 21:49.
А вы принципиально не видите разницы между своим вариантом и вариантом dzukp? Вы оперируете в отличии от него с входными переменными ПИД, а он с какими то абстрактными SP и PV, при этом используя в коде вполне конкретный pid.Y.
Так вот тот конкретный кусок кода работать не будет, так как переменная SP будет изменяться вслед за PV, как только PV попадет в мертвую зону.
Избежать этого можно только если где-то ранее в коде будет строка вида: SP:=A;
В явном виде в варианте dzukp этого нет и реализовав данный вариант "как есть" можно сильно удивится, что переменная так ни когда из мертвой зоны и не выйдет (без резкого скачка значения переменной)
Да и ваш вариант работать не будет. В вашем случае в условии нужен AND, а не OR.
Я бы наверно реализовал это как-то так:
Поясню почему PID.SP:=SP+DB.Код:IF PV>(SP+DB) THEN PID.SP:=(SP+DB); ELSIF PV<(SP-DB) THEN PID.SP:=(SP-DB); ELSE PID.SP:=PV; END_IF;
Это позволит регулятору при выходе переменной из мертвой зоны более плавно начать регулирование. В противном же случае мы получим ошибку рассогласования >= величине мертвой зоны, что может привести к резкому скачкообразному изменению выхода ПИД из-за больших значений пропорциональной и дифференциальной составляющих регулятора.
Хотел бы внести своё предложение в дискуссию: добавить задержку включения для того, чтобы "пролетая" уставку переменная не "цеплялась" за границы "мертвой зоны", и ввести "мертвую зону" в установившемся режиме.
Например:
ton1(IN := ABS(SP - PV) < DB, PT := <время выхода на уставку>);
В варианте SBeaR меня тоже смущает, то что идеальный регулятор на уставку выходить не будет, будет либо SP+DB, либо SP-DB.
Наверное как-то так нужно сделать.
Код:ton1(IN := ABS(SP - PV) < DB, PT := <время выхода на уставку>); IF ton1.Q AND PV>(SP+DB) THEN PID.SP:=(SP+DB); ELSIF ton1.Q AND PV<(SP-DB) THEN PID.SP:=(SP-DB); ELSE PID.SP:=PV; END_IF;