| Ваш IP: 3.233.219.62 | Online(17) - гости: 7, боты: 10 | Загрузка сервера: 0.89 ::::::::::::

ESP32 + Bluetooth — терморегулятор (2)

Ранее на странице https://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>         // https://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

Добавить комментарий

Войти с помощью: 

Случайные статьи

  • Высококачественный усилитель мощности на LM1876

    Высококачественный усилитель мощности на LM1876

    Усилитель выполнен на микросхеме LM1876, имеет выходную мощность до 22 Вт при напряжении питания от ±10 до ±32 В. ИМС LM1876 имеет защиту от перегрева, перегрузки, и систему мягкого включения для избавления от щелчков при подаче питания. Технические характеристики: Выходная мощность при Rн = 8 Ом и Uпит ±22 В … 2х20 …Подробнее...
  • Предусилитель на 3 микрофона

    Предусилитель на 3 микрофона

    Схема приведенная здесь имеет три микрофонных входа, схема выполнена на микросхеме LM348 IC.LM348 обладает высоким коэффициентом усиления, схема выполнена на четырех операционных усилителя с выходным каскадом класса AB. Микросхемы имеет очень низкий ток покоя (0.6mA) и работают от двухполярного источника питания. Заметки. * Сборка схемы на хорошее качество печатной плате. …Подробнее...
  • Дроссель на резисторе МЛТ

    Дроссель на резисторе МЛТ

    Самодельные дроссели основанный на резисторе МЛТ мощность от 0,125 до 2 Вт, является простым и не дорогим способом получить малогабаритный электронный компонент. Витки катушки индуктивности непосредственно наматываются на высокоомный резистор (100 кОм и более). Для расчета необходимого количества витков можно воспользоваться формулой: где: N — необходимое количество витков, L — нужная индуктивность дросселя в …Подробнее...
  • Стеклоочиститель с регулируемой паузой

    Диапазон регулирования длительности паузы стеклоочистителя от 5 до 60 с. Схема питается от постоянного напряжения 12В, максимальный ток потребления 25мА. Регулятор паузы подключают параллельно контактам конечного выключателя стеклоочистителя. При выключенном состоянии  контакты SA1 разомкнуты, при этом стеклоочиститель работает как обычно. При замыкании SA1 быстро заряжается С1 через электродвигатель привода стеклоочистителя. …Подробнее...
  • Лабораторный ГЗЧ

    Схема ГЗЧ (генератор звуковой частоты) показана на рис., выбор частотного диапазона производится переключателем S1, плавная регулировка производится резистором R3. Выходное напряжение снимается с R7 или через делитель R8-10. Генератор обеспечивает выходной сигнал около 1В при КНИ не более 0,5%. Питается ГЗЧ от 2-х полярного напряжения ±15В, монтаж производится на печатной …Подробнее...