Ранее на странице http://rcl-radio.ru/?p=92577 описывался пример создания простого терморегулятора на базе ESP32. Управление терморегулятором осуществляется по сети Bluetooth, через Android приложение. На этой странице будет рассмотрен аналогичный проект но с небольшими доработками, помимо ручного регулирования температуры добавлена возможность установки температуры регулирования по времени.
Текущее время ESP32 получает от NTP сервера через Интернет. Используется 4-е временных отметки, переключать которые можно кнопками TIME1, TIME2, TIME3 и TIME4. При переключении временных отметок показывается установленное время для текущей отметки и температура регулирования. При установки времени регулирования необходимо соблюдать временную последовательность, первая отметка начало суток, четвертая конец суток. Например, если необходимо установить температуру регулирования 22 °С с 22:30 до 6:00, а с 6:00 поднять температуру до 24 °С, то установите первую отметку на 6:00 > 24, а четвертую на 23:30 > 22. Так же первая отметка должна быть по времени меньше второй, вторая меньше третей, третья меньше четвертой.
Как показано на примере, в 23:30 установится температура в 24 °С и до 6:00 меняться не будет. В 6:00 температура повысится до 25 °С и до 15:30 меняться не будет. Далее в 15:30 температура установится на 27 °С и до 20:00 меняться не будет. В 20:00 температура установиться на 29 °С и до 23:30 меняться не будет.
Для переключения между ручным регулированием температуры и регулированием температуры по времени используется кнопка SET.
Текущий режим, все временные отметки и заданные температуры регулирования сохраняются в энергонезависимой памяти.
Перед загрузкой скетча рекомендую ознакомится со статьей — ESP32 DevKit v1 Wi-Fi Bluetooth ESP32-WROOM-32 (Arduino IDE).
Перед прошивкой в скетч добавьте параметры Вашей Wi-Fi сети:
const char* ssid = «Имя_сети»;
const char* password = «Пароль_сети»;
Так же укажите временной сдвиг в секундах от UTC:
NTPClient timeClient(ntpUDP, «pool.ntp.org», 21600,3600123);// 21600 — временной сдвиг в секундах от UTC (6 часов)
#include <BluetoothSerial.h> // Входит в состав Arduino IDE #include <OneWire.h> // Входит в состав Arduino IDE #include <EEPROM.h> // Входит в состав Arduino IDE #include <WiFi.h> #include <NTPClient.h> // http://rcl-radio.ru/wp-content/uploads/2019/11/ntpclientmaster.zip #include <WiFiUdp.h> OneWire ds(15); // Вход датчика D15 BluetoothSerial BL; const char* ssid = "Имя_сети"; const char* password = "Пароль_сети"; WiFiUDP ntpUDP; ///////////////// https://www.ntppool.org/zone/@ - другие сервера ///////////////////////////// ///////////////// для России - ru.pool.ntp.org ////////////////////////////////////////////////// NTPClient timeClient(ntpUDP, "pool.ntp.org", 21600,3600123);// 21600 - временной сдвиг в секундах от UTC float temper; int w,reg,buf[2],i,wb,rele,k,hh,mm,ss,h_reg,m_reg,tim=1,rty=1,t1,t2,t3,t4,reg_t,sett; int h1,m1,h2,m2,h3,m3,h4,m4; unsigned long buff,times,times1,times2; const int gis = 1; // int гистерезис String BT_CALLBACK = ""; void setup() { Serial.begin(9600); EEPROM.begin(100); // под EEPROM выделить 100 ячеек памяти WiFi.begin(ssid, password); while ( WiFi.status() != WL_CONNECTED ){delay (10);Serial.print ( "." );timeClient.begin();} BL.register_callback(BTCallback); BL.begin("ESP32",false); // Имя Вашего устройства Bluetooth BL.setTimeout(100); Serial.println("Bluetooth OK"); pinMode (2, OUTPUT); // LED pinMode (22,OUTPUT); // выход рег. реле D22 reg=EEPROM.read(0);h1=EEPROM.read(1);m1=EEPROM.read(2);h2=EEPROM.read(3);m2=EEPROM.read(4); h3=EEPROM.read(5);m3=EEPROM.read(6);h4=EEPROM.read(7);m4=EEPROM.read(8); t1=EEPROM.read(9);t2=EEPROM.read(10);t3=EEPROM.read(11);t4=EEPROM.read(12);sett=EEPROM.read(13); if(sett>1){sett=0;} } void loop() { /////// ПРИЕМ ДАННЫХ ///////////////////////// if(BL.available()){ for (i=0;i<1;i++) { buf[0] = BL.parseInt(); buf[1] = BL.parseInt();} times=millis();times=millis();wb=1;w=1; } ///////////// обработка команд /////////////////// if((buf[0]>10&&wb==1)||rty==1){ wb=0;rty=0; if(buf[0]==102){reg++;if(reg>50){reg=50;}} if(buf[0]==101){reg--;if(reg<10){reg=10;}} if(buf[0]==103&&sett==0){buf[0]=0;sett=1;} if(buf[0]==103&&sett==1){buf[0]=0;sett=0;} if(buf[0]==110){tim=1;} if(buf[0]==120){tim=2;} if(buf[0]==130){tim=3;} if(buf[0]==140){tim=4;} switch(tim){ case 1: h_reg=h1;m_reg=m1;reg_t=t1;break; case 2: h_reg=h2;m_reg=m2;reg_t=t2;break; case 3: h_reg=h3;m_reg=m3;reg_t=t3;break; case 4: h_reg=h4;m_reg=m4;reg_t=t4;break; } if(buf[0]==104){h_reg++;if(h_reg>23){h_reg=0;}} if(buf[0]==105){h_reg--;if(h_reg<0){h_reg=23;}} if(buf[0]==106){m_reg++;if(m_reg>59){m_reg=0;}} if(buf[0]==107){m_reg--;if(m_reg<0){m_reg=59;}} if(buf[0]==200){reg_t++;if(reg_t>50){reg_t=50;}} if(buf[0]==300){reg_t--;if(reg_t<10){reg_t=10;}} switch(tim){ case 1: h1=h_reg;m1=m_reg;t1=reg_t;break; case 2: h2=h_reg;m2=m_reg;t2=reg_t;break; case 3: h3=h_reg;m3=m_reg;t3=reg_t;break; case 4: h4=h_reg;m4=m_reg;t4=reg_t;break; } } //////////// reg temp if(sett==0){ if(reg >= temper + gis){rele=1;digitalWrite(22,HIGH);} if(reg <= temper - gis){rele=0;digitalWrite(22,LOW);} } else{ if(hh*100+mm>=h1*100+m1&&hh*100+mm<h2*100+m2){ if(t1 >= temper + gis){rele=1;digitalWrite(22,HIGH);} if(t1 <= temper - gis){rele=0;digitalWrite(22,LOW);} } if(hh*100+mm>=h2*100+m2&&hh*100+mm<h3*100+m3){ if(t2 >= temper + gis){rele=1;digitalWrite(22,HIGH);} if(t2 <= temper - gis){rele=0;digitalWrite(22,LOW);} } if(hh*100+mm>=h3*100+m3&&hh*100+mm<h4*100+m4){ if(t3 >= temper + gis){rele=1;digitalWrite(22,HIGH);} if(t3 <= temper - gis){rele=0;digitalWrite(22,LOW);} } if(hh*100+mm>=h4*100+m4 && hh*100+mm<2359){ if(t4 >= temper + gis){rele=1;digitalWrite(22,HIGH);} if(t4 <= temper - gis){rele=0;digitalWrite(22,LOW);} } if(hh*100+mm<h1*100+m1 && hh*100+mm>=0){ if(t4 >= temper + gis){rele=1;digitalWrite(22,HIGH);} if(t4 <= temper - gis){rele=0;digitalWrite(22,LOW);} } } blue(); //////////////// EEPROM if(millis()-times>5000&&w==1){EEPROM.write(0,reg); EEPROM.write(1,h1);EEPROM.write(2,m1);EEPROM.write(3,h2);EEPROM.write(4,m2); EEPROM.write(5,h3);EEPROM.write(6,m3);EEPROM.write(7,h4);EEPROM.write(8,m4); EEPROM.write(9,t1);EEPROM.write(10,t2);EEPROM.write(11,t3);EEPROM.write(12,t4);EEPROM.write(13,sett); times=millis();w=0;EEPROM.commit();} /////// измерение температуры 1 раз в секунду if(k==0){digitalWrite(2,LOW);} if(k==1){digitalWrite(2,HIGH);} if(k>1){k=0;} if(millis()-times1>1000){temper = dsRead(0);times1=millis();k++; } /////////////// times if(millis()-times2>=1000){times2=millis(); while(!timeClient.update()){timeClient.forceUpdate();} hh = timeClient.getHours(); mm = timeClient.getMinutes(); ss = timeClient.getSeconds(); } delay(5); }// loop float dsRead(byte x) { byte data[2], addr[8][8], kol = 0; while (ds.search(addr[kol])) { // поиск датчиков, определение адреса и кол-ва датчиков kol++; } ds.reset_search(); // Сброс поиска датчика ds.reset(); // Инициализация, выполняется сброс шины ds.select(addr[x]); // Обращение к датчику по адресу ds.write(0x44, 0); // Измерение температуры с переносом данных в память ds.reset(); // Инициализация, выполняется сброс шины ds.select(addr[x]); // Обращение к датчику по адресу ds.write(0xBE); // Обращение памяти data[0] = ds.read();// Чтение памяти byte low data[1] = ds.read();// Чтение памяти byte high float value = ((data[1] << 8) | data[0]) / 16.0; return (float)value; // Расчет температуры и вывод } void blue(){ //////// отправка данный в android BL.print(temper,1); BL.print(":"); BL.print(reg); BL.print(":"); BL.print(rele); BL.print(":"); BL.print(hh); BL.print(":"); BL.print(mm); BL.print(":"); BL.print(ss); BL.print(":"); BL.print(h_reg); BL.print(":"); BL.print(m_reg); BL.print(":"); BL.print(tim); BL.print(":"); BL.print(reg_t); BL.print(":"); BL.print(h1); BL.print(":"); BL.print(h2); BL.print(":"); BL.print(h3); BL.print(":"); BL.print(h4); BL.print(":"); BL.print(m1); BL.print(":"); BL.print(m2); BL.print(":"); BL.print(m3); BL.print(":"); BL.print(m4); BL.print(":"); BL.print(t1); BL.print(":"); BL.print(t2); BL.print(":"); BL.print(t3); BL.print(":"); BL.print(t4); BL.print(":"); BL.println(sett); } void BTCallback(esp_spp_cb_event_t event, esp_spp_cb_param_t *param){ if(event == ESP_SPP_SRV_OPEN_EVT){BT_CALLBACK = "BTonConnect";} else if(event == ESP_SPP_CLOSE_EVT){ESP.restart();} else if(event == ESP_SPP_DATA_IND_EVT){BT_CALLBACK = "BTonReceivedStart";} else if(event == ESP_SPP_WRITE_EVT){BT_CALLBACK = "BTonWrite";} }
Приложение — http://forum.rcl-radio.ru/misc.php?action=pan_download&item=1071&download=1
Здравствуйте! Подскажите пожалуйста, можно ли в этот проект добавить индикатор TM1637 для отображения текущей температуры с датчика DS18B20? Хочу установить данный терморегулятор на бойлер. Спасибо
Я завтра подготовлю скетч, но я не смогу его проверить, тестировать придется Вам.
Спасибо огромное
Хороший термостат !!! Хорошо бы было, если бы автор его размножил другими плюшками: ESP32 + WebServer или/и ESP32 + Telegram…