Ваш вариант ещё не пробовал, загвоздка скорее в том что я после нагрева охлаждаю один бак и частично второй, вот и получается на тот на который мало воздуха после во время охлаждения попадает вот он и нагревается больше, так как у него начальная точка и у бака выше чем с той стороны где я дую вентилятором, у меня есть два куллера но они не усьановлены, а чтобы было быстрее дую на них большим вентилятором.
Кстати, а если всё таки решу два датчика установить то, так пойдёт отслеживать?:
#define t_pwm 1000//период 100% мощности канал 1
#define t_pwm2 1000//период 100% мощности канал 2
#define t_time 100//период опроса температуры 1
#define t_time2 150//период опроса температуры 2
float termo=A0;// вход основного датчика температуры1
float termo2=A1;// вход основного датчика температуры2
//для ПИ регулятора
float ca,cb;
long time;//интервал замера температуры
long on_time=0;//для периода ШИМ1
long on_time2=0;//для периода ШИМ1
int zad=0;//задание мощности
float temp=0.0;//текущее значение температуры датчика 1
float temp2=0.0;//текущее значение температуры датчика 2
float pre_temp=0.0;//предыдущее значение температуры 1
float pre_temp2=0.0;//предыдущее значение температуры 2
int cd=0;
int c=0;
int w=0;
int ce=0;//пройденые циклы мощности
float ust4=489;//температура средний режим=115
int outten = 9;
int outten2 = 12;
void setup() {
analogReference(INTERNAL2V56);
pinMode(outten, OUTPUT);
pinMode(outten2, OUTPUT);
pinMode(termo, INPUT);
pinMode(termo2, INPUT);
}
void loop() {
if ((millis()-time)>=t_time){
time=millis();
temp=analogRead(termo);//получаем температуру
temp=(pre_temp*0.2)+(temp*0.8);//фильтр
// w=abs((ust-temp)*(pre_temp-temp));//время выхода на уставку
pre_temp=temp;}
if (millis()>3000){
if((millis()-on_time)>=t_pwm){//период ШИМ
on_time=millis();
PIctl4();//расчет мощности
if(c<zad){
digitalWrite(outten,1);
}
else{
if (zad != 100){
digitalWrite(outten,0);
}
}
c=c+1;
if(c==100){
c=0;
//PIctl();
}
}
}
if ((millis()-time)>=t_time2){
time=millis();
temp2=analogRead(termo2);//получаем температуру
temp2=(pre_temp2*0.2)+(temp2*0.8);//фильтр
// w=abs((ust-temp)*(pre_temp-temp));//время выхода на уставку
pre_temp2=temp2;}
if (millis()>3000){
if((millis()-on_time2)>=t_pwm2){//период ШИМ
on_time2=millis();
PIctl4();//расчет мощности
if(c<zad){
digitalWrite(outten2,1);
}
else{
if (zad != 100){
digitalWrite(outten2,0);
}
}
c=c+1;
if(c==100){
c=0;
//PIctl();
}
}
}
}
void PIctl4()
{
if(temp>(ust4-2.12)&&temp<(ust4+2.12))//зона нечувствительности +-0,5C
{
zad=cb;//если ошибка+-0.5С то мощность = И состовляющей
}
else//иначе
{
float cf;
cf=(ust4-temp);//вычисление ошибки регулирования
// расчет выходной мощности:
ca=65.0*cf;//расчет пропорциональной состовляющей
if (ca<0.0)//мощность не может быть отрицательной
{
ca=0.0;//ограничение P
}
cb=(cb+(cf*0.014));//расчет интегральной составляющей = тепловым потерям
if (cb>100.0)//мощность не может быть больше 100%
{
cb=100.0;//ограничение I
}
if (cb<-100.0)
{
cb=-50.0;//ограничение I
}
//расчет выходной мощности
zad=ca+cb;
}
//ограничение управляющего сигнала
//для исключения частого переключения реле
//если твердотельное реле, можно не ограничивать
if (zad<4){
zad=0;
}
if (zad>96){
zad=100;
}
//корректировка при отклонении температуры более чем на +-2С
//для быстрого выхода на уставку
if (temp<(ust4-8.5))//если темп < уст на 2С
{
zad=100;//то мощность 100%
cb=0;
}
if (temp>(ust4+8.5))//если темп > уст на 2С
{
zad=0;//то мощность 0%
cb=0;
}
}
Попробовал ваш код последний, на отдельной никуда не подпаяной ардуино мега, так замыкаю А0 на землю, в мониторе последовательного порта 0 градусов и 100% мощности, вот только на выводе 9 и 12 меги ничего нету, зато на выводе 10 появляется лог.1(ну так как 100% мощности), причём здесь вывод 10, не пойму, перепроверил 100 раз.
Я понял в чем проблемма, класс DigOut в погоне за скоростью под давлением местных прогеров я начал переделывать на прямое управление портами ... вобщем на мега он работать в таком виде не будет правильно. Я попозже вам ссылку выложу на этотже класс который со всеми дуинами работает. Просто замените его и все заработает, даже код править не нужно.
Добрый вечер. Я только начинаю изучение ардуион и наткнулся на эту тему. Сразу всплыла одна идея, которая меня волнует. Есть у меня надаче ящик с ТЭНом, порядка 1500 ватт. Есть регулятор, который держит определнную температуру в нем, за счет замыкания\размыкания реле. Так же в регуляторе есть аналоговый выход 0(4)-20 мА с функцией ПИДрегулипрвания. Так вот, как бы мне сделать плавное регулирование ТЭНами?? Я хочу чтоб при температуре близкой к уставке, потребление электричесва было минимальное. Я хочу услышать от Вас все плюсы и минусы такого подключения, есть смысл в таком регулировании?? И можно ли реализовать проект на ардуине без промышленного регулятора?? Так же у меня есть регулятор мощьностидля ТЭНа, который управляется переменным резистором, ну не вешать же на него сервопривод =))) Вообщем пока у меня тьма в котелке. Жду от вас помощи, пока только в теории.
Предложу использовать встроенный светодиод для индикации выходной мощности.
Нужно его прописать вначале
DigOut PwrInd (13,0);//индикатор мощности
И в коде где выдаем мощность
if (millis()>3000){//разрешаем управление нагрузкой через 3 сек после включения
outten.blink(t_pwm, (t_pwm/100)*zad);//управление теном 1
outten2.blink(t_pwm, (t_pwm/100)*zad2);//управление теном 2
PwrInd=outten;//индикация управления симистором
}
Спасибо yul-i-an, поисправляю у себя и проверю, на чистой меге, хотя проблема у меня была в том что один бак охлаждаю, а второй частично и разница была в стартовых температурах, а так как мощность одинаковая даётся в одинаковый промежуток времени то они догнать по температуре друг друга не могли)
Ваш вариант ещё не пробовал, загвоздка скорее в том что я после нагрева охлаждаю один бак и частично второй, вот и получается на тот на который мало воздуха после во время охлаждения попадает вот он и нагревается больше, так как у него начальная точка и у бака выше чем с той стороны где я дую вентилятором, у меня есть два куллера но они не усьановлены, а чтобы было быстрее дую на них большим вентилятором.
Кстати, а если всё таки решу два датчика установить то, так пойдёт отслеживать?:
#define t_pwm 1000//период 100% мощности канал 1
#define t_pwm2 1000//период 100% мощности канал 2
#define t_time 100//период опроса температуры 1
#define t_time2 150//период опроса температуры 2
float termo=A0;// вход основного датчика температуры1
float termo2=A1;// вход основного датчика температуры2
//для ПИ регулятора
float ca,cb;
long time;//интервал замера температуры
long on_time=0;//для периода ШИМ1
long on_time2=0;//для периода ШИМ1
int zad=0;//задание мощности
float temp=0.0;//текущее значение температуры датчика 1
float temp2=0.0;//текущее значение температуры датчика 2
float pre_temp=0.0;//предыдущее значение температуры 1
float pre_temp2=0.0;//предыдущее значение температуры 2
int cd=0;
int c=0;
int w=0;
int ce=0;//пройденые циклы мощности
float ust4=489;//температура средний режим=115
int outten = 9;
int outten2 = 12;
void setup() {
analogReference(INTERNAL2V56);
pinMode(outten, OUTPUT);
pinMode(outten2, OUTPUT);
pinMode(termo, INPUT);
pinMode(termo2, INPUT);
}
void loop() {
if ((millis()-time)>=t_time){
time=millis();
temp=analogRead(termo);//получаем температуру
temp=(pre_temp*0.2)+(temp*0.8);//фильтр
// w=abs((ust-temp)*(pre_temp-temp));//время выхода на уставку
pre_temp=temp;}
if (millis()>3000){
if((millis()-on_time)>=t_pwm){//период ШИМ
on_time=millis();
PIctl4();//расчет мощности
if(c<zad){
digitalWrite(outten,1);
}
else{
if (zad != 100){
digitalWrite(outten,0);
}
}
c=c+1;
if(c==100){
c=0;
//PIctl();
}
}
}
if ((millis()-time)>=t_time2){
time=millis();
temp2=analogRead(termo2);//получаем температуру
temp2=(pre_temp2*0.2)+(temp2*0.8);//фильтр
// w=abs((ust-temp)*(pre_temp-temp));//время выхода на уставку
pre_temp2=temp2;}
if (millis()>3000){
if((millis()-on_time2)>=t_pwm2){//период ШИМ
on_time2=millis();
PIctl4();//расчет мощности
if(c<zad){
digitalWrite(outten2,1);
}
else{
if (zad != 100){
digitalWrite(outten2,0);
}
}
c=c+1;
if(c==100){
c=0;
//PIctl();
}
}
}
}
void PIctl4()
{
if(temp>(ust4-2.12)&&temp<(ust4+2.12))//зона нечувствительности +-0,5C
{
zad=cb;//если ошибка+-0.5С то мощность = И состовляющей
}
else//иначе
{
float cf;
cf=(ust4-temp);//вычисление ошибки регулирования
// расчет выходной мощности:
ca=65.0*cf;//расчет пропорциональной состовляющей
if (ca<0.0)//мощность не может быть отрицательной
{
ca=0.0;//ограничение P
}
cb=(cb+(cf*0.014));//расчет интегральной составляющей = тепловым потерям
if (cb>100.0)//мощность не может быть больше 100%
{
cb=100.0;//ограничение I
}
if (cb<-100.0)
{
cb=-50.0;//ограничение I
}
//расчет выходной мощности
zad=ca+cb;
}
//ограничение управляющего сигнала
//для исключения частого переключения реле
//если твердотельное реле, можно не ограничивать
if (zad<4){
zad=0;
}
if (zad>96){
zad=100;
}
//корректировка при отклонении температуры более чем на +-2С
//для быстрого выхода на уставку
if (temp<(ust4-8.5))//если темп < уст на 2С
{
zad=100;//то мощность 100%
cb=0;
}
if (temp>(ust4+8.5))//если темп > уст на 2С
{
zad=0;//то мощность 0%
cb=0;
}
}
Чтобы установить второй датчик температуры достаточно будет прописать его тут
if(currentMillis-preTempMillis>=t_time){//пришлло время мерить температуру
temp=analogRead(termo);//получаем температуру с первого
temp=temp/2.06;
temp=(pre_temp*0.2)+(temp*0.8);//фильтр
pre_temp=temp;
temp2=analogRead(termo2);//получаем температуру со второго
temp2=temp2/2.06;
temp=(pre_temp2*0.2)+(temp2*0.8);//фильтр
pre_temp2=temp2;
preTempMillis=currentMillis;
}
Но ввиду усложнения код лучше написать функцию в которую передовать аналоговых вход на котором сидит датчик, а она вернет отфильтрованную температуру
например
float getTempLM35(byte Ain)
{
static float pre_temp=0;
float temp=analogRead(Ain);//получаем значение АЦП
temp=temp/2.06;//переводим в градусы
temp=(pre_temp*0.2)+(temp*0.8);//фильтруем
pre_temp=temp;//для фильтра в следующем цикле
return temp;
}
тогда вместо
if(currentMillis-preTempMillis>=t_time){//пришлло время мерить температуру
temp=analogRead(termo);//получаем температуру с первого
temp=temp/2.06;
temp=(pre_temp*0.2)+(temp*0.8);//фильтр
pre_temp=temp;
temp2=analogRead(termo2);//получаем температуру со второго
temp2=temp2/2.06;
temp=(pre_temp2*0.2)+(temp2*0.8);//фильтр
pre_temp2=temp2;
preTempMillis=currentMillis;
}
проблема у меня была в том что один бак охлаждаю, а второй частично и разница была в стартовых температурах, а так как мощность одинаковая даётся в одинаковый промежуток времени то они догнать по температуре друг друга не могли)
В таком случае обязательно применение второрого датчика, темболее что это не грозит большими затратами и усложнением кода. И часть кода которая отвечает за корректировку мощности выкинуть как ненужный костыль.
Аппарат работает, разница в ТЭНах есть около 3-4 градусов но не критично, вообще разница около 7-8 градусов, но с учётом погрешности китайских мультиметров между ними разница порядка 3-4 градусов. Пока работаю на первом варианте.
Извиняюсь занят был, освобожусь скину благодарность, первый вариант это:
#define t_pwm 1000//период 100% мощности
#define t_time 1000//период опроса температуры
float t1=A0;// Вход АЦП 0
int outten=13;
//для ПИ регулятора
float p,i;
long time;//интервал замера температуры
long on_time=0;//для периода ШИМ
int zad=0;
float temp=0.0;//текущее значение температуры
float pre_temp=0.0;//предыдущее значение температуры
int w=0;
float ust=489;//115 градусов
int c=0;//пройденные циклы мощности
void setup(){
pinMode(t1,INPUT);
pinMode(outten,OUTPUT);
time = millis();
on_time = time;
}
void loop(){
//---------------чтение температуры---------------
if ((millis()-time)>=t_time){
time=millis();
temp=analogRead(t1);//получаем температуру
temp=(pre_temp*0.2)+(temp*0.8);//фильтр
// w=abs((ust-temp)*(pre_temp-temp));//время выхода на уставку
pre_temp=temp;
PIctl();//расчет мощности
}
//---------------------управление мощностью--------------------------
//выдаем мощность
if (millis()>3000){
if((millis()-on_time)>=t_pwm){//период ШИМ
on_time=millis();
if(c<zad){
digitalWrite(outten,1);
}
else{
if (zad != 100){
digitalWrite(outten,0);
}
}
c=c+1;
if(c==100){
c=0;
//PIctl();
}
}
}
}
void PIctl()
{
if(temp>(ust-0.5)&&temp<(ust+0.5))//зона нечувствительности +-0,5C
{
zad=i;
}
else
{
float e;
e=(ust-temp);
// расчет выходной мощности:
p=65.0*e;//130 коффициент пропорциональности 130.0
if (p<0.0)
{
p=0.0;//ограничение P
}
i=(i+(e*0.014));//0.7
if (i>100.0)
{
i=100.0;//ограничение I
}
if (i<-100.0)
{
i=-50.0;//ограничение I
}
//расчет выходной мощности
zad=p+i;
}
//ограничение управляющего сигнала
//для исключения частого переключения реле
//если твердотельное реле, можно не ограничивать
if (zad<4){
zad=0;
}
if (zad>96){
zad=100;
}
//корректировка при отклонении температуры более чем на +-2С
//для быстрого выхода на уставку
if (temp<(ust-2.0))//если темп < уст на 2С
{
zad=100;//то мощность 100%
i=0;
}
if (temp>(ust+2.0))//если темп > уст на 2С
{
zad=0;//то мощность 0%
i=0;
}
}
Для первого варианта осциллограма выглядит так как всё время лог. 1 стоит, ну это понятно это же период ШИМ =1с. ( развёртка на осциле 50мс, осцил Хамелион, показания снимал задавая на вход АЦП вместо температурного датчика около 90-95% от необходимого входного для АЦП(от уставки)), так вот прямоугольные импульсы появляются как - то хаотично через разные промежутки времени , бывают как будтя два вместе соединяются, так то всё работает на симисторе, в моём устройстве, может это так осцил рисует.
С этим кодом(который на два выходы с коректировкой по мощности) всё по другому при том же периоде ШИМ=1с., прямоугольные импульсы появляются через одинаковые промежутки времени, и прямоугольные импульсы друг на друга не накладываются, в реальной работе не проверял. Праметры осцыла и задачи входного сигнала на АЦП те же. Коректировка мощности на другой канал работает.
#include <DigOut.h>//подключаем библиотеку выходов yadi.sk/d/NM4S6HmFrTRu6
#define t_time 100//период опроса температуры
DigOut outten(9), outten2(12);//инициализация цифровых выходов на тен 1 и 2
#define termo A0//вход основного датчика температуры
unsigned long time;//интервал замера температуры
byte zad=0;//задание мощности ТЭНа1
byte zad2=0;//задание мощности ТЭНа2
float temp=0.0;//текущее значение температуры
float pre_temp=0.0;//предыдущее значение температуры
unsigned long preTempMillis=0;//для опроса температуры
unsigned long prePIctl_time=0;//для расчета мощности
float ust=0;//уставка
#define t_pwm 1000//период медленного ШИМ в мс
#define ust4 115//температура средний режим=115
void setup() {
//analogReference(INTERNAL2V56);
Serial.begin (9600);
}
void loop() {
unsigned long currentMillis=millis();
if(currentMillis-preTempMillis>=t_time){
temp=analogRead(termo);//получаем температуру
//а тут неплохобы в градусы целсия перевести
temp=temp/2.06;//переводим показания АЦП в градусы С
temp=(pre_temp*0.3)+(temp*0.7);//фильтр от резких изменений температуры
pre_temp=temp;
preTempMillis=currentMillis;//сброс таймера замера температуры
}
ust=ust4;//уставка
if(currentMillis-prePIctl_time>1000){//если подошло время расчитать мощность
zad=PIctl(temp, ust);//расчет мощности
zad=pwr(zad,0);//корректировка мощности
zad2=pwr(zad,10);//корректировка мощности
prePIctl_time=currentMillis;//сброс таймера расчета мощности
//Вывод в порт температуры и мощности
Serial.print(temp);
Serial.print("-T ");
Serial.print(zad);
Serial.print("-% ");
Serial.print(zad2);
Serial.println("-%");
}
if (millis()>3000){//разрешаем управление нагрузкой через 3 сек после включения устройства
outten.blink(t_pwm, (t_pwm/100)*zad);//управление теном 1
outten2.blink(t_pwm, (t_pwm/100)*zad2);//управление теном 2
}
}//END loop
//функция расчета мощности по ПИ закону регулирования
byte PIctl(float temp, float ust)
{
byte zad=0;
static float i=0;
if(temp>(ust-0.5)&&temp<(ust+0.5))//зона нечувствительности +-0,5C
{
return byte(i);
}
else//иначе
{
float e, p;
e=(ust-temp);//вычисление ошибки регулирования
// расчет выходной мощности
p=(1.5*e);//расчет пропорциональной состовляющей
if (p<0.0)//мощность не может быть отрицательной
{
p=0.0;//ограничение P
}
i=(i+(e*0.014));//расчет интегральной составляющей = тепловым потерям
if (i>100.0)//мощность не может быть больше 100%
{
i=100.0;//ограничение I
}
if (i<-100.0)
{
i=-50.0;//ограничение I
}
//расчет выходной мощности
zad=byte(p+i);
if(zad>100){return 100;}
if(zad<0){return 0;}
//корректировка при отклонении температуры более чем на +-2С
//для быстрого выхода на уставку
if (temp<(ust-8.5))//если темп < уст на 2С
{
zad=100;//то мощность 100%
i=0;
}
if (temp>(ust+8.5))//если темп > уст на 2С
{
zad=0;//то мощность 0%
i=0;
}
return zad;
}///
}
byte pwr(int zad, int correct)
{
int res = zad+correct;
if(res>100){
res=100;
}
if(res<0){
res=0;
}
else
{
res=zad;
}
return res;
}
А вот такой код тоже на два выхода с корректировкой, в мониторе последовательного порта показывает 200%, на выходе только как я понимаю период ШИМ, а прямоугольные импульсы не появляются
#include <DigOut.h>//подключаем библиотеку выходов yadi.sk/d/NM4S6HmFrTRu6
#define t_time 100//период опроса температуры
DigOut outten(9), outten2(12);//инициализация цифровых выходов на тен 1 и 2
#define termo A0//вход основного датчика температуры
unsigned long time;//интервал замера температуры
byte zad=0;//задание мощности ТЭНа1
byte zad2=0;//задание мощности ТЭНа2
float temp=0.0;//текущее значение температуры
float pre_temp=0.0;//предыдущее значение температуры
unsigned long preTempMillis=0;//для опроса температуры
float ust=0;
#define t_pwm 1000//период ШИМ в мс
#define ust4 489//температура средний режим=115
void setup() {
analogReference(INTERNAL2V56);
}
void loop() {
unsigned long currentMillis=millis();
if(currentMillis-preTempMillis>=t_time){
temp=analogRead(termo);//получаем температуру
//а тут неплохобы в градусы целсия перевести
//temp=temp/4.25;
temp=(pre_temp*0.2)+(temp*0.8);//фильтр
pre_temp=temp;
preTempMillis=currentMillis;
}
ust=ust4;
zad=PIctl(temp, ust);//расчет мощности
zad=pwr(zad,0);//корректировка мощности
zad2=PIctl(temp, ust);//расчет мощности
zad2=pwr(zad2,10);//корректировка мощности
if (millis()>3000){//разрешаем управление нагрузкой через 3 сек после включения
outten.blink(t_pwm, (t_pwm/100)*zad);//управление теном 1
outten2.blink(t_pwm, (t_pwm/100)*zad2);//управление теном 2
}
}//END loop
//расчет мощности
byte PIctl(float temp, float ust)
{
static float p, i;
if(temp>(ust-2.12)&&temp<(ust+2.12))//зона нечувствительности +-0,5C
{
zad=i;//если ошибка+-0.5С то мощность = И состовляющей
}
else//иначе
{
float e;
e=(ust-temp);//вычисление ошибки регулирования
// расчет выходной мощности:
p=(65.0*e);//расчет пропорциональной состовляющей
if (p<0.0)//мощность не может быть отрицательной
{
p=0.0;//ограничение P
}
i=(i+(e*0.014));//расчет интегральной составляющей = тепловым потерям
if (i>100.0)//мощность не может быть больше 100%
{
i=100.0;//ограничение I
}
if (i<-100.0)
{
i=-50.0;//ограничение I
}
//расчет выходной мощности
zad=p+i;
}
//корректировка при отклонении температуры более чем на +-2С
//для быстрого выхода на уставку
if (temp<(ust-8.5))//если темп < уст на 2С
{
zad=100;//то мощность 100%
i=0;
}
if (temp>(ust+8.5))//если темп > уст на 2С
{
zad=0;//то мощность 0%
i=0;
}
}
//корректировка мощности
byte pwr(int zad, int correct)
{
int res = zad+correct;
if(res>100){
return 100;
}
if(res<0 || zad == 0){
return 0;
}
return res;
}
Насчёт кода для применения двух датчиков и двух выходов разных, пост 64, а как выдать мощность на разные выхода, после получения показания с двух датчиков, не пойму.
Ну второй код мне кажеться получился более читаемым и прозрачным. А картинки с осцилогрофа какнибудь можете выложить, для второго кода?
Я на выходных этот код мучал, мне кажеться что он полностью рабочий
#include <DigOut.h>//подключаем библиотеку выходов yadi.sk/d/NM4S6HmFrTRu6
#define t_time 1000//период опроса температуры
#define power_time 1000//период расчета мощности
DigOut outten(9), outten2(8), ind(13,0);//инициализация цифровых выходов на тен 1, 2 и индикатор
#define termo A0//вход основного датчика температуры
unsigned long time;//интервал замера температуры
byte zad=0;//задание мощности ТЭНа1
byte zad2=0;//задание мощности ТЭНа2
float temp=0.0;//текущее значение температуры
float pre_temp=0.0;//предыдущее значение температуры
unsigned long preTempMillis=0;//для опроса температуры
unsigned long prePIctl_time=0;//для расчета мощности
float ust=0;//уставка
#define t_pwm 1000//период медленного ШИМ в мс
#define ust4 100//температура средний режим=100
void setup() {
//analogReference(INTERNAL2V56);
Serial.begin (9600);
}
void loop() {
ust=ust4;//уставка
unsigned long currentMillis=millis();
if(currentMillis-preTempMillis>=t_time){
temp = getTempLM35(termo);
//сюда второй датчик
preTempMillis=currentMillis;//сброс таймера замера температуры
}
if(currentMillis-prePIctl_time>=power_time){//если подошло время расчитать мощность
zad=PIctl(temp, ust);//расчет мощности
//если два датчика то zad2= PIctl(temp2, ust);
zad2=zad;//мощность одинаковая
prePIctl_time=currentMillis;//сброс таймера расчета мощности
//Вывод в порт температуры и мощности
serialPrint();
}
if (currentMillis>5000){//разрешаем управление нагрузкой через 3 сек после включения устройства
outten.blink(t_pwm, ((t_pwm)/100)*zad);//управление теном 1
outten2.blink(t_pwm, ((t_pwm)/100)*zad2);//управление теном 2
ind=outten;
}
}//END loop
//функция расчета мощности по ПИ закону регулирования
byte PIctl(float temp, float ust)
{
byte zad=0;
static float i=0;
if(temp>(ust-0.5)&&temp<(ust+0.5))//зона нечувствительности +-0,5C
{
return byte(i);
}
else//иначе
{
float e, p;
e=(ust-temp);//вычисление ошибки регулирования
// расчет выходной мощности
p=(1.5*e);//расчет пропорциональной состовляющей
if (p<0.0)//мощность не может быть отрицательной
{
p=0.0;//ограничение P
}
i=(i+(e*0.014));//расчет интегральной составляющей = тепловым потерям
if (i>100.0)//мощность не может быть больше 100%
{
i=100.0;//ограничение I
}
if (i<-100.0)
{
i=-50.0;//ограничение I
}
//расчет выходной мощности
zad=byte(p+i);
if(zad>100){return 100;}
if(zad<0){return 0;}
//корректировка при отклонении температуры более чем на +-2С
//для быстрого выхода на уставку
if (temp<(ust-8.5))//если темп < уст на 2С
{
zad=100;//то мощность 100%
i=0;
}
if (temp>(ust+8.5))//если темп > уст на 2С
{
zad=0;//то мощность 0%
i=0;
}
}///
return zad;
}
//получение температуры с LM35
float getTempLM35(byte Ain)
{
static float pre_temp=0;
float temp=analogRead(Ain);//получаем значение АЦП
temp=temp/2.06;//переводим в градусы
temp=(pre_temp*0.3)+(temp*0.7);//фильтруем
pre_temp=temp;//для фильтра в следующем цикле
return temp;
}
//вывод в монитор для отладки
void serialPrint()
{
Serial.print(temp);
Serial.print("-T ");
Serial.print(zad);
Serial.print("-% ");
Serial.print(zad2);
Serial.println("-%");
}
Единственное останется настроить ПИ регулятор и если всётаки две разные емкости добавить второй датчик температуры, темболее что теперь это не составит труда.
А вот такой код тоже на два выхода с корректировкой, в мониторе последовательного порта показывает 200%, на выходе только как я понимаю период ШИМ, а прямоугольные импульсы не появляются
#include <DigOut.h>//подключаем библиотеку выходов yadi.sk/d/NM4S6HmFrTRu6
#define t_time 100//период опроса температуры
DigOut outten(9), outten2(12);//инициализация цифровых выходов на тен 1 и 2
#define termo A0//вход основного датчика температуры
unsigned long time;//интервал замера температуры
byte zad=0;//задание мощности ТЭНа1
byte zad2=0;//задание мощности ТЭНа2
float temp=0.0;//текущее значение температуры
float pre_temp=0.0;//предыдущее значение температуры
unsigned long preTempMillis=0;//для опроса температуры
float ust=0;
#define t_pwm 1000//период ШИМ в мс
#define ust4 489//температура средний режим=115
void setup() {
analogReference(INTERNAL2V56);
}
void loop() {
unsigned long currentMillis=millis();
if(currentMillis-preTempMillis>=t_time){
temp=analogRead(termo);//получаем температуру
//а тут неплохобы в градусы целсия перевести
//temp=temp/4.25;
temp=(pre_temp*0.2)+(temp*0.8);//фильтр
pre_temp=temp;
preTempMillis=currentMillis;
}
ust=ust4;
zad=PIctl(temp, ust);//расчет мощности
zad=pwr(zad,0);//корректировка мощности
zad2=PIctl(temp, ust);//расчет мощности
zad2=pwr(zad2,10);//корректировка мощности
if (millis()>3000){//разрешаем управление нагрузкой через 3 сек после включения
outten.blink(t_pwm, (t_pwm/100)*zad);//управление теном 1
outten2.blink(t_pwm, (t_pwm/100)*zad2);//управление теном 2
}
}//END loop
//расчет мощности
byte PIctl(float temp, float ust)
{
static float p, i;
if(temp>(ust-2.12)&&temp<(ust+2.12))//зона нечувствительности +-0,5C
{
zad=i;//если ошибка+-0.5С то мощность = И состовляющей
}
else//иначе
{
float e;
e=(ust-temp);//вычисление ошибки регулирования
// расчет выходной мощности:
p=(65.0*e);//расчет пропорциональной состовляющей
if (p<0.0)//мощность не может быть отрицательной
{
p=0.0;//ограничение P
}
i=(i+(e*0.014));//расчет интегральной составляющей = тепловым потерям
if (i>100.0)//мощность не может быть больше 100%
{
i=100.0;//ограничение I
}
if (i<-100.0)
{
i=-50.0;//ограничение I
}
//расчет выходной мощности
zad=p+i;
}
//корректировка при отклонении температуры более чем на +-2С
//для быстрого выхода на уставку
if (temp<(ust-8.5))//если темп < уст на 2С
{
zad=100;//то мощность 100%
i=0;
}
if (temp>(ust+8.5))//если темп > уст на 2С
{
zad=0;//то мощность 0%
i=0;
}
}
//корректировка мощности
byte pwr(int zad, int correct)
{
int res = zad+correct;
if(res>100){
return 100;
}
if(res<0 || zad == 0){
return 0;
}
return res;
}
Надо сравнить функцию ПИ регулятора с кодом из поста #75 (самая последняя версия), там помоему глюки были но я их исправил.
Выложу картинки попозже, а насчёт кода со вторым датчиком, то почему, мощность одинаковая, если допустим баки хоть и одинаковые, но допустим тот стартует с 30 градусов, а другой с 20 градусов ну если их не равномерно охладить, да и разница в ТЭНах в 3-4 градуса всё равно есть, хотя и мультиметры с термопарами около 2градусов погрешность, причём разница изначально в мультиметрах 2 градуса, а мы будем одинаковую мощность давать, или я что-то не пойму?
if(currentMillis-prePIctl_time>=power_time){//если подошло время расчитать мощность
Насчёт кода для применения двух датчиков и двух выходов разных, пост 64, а как выдать мощность на разные выхода, после получения показания с двух датчиков, не пойму.
Есть секция получения температуры
if(currentMillis-preTempMillis>=t_time){
temp = getTempLM35(termo);
temp2 = getTempLM35(termo2);//добавили второй датчик
preTempMillis=currentMillis;//сброс таймера замера температуры
}
Есть секция расчета мощности по ПИ закону
if(currentMillis-prePIctl_time>=power_time){//если подошло время расчитать мощность
zad=PIctl(temp, ust);//расчет мощности для первой емкости
zad2=PIctl(temp2, ust);//расчет мощности для второй емкости
prePIctl_time=currentMillis;//сброс таймера расчета мощности
//Вывод в порт температуры и мощности
serialPrint();
}
Есть секция управления нагрузкой
if (currentMillis>5000){//разрешаем управление нагрузкой через 3 сек после включения устройства
outten.blink(t_pwm, ((t_pwm)/100)*zad);//управление теном 1
outten2.blink(t_pwm, ((t_pwm)/100)*zad2);//управление теном 2
ind=outten;
}
//тут ничего не меняем
И по анологии хоть 10 добавляйте, но если емкости разные, то придется переписать функцию расчета ПИ чтобы она принимала коэффициенты для каждой емкости свои.
Это изменения для последнего кода из поста #75 для работы с двумя каналами измерения/регулирования.
Баки одинаковые но охлаждаются возможно по разному, или даже одинаково но один куллер заклинет, да и говорю же что разница в ТЭНах хоть и не большая есть, а я просто не увидел секция управления нагрузкой, спасибо, просто и думаю зачем же два датчика если включать ТЭНы как и раньше, теперь увидел, спасибо.
Баки одинаковые но охлаждаются возможно по разному, или даже одинаково но один куллер заклинет, да и говорю же что разница в ТЭНах хоть и не большая есть, а я просто не увидел секция управления нагрузкой, спасибо, просто и думаю зачем же два датчика если включать ТЭНы как и раньше, теперь увидел, спасибо.
Вот эта строчка формирует управляющие сигналы на симистор, в неё мы передаем период ШИМ - 1000мс (1с) и задание в %, для того чтобы % перевести в длину управляющего импульса мы период делим на 100% и получаем продолжительность импульса для 1-го %, а затем умножаем его на zad что нам дает в результате продолжительность управляющего воздействия на симистор для получения расчетной мощности zad.
Ну а если бы ёмкости были разные то можно же греть их на разные уставки и всё
Ну если Вам для процесса нужно поддерживать точную температуру, зачем уставки менять? Разные так разные регулятор для каждой свою мощность расчитает при одной уставке.
Если баки разные(конкретно допустим обьём у них в два раза отличается) их и греть допустим нужно для разной температуры, так как их емкость разная, и что бы выделилось одинаковое количество пара допустим. то и нужно к разным температурам. Это так теоретически. Вы конечно правы, для моего случая да допустим разница не большая и мощность ПИ-регулятор подберёт на каждый выходной канал свою в соответствии от входных сигналов. А вообще пока что использую первый вариант и он меня устраивает, а там и этот на два датчика может пригодится. Огромное спасибо за помощь
//функция расчета мощности по ПИ закону регулирования
byte PIctl(float temp, float ust)
{
byte zad=0;
static float i=0;
if(temp>(ust-0.5)&&temp<(ust+0.5))//зона нечувствительности +-0,5C
{
zad=i;
}
else//иначе
{
float e, p;
e=(ust-temp);//вычисление ошибки регулирования
// расчет выходной мощности
p=(1.5*e);//расчет пропорциональной состовляющей
if (p<0.0)//мощность не может быть отрицательной
{
p=0.0;//ограничение P
}
i=(i+(e*0.014));//расчет интегральной составляющей = тепловым потерям
if (i>100.0)//мощность не может быть больше 100%
{
i=100.0;//ограничение I
}
if (i<-100.0)
{
i=-50.0;//ограничение I
}
//расчет выходной мощности
zad=byte(p+i);
if(zad>100){zad = 100;}
if(zad<0){zad = 0;}
//для быстрого выхода на уставку
if (temp<(ust-8.5))//если темп < уст на 8,5С
{
zad=100;//то мощность 100%
i=0;
}
if (temp>(ust+3))//если темп > уст на 3С
{
zad=0;//то мощность 0%
i=0;
}
}
return zad;
}
Долго из за не оптимальных настроек коэффициентов. И варийантов не много, или быстро с перерегулированием или дольше но без перерегулирования, выбирается под свои нужды.
Про знаки вопросов - (условие)? если истина : если лож ;
Все будет работатть, только ж реле бери 15А и нужное напряжение коммутации, или ддва реле в параллель контакты, или у одного если есть две пары контактов по 10А в параллель.
Вот эта строчка формирует управляющие сигналы на симистор, в неё мы передаем период ШИМ - 1000мс (1с) и задание в %, для того чтобы % перевести в длину управляющего импульса мы период делим на 100% и получаем продолжительность импульса для 1-го %, а затем умножаем его на zad что нам дает в результате продолжительность управляющего воздействия на симистор для получения расчетной мощности zad.
Вот эта строчка формирует управляющие сигналы на симистор, в неё мы передаем период ШИМ - 1000мс (1с) и задание в %, для того чтобы % перевести в длину управляющего импульса мы период делим на 100% и получаем продолжительность импульса для 1-го %, а затем умножаем его на zad что нам дает в результате продолжительность управляющего воздействия на симистор для получения расчетной мощности zad.
Здравствуйте yul-i-an
Пришла плата и остальные детали
Пробую ваш код, если можно глянете правильно ли я все сделал.
[code]
#include <DigOut.h>//подключаем библиотеку выходов yadi.sk/d/NM4S6HmFrTRu6
#define t_time 1000//период опроса температуры
#define power_time 1000//период расчета мощности
DigOut outten(9);//инициализация цифровых выходов на тен
unsigned long time;//интервал замера температуры
byte zad=0;//задание мощности ТЭНа1
float temp=0.0;//текущее значение температуры
float pre_temp=0.0;//предыдущее значение температуры
unsigned long preTempMillis=0;//для опроса температуры
unsigned long prePIctl_time=0;//для расчета мощности
float ust=0;//уставка
#define t_pwm 1000//период медленного ШИМ в мс
#define ust4 85//температура средний режим=100
///------------------------ temp
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 2//вход основного датчика температуры
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature datchik(&oneWire);
//-----------------------------------------
//функция расчета мощности по ПИ закону регулирования
//расчет мощности по ПИ закону регулирования
#define kP 6//коэффициент пропорциональности
#define p_min 0.0//минимум П составляющей - не < 0
#define p_max 100.0//максимум П составляющей - не > 100
#define kI 0.025//коэффициент интегрирования
#define i_min 0.0//минимум И составляющей
#define i_max 30.0//максимум И составляющей
#define d_ctl 1.5//зона пропорциональности ust-d_ctl
#define out_min 0//минимальный выходной %
#define out_max 100//максимальный выходной %
byte PIctl(float temp, uint8_t ust)//возвращает необходимую мощность
{
uint8_t out=0;//uint8_t
static float i=0;
float e, p;
e=(ust-temp);//ошибка регулирования
//расчет p
p=(temp<ust-d_ctl)?p_max:(temp>ust)?p_min:(kP*e);
//расчет i
i=(i<i_min)?i_min:(i>i_max)?i_max:i+(kI*e);
out=(p+i<out_min)?out_min:(p+i>out_max)?out_max:p+i;
return out;
}
//вывод в монитор для отладки
void serialPrint()
{
Serial.print(temp);
Serial.println("-T ");
Serial.print(zad);
Serial.print("-% ");
}
void setup() {
datchik.begin();
Serial.begin (9600);
}
void loop() {
ust=ust4;//уставка
unsigned long currentMillis=millis();
if(currentMillis-preTempMillis>=t_time){
temp=datchik.getTempCByIndex(0);//получаем температуру
preTempMillis=currentMillis;//сброс таймера замера температуры
}
if(currentMillis-prePIctl_time>=power_time){//если подошло время расчитать мощность
zad=PIctl(temp, ust);//расчет мощности
prePIctl_time=currentMillis;//сброс таймера расчета мощности
//Вывод в порт температуры и мощности
serialPrint();
}
if (currentMillis>5000){//разрешаем управление нагрузкой через 3 сек после включения устройства
outten.lpwm(t_pwm, zad);//управление теном 1
//ind=outten;// ?
}
}//END loop
[/code]
При компиляции скетча ругался на ind=outten; убрал вроде все пошло.
Также заменил как вы писали outten.lpwm(t_pwm, zad);
Вопрос, нужную мне температуру я задаю переменной zad ?
Не могу понять для чего #define ust4 85//температура средний режим, что значит средний режим?
Для чего две ust и ust4 если всеровно ust=ust4;
Ваш вариант ещё не пробовал, загвоздка скорее в том что я после нагрева охлаждаю один бак и частично второй, вот и получается на тот на который мало воздуха после во время охлаждения попадает вот он и нагревается больше, так как у него начальная точка и у бака выше чем с той стороны где я дую вентилятором, у меня есть два куллера но они не усьановлены, а чтобы было быстрее дую на них большим вентилятором.
Кстати, а если всё таки решу два датчика установить то, так пойдёт отслеживать?:
Попробовал ваш код последний, на отдельной никуда не подпаяной ардуино мега, так замыкаю А0 на землю, в мониторе последовательного порта 0 градусов и 100% мощности, вот только на выводе 9 и 12 меги ничего нету, зато на выводе 10 появляется лог.1(ну так как 100% мощности), причём здесь вывод 10, не пойму, перепроверил 100 раз.
Я понял в чем проблемма, класс DigOut в погоне за скоростью под давлением местных прогеров я начал переделывать на прямое управление портами ... вобщем на мега он работать в таком виде не будет правильно. Я попозже вам ссылку выложу на этотже класс который со всеми дуинами работает. Просто замените его и все заработает, даже код править не нужно.
Перекачайте класс DigOut
Добрый вечер. Я только начинаю изучение ардуион и наткнулся на эту тему. Сразу всплыла одна идея, которая меня волнует. Есть у меня надаче ящик с ТЭНом, порядка 1500 ватт. Есть регулятор, который держит определнную температуру в нем, за счет замыкания\размыкания реле. Так же в регуляторе есть аналоговый выход 0(4)-20 мА с функцией ПИДрегулипрвания. Так вот, как бы мне сделать плавное регулирование ТЭНами?? Я хочу чтоб при температуре близкой к уставке, потребление электричесва было минимальное. Я хочу услышать от Вас все плюсы и минусы такого подключения, есть смысл в таком регулировании?? И можно ли реализовать проект на ардуине без промышленного регулятора?? Так же у меня есть регулятор мощьностидля ТЭНа, который управляется переменным резистором, ну не вешать же на него сервопривод =))) Вообщем пока у меня тьма в котелке. Жду от вас помощи, пока только в теории.
А последний класс DigOut работает только с Дунами или с УНо и другими на меге 328 тоже, или для меги 328 предыдущий класс, а для меги этот?
andreyR, с реле не очень хорошо вдруг что можно оптосимистор с симистором поставить, 4-20мА, тебе не к чему, это универсальный КИПовский сигнал
Вот тема была на форуме как измерить 4-20мА. Я так понимаю это будет 0-100% выходной мощности.
В начале темы я ссылки выкладывал, ПИ регулятор вроде я себе на дачу делал в прошлом году. Всю зиму отработал без проблемм +-0.3С.
Если хотите полностью на Ардуино собрать, просто возмите код из этой темы.
Из кода нужно будет только второй тен выбросить и всё.
А переменный резистор из Вашего блока управления мощностью можно заменить на чтото типа этого.
А последний класс DigOut работает только с Дунами или с УНо и другими на меге 328 тоже, или для меги 328 предыдущий класс, а для меги этот?
Последний работает на всех дуинах поддерживаемых средой (но он медленней - скорость как у стандартной функции digitalWrite()).
В функции корректировки мощности закралась ошибочка.
Исправил, замените на это
В этой функции осталась еще ошибка, как исправлю выложу.
Предложу использовать встроенный светодиод для индикации выходной мощности.
Нужно его прописать вначале
И в коде где выдаем мощность
Наверное окончательный варийант
Спасибо yul-i-an, поисправляю у себя и проверю, на чистой меге, хотя проблема у меня была в том что один бак охлаждаю, а второй частично и разница была в стартовых температурах, а так как мощность одинаковая даётся в одинаковый промежуток времени то они догнать по температуре друг друга не могли)
Ваш вариант ещё не пробовал, загвоздка скорее в том что я после нагрева охлаждаю один бак и частично второй, вот и получается на тот на который мало воздуха после во время охлаждения попадает вот он и нагревается больше, так как у него начальная точка и у бака выше чем с той стороны где я дую вентилятором, у меня есть два куллера но они не усьановлены, а чтобы было быстрее дую на них большим вентилятором.
Кстати, а если всё таки решу два датчика установить то, так пойдёт отслеживать?:
Чтобы установить второй датчик температуры достаточно будет прописать его тут
Но ввиду усложнения код лучше написать функцию в которую передовать аналоговых вход на котором сидит датчик, а она вернет отфильтрованную температуру
например
тогда вместо
будет
проблема у меня была в том что один бак охлаждаю, а второй частично и разница была в стартовых температурах, а так как мощность одинаковая даётся в одинаковый промежуток времени то они догнать по температуре друг друга не могли)
В таком случае обязательно применение второрого датчика, темболее что это не грозит большими затратами и усложнением кода. И часть кода которая отвечает за корректировку мощности выкинуть как ненужный костыль.
yul-i-an, а какой симулятор для ардуино вы используете?
Симулятор использую Proteus 7.7
Ну как Ваш аппарат, заработал?
Я тут в симуляторе пыряю алгоритм, так вот если заменить
на
то количество полупериодов сети прошедших в нагрузку получается пропорционально мощности (7% - 7 полупериодов).
Вот графики при мощности в 10%
Желтый - напряжение в нагрузку
Зеленый - управление на симистр
Но особой разницы в работе на глаз не заметите.
Может в классе DigOut переименовать blink в Lpwm думаю? А то будут думать что он только для мигания годиться.
Аппарат работает, разница в ТЭНах есть около 3-4 градусов но не критично, вообще разница около 7-8 градусов, но с учётом погрешности китайских мультиметров между ними разница порядка 3-4 градусов. Пока работаю на первом варианте.
Снимал реальные осциллограмы с ваших кодов, ну потом расскажу
Про осцилограммы очень интересно, буду ждать.
А первый варийант это какой, из какого поста?
Извиняюсь занят был, освобожусь скину благодарность, первый вариант это:
Для первого варианта осциллограма выглядит так как всё время лог. 1 стоит, ну это понятно это же период ШИМ =1с. ( развёртка на осциле 50мс, осцил Хамелион, показания снимал задавая на вход АЦП вместо температурного датчика около 90-95% от необходимого входного для АЦП(от уставки)), так вот прямоугольные импульсы появляются как - то хаотично через разные промежутки времени , бывают как будтя два вместе соединяются, так то всё работает на симисторе, в моём устройстве, может это так осцил рисует.
С этим кодом(который на два выходы с коректировкой по мощности) всё по другому при том же периоде ШИМ=1с., прямоугольные импульсы появляются через одинаковые промежутки времени, и прямоугольные импульсы друг на друга не накладываются, в реальной работе не проверял. Праметры осцыла и задачи входного сигнала на АЦП те же. Коректировка мощности на другой канал работает.
А вот такой код тоже на два выхода с корректировкой, в мониторе последовательного порта показывает 200%, на выходе только как я понимаю период ШИМ, а прямоугольные импульсы не появляются
Насчёт кода для применения двух датчиков и двух выходов разных, пост 64, а как выдать мощность на разные выхода, после получения показания с двух датчиков, не пойму.
Ну второй код мне кажеться получился более читаемым и прозрачным. А картинки с осцилогрофа какнибудь можете выложить, для второго кода?
Я на выходных этот код мучал, мне кажеться что он полностью рабочий
Единственное останется настроить ПИ регулятор и если всётаки две разные емкости добавить второй датчик температуры, темболее что теперь это не составит труда.
А вот такой код тоже на два выхода с корректировкой, в мониторе последовательного порта показывает 200%, на выходе только как я понимаю период ШИМ, а прямоугольные импульсы не появляются
Надо сравнить функцию ПИ регулятора с кодом из поста #75 (самая последняя версия), там помоему глюки были но я их исправил.
Выложу картинки попозже, а насчёт кода со вторым датчиком, то почему, мощность одинаковая, если допустим баки хоть и одинаковые, но допустим тот стартует с 30 градусов, а другой с 20 градусов ну если их не равномерно охладить, да и разница в ТЭНах в 3-4 градуса всё равно есть, хотя и мультиметры с термопарами около 2градусов погрешность, причём разница изначально в мультиметрах 2 градуса, а мы будем одинаковую мощность давать, или я что-то не пойму?
if
(currentMillis-prePIctl_time>=power_time){
//если подошло время расчитать мощность
033
zad=PIctl(temp, ust);
//расчет мощности
034
//если два датчика то zad2= PIctl(temp2, ust);
035
zad2=zad;
//мощность одинаковая
Насчёт кода для применения двух датчиков и двух выходов разных, пост 64, а как выдать мощность на разные выхода, после получения показания с двух датчиков, не пойму.
Есть секция получения температуры
Есть секция расчета мощности по ПИ закону
Есть секция управления нагрузкой
И по анологии хоть 10 добавляйте, но если емкости разные, то придется переписать функцию расчета ПИ чтобы она принимала коэффициенты для каждой емкости свои.
Это изменения для последнего кода из поста #75 для работы с двумя каналами измерения/регулирования.
Баки одинаковые но охлаждаются возможно по разному, или даже одинаково но один куллер заклинет, да и говорю же что разница в ТЭНах хоть и не большая есть, а я просто не увидел секция управления нагрузкой, спасибо, просто и думаю зачем же два датчика если включать ТЭНы как и раньше, теперь увидел, спасибо.
Ну а если бы ёмкости были разные то можно же греть их на разные уставки и всё
Баки одинаковые но охлаждаются возможно по разному, или даже одинаково но один куллер заклинет, да и говорю же что разница в ТЭНах хоть и не большая есть, а я просто не увидел секция управления нагрузкой, спасибо, просто и думаю зачем же два датчика если включать ТЭНы как и раньше, теперь увидел, спасибо.
Вот эта строчка формирует управляющие сигналы на симистор, в неё мы передаем период ШИМ - 1000мс (1с) и задание в %, для того чтобы % перевести в длину управляющего импульса мы период делим на 100% и получаем продолжительность импульса для 1-го %, а затем умножаем его на zad что нам дает в результате продолжительность управляющего воздействия на симистор для получения расчетной мощности zad.
Ну а если бы ёмкости были разные то можно же греть их на разные уставки и всё
Ну если Вам для процесса нужно поддерживать точную температуру, зачем уставки менять? Разные так разные регулятор для каждой свою мощность расчитает при одной уставке.
Если баки разные(конкретно допустим обьём у них в два раза отличается) их и греть допустим нужно для разной температуры, так как их емкость разная, и что бы выделилось одинаковое количество пара допустим. то и нужно к разным температурам. Это так теоретически. Вы конечно правы, для моего случая да допустим разница не большая и мощность ПИ-регулятор подберёт на каждый выходной канал свою в соответствии от входных сигналов. А вообще пока что использую первый вариант и он меня устраивает, а там и этот на два датчика может пригодится. Огромное спасибо за помощь
Вот рабочая версия функции расчета мощности
Если всё еще актуально?!
Переписал ПИ регулятор. (более удобная настройка)
Спасибо, как - нибудь опробую.
Еще к теме, последняя версия функции ПИ регулятора
График выхода на уставку с 36 до 41С в течении 5-7 минут, точно не засекал. Ну и конечно всё зависит от kI и kP коэффициентов.
Синяя линия - текущая температура (С)
Красная - уставка (С)
Желтая - мощность (%)
Зеленая - ошибка регулирования (С)
Сиреневая - П составляющая (%)
Голубая - И составляющая (%)
Синяя - температура
Красная - уставка
Желтая - мощность
Я за вами не успеваю, сейчас занят, не когда заняться переработкой инфы от вас, и скинуть благодарность, как только так сразу
График выхода на уставку с 36 до 41С в течении 5-7 минут
А почему так долго? И что в вашем коде и вообще в коде Ардуино ИДЕ означают вопросительные знаки?
Долго из за не оптимальных настроек коэффициентов. И варийантов не много, или быстро с перерегулированием или дольше но без перерегулирования, выбирается под свои нужды.
Про знаки вопросов - (условие)? если истина : если лож ;
И что в вашем коде и вообще в коде Ардуино ИДЕ означают вопросительные знаки?
https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D1%80%D0%BD%D0%B0%D1%80%D0%BD...
https://habrahabr.ru/post/205848/
http://cppstudio.com/post/304/
http://purecodecpp.com/archives/554
Здравствуйте yul-i-an
Заинтересовал ваш код
интересует будет ли он работоспособен для arduino uno + ssr реле + тэн 2кВт(от эл.плиты)
хочу это все приспособить для коптильни
ps (arduino uno + ssr реле) заказал должно скоро прийти
Все будет работатть, только ж реле бери 15А и нужное напряжение коммутации, или ддва реле в параллель контакты, или у одного если есть две пары контактов по 10А в параллель.
Здравствуйте yul-i-an
Заинтересовал ваш код
интересует будет ли он работоспособен для arduino uno + ssr реле + тэн 2кВт(от эл.плиты)
хочу это все приспособить для коптильни
ps (arduino uno + ssr реле) заказал должно скоро прийти
Будет. Для этого и писалось.
Вот эта строчка формирует управляющие сигналы на симистор, в неё мы передаем период ШИМ - 1000мс (1с) и задание в %, для того чтобы % перевести в длину управляющего импульса мы период делим на 100% и получаем продолжительность импульса для 1-го %, а затем умножаем его на zad что нам дает в результате продолжительность управляющего воздействия на симистор для получения расчетной мощности zad.
Ругается на эту строчку, на blink
Вот эта строчка формирует управляющие сигналы на симистор, в неё мы передаем период ШИМ - 1000мс (1с) и задание в %, для того чтобы % перевести в длину управляющего импульса мы период делим на 100% и получаем продолжительность импульса для 1-го %, а затем умножаем его на zad что нам дает в результате продолжительность управляющего воздействия на симистор для получения расчетной мощности zad.
Ругается на эту строчку, на blink
В Классе DigOut blink был заменен на lpwm
Спасибо, попробую.
Здравствуйте yul-i-an
Пришла плата и остальные детали
Пробую ваш код, если можно глянете правильно ли я все сделал.
При компиляции скетча ругался на ind=outten; убрал вроде все пошло.
Также заменил как вы писали outten.lpwm(t_pwm, zad);
Вопрос, нужную мне температуру я задаю переменной zad ?
Не могу понять для чего #define ust4 85//температура средний режим, что значит средний режим?
Для чего две ust и ust4 если всеровно ust=ust4;
Спасибо.
ust - это уставка температуры
ust4 - можете выбросить
необходимую температуру просто передовайте в переменную ust (ust=54; например) или любым иным способом.
чтобы работал индикатор на 13 пине (ind) нужно после строки
добавить
и раскоментировать
Встроеный светодиод на 13 пине отображает состояние выхода на тен.
Спасибо. Попробую. Блин Ind пропустил... А так на ваш взгляд всё правильно?
Номер тел или карты для возногрождения?