Очередной термостат
- Войдите на сайт для отправки комментариев
Понадобилось регулировать температуру с очень инерционной средой, при том что включать нагреватель не желательно чаще чем раз в минуту ( его включает пневматический контактор, а ресурс не резиновый).
теплоемкость отопителя очень велика, так после выключения отопителя температура еще несколько минут растет, и соответственно после включения несколько минут падает.
ПИД отпадает т.к (а неполучилось, в системе постоянно меняется скорость вентиляции, и нагрев стен помещения)
решил попробовать такой алгоритм:
До температуры 20 нарев идет постоянно
затем если между двумя измерениями (1 мин ) температура растет то отопитель выключается, если падает включается
при температуре выше 22 нагрев отключается
Готовых решений на 5в ненашел, поэтому творю))
пока работу реле от термистора проверил на протеусе, работу дисплея TM1637 вживую на макетке
развел плату. Питание NANO предусматривается только от USB 2А, включение возможно только через реле.
Посмотрите в чем есть просчеты? или может есть какие предложения? пока снова по 5 раз плату травить не пришлось
#include "TM1637.h" /// библиотека дисплея #define CLK 3//pins definitions for the module and can be changed to other ports #define DIO 2 TM1637 disp(CLK, DIO); unsigned long zzz = 0; unsigned long yyy = 0; unsigned long zzz1 = 0; unsigned long yyy1 = 0; unsigned long zzz2 = 0; unsigned long yyy2 = 0; unsigned long zzz3 = 0; unsigned long yyy3 = 0; boolean flag3 = 0; boolean flag1 = 0; boolean flag2 = 0; boolean flag11 = 0; boolean flag12 = 0; float ind = 0; float tdisp = 0; int tempres = 0; int deltaT = 0; int temp1 = 0; double voltage = 0; double r1 = 0; double TempRes = 0; // всякие разнве переменные int relay = 6; // выход на реле int buttonUP = 5; // вход клвиши вверх int buttonDOWN = 4; // вход клавиши вниз int ntc = A0; // вход с термистора int Tust = 200; // заданная температура (уставки) int klav = 600; // зажатия кнопки чтобы каждые Х мс добавлялось +10 int diap = 20; // диапазон где идет регулирование по дельте 2 градуса "20/10" int dreb = 30; // значение антидребезга = 30 мс unsigned int Trelay = 15000; // значение задержки времени между срабатываниями реле в мс double Vin = 5.0; // напряжение void setup() { // Serial.begin(9600); pinMode(relay, OUTPUT); digitalWrite(relay, LOW); pinMode(buttonUP, INPUT); pinMode(buttonDOWN, INPUT); digitalWrite(buttonUP, HIGH); digitalWrite(buttonDOWN, HIGH); disp.set(BRIGHT_TYPICAL);//BRIGHT_TYPICAL = 2,BRIGHT_DARKEST = 0,BRIGHTEST = 7; //настройки дисплея disp.init(D4056A);//D4056A is the type of the module } void loop() { button(); // опрос клавиш // Serial.println(tempres); // Serial.println(Tust); // Serial.println("-----------"); yyy3 = millis() - zzz3; if (yyy3 > 500) { readtemp(); // опрос датчика температуры // вывод значений текущая:установленная температура, вывод раз в 500мс zzz3 = millis(); tdisp = tempres / 10; tdisp = tdisp * 100; tdisp = tdisp + Tust; if ( flag3 == 1) { // если реле включено, тогда горит разделитель ind = tdisp / 100; disp.display(ind); } else { disp.display(tdisp); } } yyy = millis() - zzz; if (yyy > Trelay) { //если прошло более Х mc, тогда переход на void relay() zzz = millis(); relay1(); } } //------------------------------------------------------------------------------------------------------------------------------------------------------------------- void button() //опрос клавиш { zzz1 = millis() - yyy1; if (zzz1 > dreb) { flag2 = 0; // антидребезг } if (flag2 == 0) { if (digitalRead( buttonUP) == LOW && flag1 == 0) { Tust = Tust + 10; // добавление +10 c последующей блокировкой набора yyy1 = millis(); flag1 = 1; flag2 = 1; } if (zzz1 > klav) { if (digitalRead( buttonUP) == LOW) { Tust = Tust + 10; //обработка зажатия кнопки чтобы каждые Х мс добавлялось +10 yyy1 = millis(); } } if (digitalRead( buttonUP) == HIGH) { flag1 = 0; } } zzz2 = millis() - yyy2; if (zzz2 > dreb) { flag12 = 0; // антидребезг } if (flag12 == 0) { if (digitalRead( buttonDOWN) == LOW && flag11 == 0) { Tust = Tust - 10; // добавление +10 c последующей блокировкой набора yyy2 = millis(); flag11 = 1; flag12 = 1; } if (zzz2 > klav) { if (digitalRead( buttonDOWN) == LOW) { Tust = Tust - 10; //обработка зажатия кнопки чтобы каждые Х мс добавлялось +10 yyy2 = millis(); } } if (digitalRead( buttonDOWN) == HIGH) { flag11 = 0; } } } //----------------------------------------------------------------------------------------------------------------------------------------------------------------------- void relay1() { deltaT = tempres - temp1; { if (tempres >= Tust) { //если температура выше уставки выключаю реле digitalWrite(relay, LOW); flag3 = 0; } else { // если температура ниже температуры уставки на 2 градуса реле постоянно включено if (tempres < Tust - diap) { // если дельта температуры положительная и температура в пределах ноль -2 градуса от уставки реле выключается и наоборот digitalWrite(relay, HIGH); flag3 = 1; } else { if (deltaT <= 0) { digitalWrite(relay, HIGH); flag3 = 1; } else { digitalWrite(relay, LOW); flag3 = 0; } } } } temp1 = tempres; } //--------------------------------------------------------------------------------------------------------------------------------------------------------------- void readtemp() // расчет температуры по формуле Стейнхарта — Харта { voltage = analogRead(ntc) * Vin / 1023; r1 = voltage * 100000.0 / (Vin - voltage); // 100 кОм - резистор моста TempRes = (1.0 / (1.0 / (3950.0) * log(r1 / 100000.0) + 1.0 / (273.0 + 25.0))) - 273.0; // двнные NTC tempres = TempRes * 10; }
R1 1-2K, с базы на землю 10К и кнопки подпереть 4.7-10К.
включен внутренний подтяг, а зачем резистор на транзистор? на базу всегда либо - либо + приходить будет
и то и другое для помехоустойчивости. (Внутренний подтяг на 100 кОм - многовато).
включен внутренний подтяг, а зачем резистор на транзистор? на базу всегда либо - либо + приходить будет
А хрена там в момент перезагрузки. Тоже так думал, теперь бузер воет (сцука).
А хрена там в момент перезагрузки. Тоже так думал, теперь бузер воет (сцука).
как-то непонял фразы?
что такое бузер?
Недавно собирал себе подобный девайс для электрокаменки.
Уважаемый bwn дело говорит. У него ладно бузер..., у меня пускатель подскакивает.
Еще замечание из личного опыта - параллельно контактам реле поставить РЦ цепочку (снабер).
У меня без неё при комутации пускателя (размыкании) контроллер подвисал.
А еще при питании схемы от зарядки мобильника 1200мА/ч 5В переодически отваливалось самопроизвольно реле (непонятно почему но после этого его клинило в разомкнутом состоянии), после чего оно безжалостно было заменено на симистор.
Вот схема
Печатку не разрабатывал, собрал всё навесом.
evgta, кнопки SW1 и SW2 правильнее будет замыкать на массу через резисторы в 100 - 300 Ом. Причины подробно изложены в прикрепленной теме "Ардуино для новичков - работа с кнопками" в разделе Программирование
Решил зажать 2 резистора)) подумал что длинна дорожек к кнопкам короткая и индукция в них наводится будет слабая и хватит внутреннего подтяга, но коль советуете, еще думаю от плюса реле к земле поставить супрессор на 5V1. еще как вариант к базе транзистора супрессор повесить чтобы выход наны прикрыть. оптопару как-то невижу смысл ставить, т.к питание с одного места,
Симистр не воткнуть, т.к постоянка 55В с кучей помех, и мосфет тоже неполучится, там на этих 55В куча контакторов с токами 2-5А живут
А хрена там в момент перезагрузки. Тоже так думал, теперь бузер воет (сцука).
как-то непонял фразы?
что такое бузер?
Активная пищалка через транзисторный ключ. При перезагрузке и до сетапа пины в высокоимпедансном состоянии, и что там антенна наловит.
включен внутренний подтяг, а зачем резистор на транзистор? на базу всегда либо - либо + приходить будет
При перезагрузке контроллера пины, хоть и на короткий момент, но переводятся в 3 состояние, а в нем на базу будет приходить только потенциал Святого Эфира в твоей точке пространства. Что он там поймает - неизвестно, возможно файер шоу. Такшто, запирающий резистор в базу - обязательно надо ставить.
Решил зажать 2 резистора)) подумал что длинна дорожек к кнопкам короткая и индукция в них наводится будет слабая и хватит внутреннего подтяга,
Индукция тут не при чем. никакой внутренний подтяг не поможет, если на выход, подключенный к нажатой кнопке, случайно подать HIGH