Управление отоплением 0-10в / ПИД регулятор

Node-Red + готовые модули ПИД в нём.
Схема рабочая. Проверял у себя в прошлом году
когда делал систему подмеса твердотопливного котла
нагруженного на тепловой аккумулятор.

я только включаюсь в эту игру. тоже буду делиться своими наработками.

Мне так и не удалось установить Node-Red.
Поэтому нужен другой рабочий код.

Речь скорее всего шла про физическое подключение питания приводов 0-10V (24VAC).
А код как работал, так и работает, просто он раньше обслуживал лишь два клапана, а для трех одновременно надо было корректно подключать землю.
Если нет иного алгоритма, то можете взять мой на вооружение. Может не идеальный, но вполне боевой. Были мысли его усовершенствовать, но руки не доходят. Много работы.

Разберитесь со строчками 0-202 в действующем скрипте:
https://yadi.sk/d/ZdLUKcQJKlZGnw

Я для трех контуров вызываю через плавающий интервал времени функцию корректировки MOD от 0-10В. Время и величина корректировки зависят от величины изменения температуры за ед времени (сравнение идет с предыдущими сохраненными показателями темп). По мере приближения к уставке(выставленная температура в моих вирт контролах) коррекция идет плавнее, дабы не проскочить настроенную температуру. Мысли были дальше вычислять скорость изменения температуры, пересекать уставку вверх - вниз, постепенно уменьшая дельту изменения 0-10В (по принципу затухающего колебания волны)

1 лайк

Мало описания

Ну, извиняйте. Я же для себя писал и комментировал столько, сколько посчитал необходимым.

1 лайк

Кто-нибудь пробовал этот алгоритм?
Я на днях запустил, код работоспособный, но в полезности я пока сомневаюсь. Пришлось сделать виртуальное устройство для подбора коэффициентов ПИД регулятора. Начитался кучу методов подбора коэффициентов ПИД регулятора. Но пока не удается подобрать нужные коэффициенты и достичь стабильности в регулировании 0-10В. Или в коде есть ошибки или не подобрал нужные коэффициенты.
Никто не занимался подбором коэффициентов для отопления?

В чем заключается стабильность регулирования на мой взгляд?
Это после того как комнатная температура достигла заданной регулирование по 0-10В перестает меняться. На данный момент я достиг показаний когда это значение меняется на единицы. Но это плохо, так как шаговому двигателю от этого не очень хорошо, выйдет из строя раньше времени.

Может проблема в виртуальном устройстве. Как его создали?

defineVirtualDevice(“HOME_Temperature”, {
title: “Home temperature”,
cells: {
“kp1” : {
type : “range”,
value : 4,
min: 0,
max : 100,
},
“ki1” : {
type : “range”,
value : 1,
min: 0,
max : 1000,
},
“kd1” : {
type : “range”,
value : 1,
min: 0,
max : 1000,
},
“Set temp Hoz” : {
type : “range”,
value : 20,
min: 15,
max : 30,
},
“Room_temperature” : {
type : “range”,
value : 19,
min: 15,
max : 30,
},
“Upravlenie”: {
type : “range”,
value : 0,
min: 0,
max : 10000,
},
}
});

// Виртуальное устройство для теста
defineVirtualDevice(“DevTest”, {
title: “Test”,
cells: {
enabled: {
type: “range”,
value: 27,
max: 34,
min: 26
},
log: {
type: “text”,
value: false,
max: 100
},
kp1: {
type: “range”,
value: 2,
min: 0,
max: 100,

},
}

});
// Начало кода PID регулятора
var Pid = function(opts) { //Конструктор объектов
opts = opts || {};
this._target = opts.target //|| 0;
this._kp = opts.kp || 0;
this._ki = opts.ki || 0;
this._kd = opts.kd || 0;
this._outputMin = opts.outputMin || 0;
this._outputMax = opts.outputMax === undefined ? 1 : opts.outputMax;
this._lastTime = null;
this._intervalId = null;
};

Pid.prototype.clip = function(x, min, max) { //Функция ограничения выходных значений регулирующего устройства
if (x < min){
return min;
} else if (x > max) {
return max;
} else {
return x;
}
};

Pid.prototype._clearErrors = function() { //Функция очистки накопленной ошибки PID регулятора
this._sumError = 0;
this._lastError = 0;
this._lastTime = null;
};

Pid.prototype.setup = function(opts) {
this._target = opts.target === undefined ? this._target : opts.target;
this._kp = opts.kp === undefined ? this._kp : opts.kp;
this._ki = opts.ki === undefined ? this._ki : opts.ki;
this._kd = opts.kd === undefined ? this._kd : opts.kd;
this._outputMin =
opts.outputMin === undefined ? this._outputMin : opts.outputMin;
this._outputMax =
opts.outputMax === undefined ? this._outputMax : opts.outputMax;
this._clearErrors();
};

Pid.prototype.tune = function(opts) {
this._kp += opts.kp || 0;
this._ki += opts.ki || 0;
this._kd += opts.kd || 0;
this._clearErrors();
};

Pid.prototype.update = function(input) { //Функция PID регулятора
var date = new Date();
var dt = date.getTime() - this._lastTime;
var error = this._target - input;
var dError = 0;
var integralNormalized = 0;
var differential = 0;

if (this._lastTime) {
dError = error - this._lastError;
this._sumError += error;
integralNormalized = this._ki * this._sumError * dt;
differential = (this._kd * dError) / dt;
integralNormalized = this.clip(
integralNormalized,
this._outputMin,
this._outputMax
);

} else {
this._clearErrors();
}

var output = this._kp * error + integralNormalized - differential;

output = this.clip(output, this._outputMin, this._outputMax);
this._lastError = error;
var date = new Date();
this._lastTime = date.getTime();
return output;
};

Pid.prototype.run = function(repeat, interval) {
if (!this._intervalID) {
this._intervalID = setInterval(repeat, interval * 1000);
this._clearErrors();
}
};

Pid.prototype.stop = function() {
if (this._intervalID) {
clearInterval(this._intervalID);
}
this._intervalID = null;
};
//Создаем объект с нужными параметрами PID регулятора

var myControl = new Pid({
target: 20, // требуемая величина выходного значения
kp: 0.5, // пропорциональная составляющая
ki: 5, // интегральная составляющая
kd: 0.1, // дифференциальная составляющая
outputMin: 0, // минимальное значение выхода
outputMax: 10 // максимальное значение выхода
});

myControl.run(function() {

var input = dev[“DevTest”][“enabled”]; //Входное значение от виртуального устройства
var output = myControl.update(input); //Выходное значение
dev[“DevTest”][“log”] = String(output); //Выходное значение передаем в виртуальное устройство
myControl.kp = dev[“DevTest/kp1”]; //Пример для подбора параметров PID
myControl.setup(myControl); //Пример для подбора параметров PID
}, 2); //Интервал запуска ПИД-регулятора каждые 200 мс

4 лайка

Привет, немного подниму тему, тут смотрел докумнтацию к опциональному контроллеру к своему смесительному узлу valtec и увидел интересную идею: за счет ШИМ управляют обычной 24в термоголовкой, без 0-10v. По документации не понятно - там медленный ШИМ (10ки секунд или минуты период) или быстрый.
Мне видится быстрый (на уровне кГц) будет вполне работоспособен - нагрев нагревателя в термоголовке будет пропорционален. Получается - берем wb-led и можно подключать 4 головки и точно регулировать. Никто еще не реализовывал? Или может видите принципиальные подводные камни?

Как отрицательные моменты это:

  • провода от диммера могут генерировать помехи на высоких частотах ШИМ
  • логарифмическая кривая диммирования у модуля. То есть нужно подбирать состояния клапана и значения уставки

В целом должно работать, однако реального опыта у меня нет.

1 лайк

Медленного для термоэлектрических вполне достаточно, вот так: Подключение термоэлектрических сервоприводов к WBIO-DO-SSR-8 или WBIO-DO-HS-8 - #6 от пользователя BrainRoot
У них очень большая инерционность.
Но встречается , даже довольно часто, - и применение WB-LED (WB-MRGBW-D) для низковольтных, либо WB-MDM3 для актуаторов “на 220”. Кстати, внутри актуаторы с “0-10” управлением, которые требуют переменный ток питания - так и устроены - в зависимости от управляющего наприяжения часть периодов просто пропускается.

В общем - “медленного” вполне достаточно, но и с диммерами - работает.

1 лайк

Эта тема была автоматически закрыта через 7 дней после последнего ответа. В ней больше нельзя отвечать.