Если рассогласования между заданием и уставкой нет то и выход регулятора не изменится. Или я не так понял? Можете подробней описать или лог выхода на задание выложить, если ведёте.
П составляющая = рассогласование * коэффициент пропорциональности (если рассогласование =0 то и П =0)
И составляющая накапливается пока рассогласование не устранится (скорость увеличения зависит от частоты расчета регулятора и от коэффициента интегрирования) если очень медленно накапливается увеличить коэффициент или частоту расчета регулятогра
Д составляющая тем больше чем больше разница между прошлым измеренным значением и текущим с соответствующим знаком
Но не так немного. Рассогласование есть, нет приращения. В комнате температура 22,5 градуса. По DS измеряю. Задаю скажем 28 в термостате. Выход ПИД (П) становится 113 и стоит как вкопаный. И маленький, 0,1 задан, И и Д вообще можно на прерку в 0 сделать, пропорция должна суммироваться. Так библиотека ПИД работает. Она повышает постоянно выходной коэффициент до максимума. С прогрессией. А тут посчитали разницу, добавили ее к среднему и стоим. Нет движения вверх. Рассогласование уменьшать если (грею пальцами DS), то и выходной коэффициент уменьшается. Ну оно и понятно, прибавляется меньшее рассогласование. Да, в И есть сумма, а в П нету.
Может надо p = (temp < ust - d_ctl) ? p_max : (temp > ust) ? p_min : p + (kP * e);
Но не так немного. Рассогласование есть, нет приращения. В комнате температура 22,5 градуса. По DS измеряю. Задаю скажем 28 в термостате. Выход ПИД (П) становится 113 и стоит как вкопаный. И маленький, 0,1 задан, И и Д вообще можно на прерку в 0 сделать, пропорция должна суммироваться. Так библиотека ПИД работает. Она повышает постоянно выходной коэффициент до максимума. С прогрессией. А тут посчитали разницу, добавили ее к среднему и стоим. Нет движения вверх. Рассогласование уменьшать если (грею пальцами DS), то и выходной коэффициент уменьшается. Ну оно и понятно, прибавляется меньшее рассогласование. Да, в И есть сумма, а в П нету.
Может надо p = (temp < ust - d_ctl) ? p_max : (temp > ust) ? p_min : p + (kP * e);
В П суммы не должно быть (П это пропорционально ошибке и ни какой информации (сумме ошибок) она в отличие от И не несет.
ПИД необходимо настраивать на объекте регулирования, т.е. у Вас должен быть подключен и нагреватель.
После кИ и кД выставляем в 0
Задаем уставку и примерно кП. Включаем. Смотрим при текущем кП какая установилась температура, если ниже уставки увеличиваем немного кП, если начались колебания или колебания возникали при первом включении то кП убавляем. Когда добились максимально стабильной приблеженной к уставке температуры начинаем увеличивать потихоньку кИ, смотрим чтобы регулятор выходил точно на уставку без колебаний, при появлении колебаний уменьшаем кИ.
Так библиотека ПИД работает. Она повышает постоянно выходной коэффициент до максимума. С прогрессией. А тут посчитали разницу, добавили ее к среднему и стоим. Нет движения вверх. Рассогласование уменьшать если (грею пальцами DS), то и выходной коэффициент уменьшается. Ну оно и понятно, прибавляется меньшее рассогласование. Да, в И есть сумма, а в П нету.
Может надо p = (temp < ust - d_ctl) ? p_max : (temp > ust) ? p_min : p + (kP * e);
На выходе регулятора складываются П+И+Д. Постоянно приростать может только И.
Я уставки не менял, только P = 20 сделал. Да, скорее всего проблема с частотой вызова функции. 113 это выходной ПИД коэффициент при максимальном 255. Он не меняется при i=0.1, вообще не увеличивается, даже за 2 часа на столе. А если этих 113 попугаев на выходе не достаточно для нагрева? В общем смысл вроде уяснил. Либо Ki больше делать, либо чаще пересчет запускать. 1 раз в секунду слишком мало. В ПИД библиотеке по умолчанию 100мС стоит.
Попробуйте вместо
i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e); //И составляющая
Это
i = (i < i_min) ? i_min : (i > i_max) ? i_max : i += (kI * e); //И составляющая
Смысл EEPROM.put(); и EEPROM.get(); в том что пишется только изменение и любой тип переменных автоматически поддерживается. Надо бы и на этом сайте в разделе Программирования это дописать. Эти функции класса EEPROM относительно недавно появились.
Смысл EEPROM.put(); и EEPROM.get(); в том что пишется только изменение и любой тип переменных автоматически поддерживается. Надо бы и на этом сайте в разделе Программирования это дописать. Эти функции класса EEPROM относительно недавно появились.
Да дело в том что сам использую, пишу структуры в EEPROM, вот про EEPROM.update() прочитал, но как то всегда был уверен что если есть EEPROM.update() то EEPROM.put() именно переписывает информацию без доп проверок. Спасибо за подсказку перечитал справку, понял разницу :-)
С ПИД алгоритмом то удалось разобраться я так понял?
В диапазоне между (ust-d_ctl) и ust рассчитывается регулятор, если текущая температура ниже (ust-d_ctl) то П = макс. значению, если выше ust то П = мин.
Либо Ki больше делать, либо чаще пересчет запускать. 1 раз в секунду слишком мало. В ПИД библиотеке по умолчанию 100мС стоит.
То есть выво пересчета ПИД надо запускать чем чаще тем лучше? Период вызова 1 раз в секунду уже плохо?
Либо есть какойто рекомендованый период запуска пересчета?
Смотря с какого датчика параметр получать и от скорости реакции (постянной времени) всей системы зависит. DS18B20 считает температуру 750мС, то есть чаще чем почти раз в секунду новые данные не прийдут, а тепловая инерция у него куда больше, особенно в гильзе когда. А квадрик за это время упадет уже с такой стабилизацией. Тот же аналоговый LM35 может 1000 раз в секунду данные выдать, но толку от этого, если они с шумом будут и опять же тепловая инерция у него. Но тема про инкубаторы, а инкубатор за секунду свой режим не изменит. Так что пойдет. Это баржа груженая на реке. Ей рулить как катером легким не получится.
не, не ровно. Колбасит 0,4 туда-сюда. Но на открытом воздухе это невозможно, воздух движется как хочет между лампой и датчиком. Надо в коробочку. Вот приедет на днях человек, забиру коробочку инкубаторную из сендвича. Там и погоняем тогда.
Если рассогласования между заданием и уставкой нет то и выход регулятора не изменится. Или я не так понял? Можете подробней описать или лог выхода на задание выложить, если ведёте.
П составляющая = рассогласование * коэффициент пропорциональности (если рассогласование =0 то и П =0)
И составляющая накапливается пока рассогласование не устранится (скорость увеличения зависит от частоты расчета регулятора и от коэффициента интегрирования) если очень медленно накапливается увеличить коэффициент или частоту расчета регулятогра
Д составляющая тем больше чем больше разница между прошлым измеренным значением и текущим с соответствующим знаком
Но не так немного. Рассогласование есть, нет приращения. В комнате температура 22,5 градуса. По DS измеряю. Задаю скажем 28 в термостате. Выход ПИД (П) становится 113 и стоит как вкопаный. И маленький, 0,1 задан, И и Д вообще можно на прерку в 0 сделать, пропорция должна суммироваться. Так библиотека ПИД работает. Она повышает постоянно выходной коэффициент до максимума. С прогрессией. А тут посчитали разницу, добавили ее к среднему и стоим. Нет движения вверх. Рассогласование уменьшать если (грею пальцами DS), то и выходной коэффициент уменьшается. Ну оно и понятно, прибавляется меньшее рассогласование. Да, в И есть сумма, а в П нету.
Может надо p = (temp < ust - d_ctl) ? p_max : (temp > ust) ? p_min : p + (kP * e);
Либу рою, там сложнее все
01
/*Add Proportional on Measurement, if P_ON_M is specified*/
02
if
(!pOnE) outputSum-= kp * dInput;
03
04
if
(outputSum > outMax) outputSum= outMax;
05
else
if
(outputSum < outMin) outputSum= outMin;
06
07
/*Add Proportional on Error, if P_ON_E is specified*/
08
double
output;
09
if
(pOnE) output = kp * error;
10
else
output = 0;
11
12
/*Compute Rest of PID Output*/
13
output += outputSum - kd * dInput;
Но не так немного. Рассогласование есть, нет приращения. В комнате температура 22,5 градуса. По DS измеряю. Задаю скажем 28 в термостате. Выход ПИД (П) становится 113 и стоит как вкопаный. И маленький, 0,1 задан, И и Д вообще можно на прерку в 0 сделать, пропорция должна суммироваться. Так библиотека ПИД работает. Она повышает постоянно выходной коэффициент до максимума. С прогрессией. А тут посчитали разницу, добавили ее к среднему и стоим. Нет движения вверх. Рассогласование уменьшать если (грею пальцами DS), то и выходной коэффициент уменьшается. Ну оно и понятно, прибавляется меньшее рассогласование. Да, в И есть сумма, а в П нету.
Может надо p = (temp < ust - d_ctl) ? p_max : (temp > ust) ? p_min : p + (kP * e);
В П суммы не должно быть (П это пропорционально ошибке и ни какой информации (сумме ошибок) она в отличие от И не несет.
Увеличивайте И.
Я не могу понять почему у Вас П=113
Полность секцию ПИД с дефайнами выложте.
ПИД необходимо настраивать на объекте регулирования, т.е. у Вас должен быть подключен и нагреватель.
После кИ и кД выставляем в 0
Задаем уставку и примерно кП. Включаем. Смотрим при текущем кП какая установилась температура, если ниже уставки увеличиваем немного кП, если начались колебания или колебания возникали при первом включении то кП убавляем. Когда добились максимально стабильной приблеженной к уставке температуры начинаем увеличивать потихоньку кИ, смотрим чтобы регулятор выходил точно на уставку без колебаний, при появлении колебаний уменьшаем кИ.
Так библиотека ПИД работает. Она повышает постоянно выходной коэффициент до максимума. С прогрессией. А тут посчитали разницу, добавили ее к среднему и стоим. Нет движения вверх. Рассогласование уменьшать если (грею пальцами DS), то и выходной коэффициент уменьшается. Ну оно и понятно, прибавляется меньшее рассогласование. Да, в И есть сумма, а в П нету.
Может надо p = (temp < ust - d_ctl) ? p_max : (temp > ust) ? p_min : p + (kP * e);
На выходе регулятора складываются П+И+Д. Постоянно приростать может только И.
Я уставки не менял, только P = 20 сделал. Да, скорее всего проблема с частотой вызова функции. 113 это выходной ПИД коэффициент при максимальном 255. Он не меняется при i=0.1, вообще не увеличивается, даже за 2 часа на столе. А если этих 113 попугаев на выходе не достаточно для нагрева? В общем смысл вроде уяснил. Либо Ki больше делать, либо чаще пересчет запускать. 1 раз в секунду слишком мало. В ПИД библиотеке по умолчанию 100мС стоит.
Вызов PIDctl(Temp, setTemp); раз в секунду.
Температура и settemp просто заданы констатами. 22.0 и 37.0 соответственно. Что-то не так опять. Будто переменная Ki сбрасывается.
001
// автономный ПИД термостат с диммером на ATtiny85
002
//
003
004
#include <EEPROM.h>
005
#include <OneWire.h>
006
#define DETECT 1 //Детектор ноля
007
#define GATE 3 //управление симистором
008
#define PULSE 5 //ширина управляющего импульса на симистор
009
#define RESISTOR 4 //Светодиод совместно с кнопкой
010
011
//расчет мощности по ПИД закону регулирования
012
//Параметры регулятора
013
#define kP 20//коэффициент пропорциональности
014
#define p_min 0.0//минимум П составляющей - не < 0
015
#define p_max 100.0//максимум П составляющей - не > 100
016
#define kI 0.500//коэффициент интегрирования
017
#define i_min 0.0//минимум И составляющей
018
#define i_max 30.0//максимум И составляющей
019
#define kd 0.5//коэффициент диференциирования
020
#define d_ctl 7.0//зона пропорциональности ust-d_ctl
021
#define out_min 0//минимальный выходной %
022
#define out_max 254//максимальный выходной %
023
#define START_CONVERT 0
024
#define READ_TEMP 1
025
#define interval 1000UL
026
027
unsigned
long
prevmillis = 0;
028
//boolean state = 0;
029
//boolean statePrevios = 0;
030
// state 1 - светодиод светится, пин=выход
031
// state 0 светодиод не светится, пин=вход
032
volatile
byte
Value, ocr, jj;
033
float
Temp;
034
const
unsigned
int
TRHSTEP = 1000;
// Период опроса датчиков
035
unsigned
long
trhMillis = 0;
036
OneWire ds(10);
037
038
void
setup
() {
039
Serial
.begin(9600);
040
}
041
042
043
void
loop
() {
044
if
(millis() - prevmillis >= 1500) {
045
float
tempSet = 37.0;
046
//float tempSet = map(analogRead(RESISTOR), 0, 1023, 20, 40);
047
EEPROM.put(10, tempSet);
048
prevmillis = millis();
049
}
050
thermostat();
051
}
052
053
054
uint8_t PIDctl(
float
temp,
float
ust) {
055
uint8_t
out
= 0;
056
static
float
i = 0;
057
static
float
ed = 0;
058
float
e, p;
059
float
d;
060
e = (ust - temp);
//ошибка регулирования
061
p = (temp < ust - d_ctl) ? p_max : (temp > ust) ? p_min : (kP * e);
//П составляющая
062
i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e);
//И составляющая
063
d = kd * (e - ed);
//Д составляющая
064
ed = e;
065
out
= (p + i + d < out_min) ? out_min : (p + i + d > out_max) ? out_max : p + i + d;
066
return
out
;
067
}
068
069
int
tempProcess(boolean ch) {
070
int
t = 0;
071
if
(!ch) {
072
ds.reset();
073
ds.write(0xCC);
074
ds.write(0x44);
075
}
076
else
{
077
ds.reset();
078
ds.write(0xCC);
079
ds.write(0xBE);
080
t = ds.read();
081
t = t | (ds.read() << 8);
082
return
(t * 10) >> 4;
//целое в десятых *C (214=>21,4*C)
083
}
084
}
085
086
void
thermostat() {
087
unsigned
long
curMillis = millis();
// Получаем текущее время работы
088
if
(curMillis - trhMillis >= TRHSTEP) {
// время для нового измерения?
089
trhMillis = curMillis;
090
Temp = tempProcess(READ_TEMP);
//читаем темпратуру с далласа
091
Temp = (
float
) Temp / 10;
092
Temp = 20.0;
093
//Serial.println(Temp);
094
tempProcess(START_CONVERT);
// сразу запрос на конвертацию
095
float
setTemp;
096
EEPROM.
get
(10, setTemp);
097
Value = PIDctl(Temp, setTemp);
098
Serial
.println(Value);
099
ocr = map(Value, 5, 254, 250, 30);
100
//Serial.println(ocr);
101
}
102
}
Попробуйте вместо
i = (i < i_min) ? i_min : (i > i_max) ? i_max : i + (kI * e); //И составляющая
Это
i = (i < i_min) ? i_min : (i > i_max) ? i_max : i += (kI * e); //И составляющая
Двойное присваивание? Попробовал. Совершенно тот же результат. Залейте код в любую Ардуинку и посмотрите в порт.
Но у меня и так работало. Может Вам пока кД уменьшить или воопще в 0 выставить, а кП увеличивать пока куставке неприблизетесь.
Нет, тут что-то не так. При Kd = 0 тот же результат. Почему оно I не суммирует?
43
void
loop
() {
44
if
(millis() - prevmillis >= 1500) {
45
float
tempSet = 37.0;
46
//float tempSet = map(analogRead(RESISTOR), 0, 1023, 20, 40);
47
EEPROM.put(10, tempSet);
48
prevmillis = millis();
49
}
50
thermostat();
51
}
Немного не по теме, но строка 47 убъет EPPROM за 2 дня :-(
Если я провильно посчитал 40 вывозов в минуту, 2400 в час, 57600 в сутки. Ресурс у EEPROM 100 000 циклов записи.
Нет, put пишет только изменившееся значение.
Пруф https://www.arduino.cc/en/Reference/EEPROMPut
Note
This function uses EEPROM.update() to perform the write, so does not rewrites the value if it didn't change.
Вывел i в монитор.
Нашел #define i_max 30.0//максимум И составляющей
Да. Можете до 255 поднять
Просто в моем случае И более 15 не поднималось в установившемся режиме и я ограничил его 30
Ещё p_max установите в 255
Фух, ну разобрались. Спасибо. Разъясните пожалуйста смысл d_ctl
Нет, put пишет только изменившееся значение.
Пруф https://www.arduino.cc/en/Reference/EEPROMPut
Note
This function uses EEPROM.update() to perform the write, so does not rewrites the value if it didn't change.
Спасиб, век живи век учись :-)
Смысл EEPROM.put(); и EEPROM.get(); в том что пишется только изменение и любой тип переменных автоматически поддерживается. Надо бы и на этом сайте в разделе Программирования это дописать. Эти функции класса EEPROM относительно недавно появились.
Смысл EEPROM.put(); и EEPROM.get(); в том что пишется только изменение и любой тип переменных автоматически поддерживается. Надо бы и на этом сайте в разделе Программирования это дописать. Эти функции класса EEPROM относительно недавно появились.
Да дело в том что сам использую, пишу структуры в EEPROM, вот про EEPROM.update() прочитал, но как то всегда был уверен что если есть EEPROM.update() то EEPROM.put() именно переписывает информацию без доп проверок. Спасибо за подсказку перечитал справку, понял разницу :-)
С ПИД алгоритмом то удалось разобраться я так понял?
Да, все пошло.
Фух, ну разобрались. Спасибо. Разъясните пожалуйста смысл d_ctl
В диапазоне между (ust-d_ctl) и ust рассчитывается регулятор, если текущая температура ниже (ust-d_ctl) то П = макс. значению, если выше ust то П = мин.
Да, все пошло.
Ну и хорошо.
Попозже немного допилю ПИД, есть некоторые мысли ещё.
И автонастройку написать хочу.
А это реально на медленных процессах? У меня либа autotune странное выдавала.
Тут больше от алгоритма зависет и от анализа полученных при испытаниях данных.
Ок, ждем с нетерпением! Хотябы адаптивный подбор коэффициентов.
Либо Ki больше делать, либо чаще пересчет запускать. 1 раз в секунду слишком мало. В ПИД библиотеке по умолчанию 100мС стоит.
То есть выво пересчета ПИД надо запускать чем чаще тем лучше? Период вызова 1 раз в секунду уже плохо?
Либо есть какойто рекомендованый период запуска пересчета?
Смотря с какого датчика параметр получать и от скорости реакции (постянной времени) всей системы зависит. DS18B20 считает температуру 750мС, то есть чаще чем почти раз в секунду новые данные не прийдут, а тепловая инерция у него куда больше, особенно в гильзе когда. А квадрик за это время упадет уже с такой стабилизацией. Тот же аналоговый LM35 может 1000 раз в секунду данные выдать, но толку от этого, если они с шумом будут и опять же тепловая инерция у него. Но тема про инкубаторы, а инкубатор за секунду свой режим не изменит. Так что пойдет. Это баржа груженая на реке. Ей рулить как катером легким не получится.
Да, все пошло.
А можете график с П,И, уставкой и текущей одновременно выложить?
Или устава температура и выход регулятора.
Завтра, на работе железки.
MOC3040 Подходит к этому варианту?
MOC3040 Подходит к этому варианту?
Подойдет хоть реле, только управлять надобудет так называемым медленным ШИМ.
Спасибо .Я так понял что нужен оптрон без Zero contpol?
Спасибо .Я так понял что нужен оптрон без Zero contpol?
И с ним можно.
Есть диммер автономный если кому надо.
http://arduino.ru/forum/programmirovanie/attiny85-i-preryvanie?
Графики не могу сегодня сделать - кабель дома забыл.
Трогал термометр в процессе. Вроде работает. Грелку позже прицеплю и в реале испытаем.
С грелкой интереснее конечно будет выход на уставку посмотреть. Будем подождать.
У меня такой выход на уставку был http://arduino.ru/forum/programmirovanie/trebuetsya-perenesti-znachenie-peremennoi-v-sleduyushchii-tsikl-loop#comment-108465
Красиво. Но "цветомузыка" убила.
Вот так с грелкой-галогенкой на столе. Не настраивал.
Подвинул датчик ближе. ШИМ от 1 уже светит. 43градуса это ого!
А на уставке ровно держится? Колебания спадают?
не, не ровно. Колбасит 0,4 туда-сюда. Но на открытом воздухе это невозможно, воздух движется как хочет между лампой и датчиком. Надо в коробочку. Вот приедет на днях человек, забиру коробочку инкубаторную из сендвича. Там и погоняем тогда.
Рисую свою плату под инкубатор на платформе НАНО.
Можно ли использовать выводы А6,А7 на плате НАНО как обычные линии ввода-вывода?
http://arduino.ru/Tutorial/AnalogInputPins
Спасибо.
Т-есть можно выводы А6иА7 использовать как стандартный дигитальный выход.
Нет, только A6 можно. A7 в другом регистре. Разве трудно посчитать? А0 это 14, А6 - 19.