Терморегулятор для системы отопления (Arduino)

Терморегулятор для системы отопления предназначен для удаленного управления нагревательным элементом. Основной (базовый) блок на базе Arduino (Nano) измеряет температуру (DS18B20) в помещении, задает температуру регулировки и далее по линии связи на основе интерфейса RS-485 передает команду включения или отключения нагревательного элемента второй плате на базе Arduino (Nano).

Дополнительно к основному блоку подключен датчик влажности. Вся информация выводится на LCD1602 который расположен в основном блоке, регулировка параметров осуществляется при помощи энкодера KY-040. Так же управление и вывод информации дублируется при помощи Android приложения, связь с которым осуществляется при помощи Bluetooth модуля HC-06.

Основные компоненты схемы

RS485 — это последовательный интерфейс передачи данных. Максимальная длина линии при соединении по RS485 составляет 1200 метров. В качестве кабеля для RS485 используется витая пара. Это два провода, сплетенные друг с другом. Чтобы передавать данные на дистанции более 500 метров, потребуется экранированная витая пара.

Подключение — http://rcl-radio.ru/?p=80037

 Bluetooth модуль HC-06

Arduino HC-06 (подключение, управление реле)

Экран LCD1602 используется совместно с модулем PCF8574.

I2C модуль на базе микросхем PCF8574 позволяют подключить символьный дисплей 1602 к плате Arduino всего по двум проводам SDA и SCL (А4 и А5), что дает возможность не использовать цифровые выходы Arduino при подключении дисплея.

Датчик влажности DHT11

Подключение — http://rcl-radio.ru/?p=47025

Датчик температуры DS18B20

Подключение — http://rcl-radio.ru/?p=82063

Схема терморегулятора

Основной блок позволяет изменять температуру регулирования от 10,0 до 50,0 °С с шагом регулировки 0,1 °С, а так же температуру гистерезиса от 0,1 до 5,0 °С с шагом 0,1 °С. Температура регулирования и гистерезис меняется поворотом ручки энкодера, нажатие кнопки энкодера меняет режим регулировки с регулирования температуры на регулировку энкодера и наоборот.

Android приложение отображает температуру в помещении и влажность, так же позволяет менять температуру регулирования.

Подключение к Bluetooth модулю HC-06 — http://rcl-radio.ru/?p=68590

Второй блок осуществляет регулировку (включение/отключение) нагревательного элемента, дополнительно содержит индикатор (светодиод) линии связи RS485, постоянное мигание которого сигнализирует об исправности линии связи.

Скетч — основной блок управления

#include <SoftwareSerial.h>   // Входит в состав Arduino IDE  
#include <Wire.h> // Входит в состав Arduino IDE 
#include <EEPROM.h>  // Входит в состав Arduino IDE 
#include <Encoder.h>  // http://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // http://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <OneWire.h>  // http://rcl-radio.ru/wp-content/uploads/2018/07/OneWire.zip
#include <LiquidCrystal_I2C.h> //Библиотека - http://forum.rcl-radio.ru/misc.php?action=pan_download&item=45&download=1
#include <DHT.h> // http://rcl-radio.ru/wp-content/uploads/2018/08/DHT.zip
 LiquidCrystal_I2C lcd(0x27,16,2);  // Устанавливаем дисплей
 SoftwareSerial rs485(11, 12);  // RO и DI     
 Encoder myEnc(8, 9);//CLK, DT    
 OneWire  ds(A0); // Вход датчика  
 DHT dht(A1, DHT11); // выход DAT  
 byte a1[8] = {0b11000,0b11000,0b00111,0b01000,0b01000,0b01000,0b00111,0b00000}; //c  
 
 float temper;
 int w,rele_1,menu,www,reg,gis,buf[2],i,wb;
 unsigned long buff,oldPosition  = -999,newPosition,times,times1;
 
void setup() {
  Serial.begin(9600);Serial.setTimeout(50);rs485.begin(9600);dht.begin();         
  pinMode(10,INPUT);// МЕНЮ КНОПКА SW энкодера
  pinMode(7,OUTPUT);// rs - r/w  
  MsTimer2::set(3, to_Timer);MsTimer2::start();            
  lcd.init();lcd.backlight();lcd.createChar(0,a1); 
  reg=EEPROM.read(0)*256+EEPROM.read(1);gis=EEPROM.read(2);          
}
 
void loop() {
//////////// MENU  
  if(digitalRead(10)==LOW){menu++;if(menu>1){menu=0;};times1=millis();w=1;delay(100);}
 
/////////// SETTING temperature + hysteresis  
  if(menu==0){
  if (newPosition != oldPosition){oldPosition = newPosition;times=millis();times1=millis();w=1;www=1;
     reg=reg+newPosition;myEnc.write(0);newPosition=0;if(reg>500){reg=500;}if(reg<100){reg=100;}
     //Serial.println(reg);
     }}
  if(menu==1){
  if (newPosition != oldPosition){oldPosition = newPosition;times=millis();times1=millis();w=1;www=1;
     gis=gis+newPosition;myEnc.write(0);newPosition=0;if(gis>50){gis=50;}if(gis<1){gis=1;}
     //Serial.println(gis);
     }}
 
/////////// LCD + DS18B20     
  temper = dsRead(0);
  lcd.setCursor(0, 0);lcd.print("T=");lcd.print(temper,1);lcd.write((uint8_t)0);
  if(menu==0){
  lcd.setCursor(8, 0);lcd.print("Ts=");lcd.print((float)reg/10,1);lcd.write((uint8_t)0);lcd.print(" ");}
  else{
  lcd.setCursor(8, 0);lcd.print("Gs=");lcd.print((float)gis/10,1);lcd.write((uint8_t)0);lcd.print(" ");}
  lcd.setCursor(0, 1);lcd.print("H=");lcd.print(dht.readHumidity(),0);lcd.print("%");
  lcd.setCursor(7, 1);lcd.print("heat ");if(rele_1==0){lcd.print("OFF");}else{lcd.print("ON ");}
 
 ///////// отправка данных 
  if((float)reg/10 >= temper + (float)gis/10){rele_1=1;}
  if((float)reg/10 <= temper - (float)gis/10){rele_1=0;}  
  if(millis()-times>2000){
  digitalWrite(7,HIGH); // DE-RE оправка данных 
  rs485.print(rele_1);for(int i=0;i<10;i++){delay(100);if(www==1){www=0;break;}}}
 
//////////////// EEPROM
  if(millis()-times1>5000&&w==1){
    EEPROM.update(0,highByte(reg));EEPROM.update(1,lowByte(reg));EEPROM.update(2,gis);
    times1=millis();w=0;menu=0;}
 
/////// ПРИЕМ ДАННЫХ С SERIAL PORT /////////////////////////
  while (Serial.available()>0){ 
   for (i=0;i<1;i++) { 
     buf[0] = Serial.parseInt(); 
     buf[1] = Serial.parseInt();}    
     times=millis();times1=millis();wb=1;w=1;www=1;}  
 
///////////// обработка команд /////////////////// 
 if(buf[0]>10&&wb==1){ wb=0;
     if(buf[0]==102){reg++;if(reg>500){reg=500;}}
     if(buf[0]==101){reg--;if(reg<100){reg=100;}}}
 
//////// отправка днный в android
   Serial.print(temper,1);
   Serial.print(":");
   Serial.print(reg);
   Serial.print(":");
   Serial.print(rele_1);
   Serial.print(":");
   Serial.println(int(dht.readHumidity())); 
}//loop
 
 
void to_Timer(){newPosition = myEnc.read()/4;
   if(digitalRead(10)==LOW){www=1;}
   if(newPosition != oldPosition){www=1;}
   if(Serial.available()>0){www=1;times=millis();}
}
 
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; // Расчет температуры и вывод
}

Скетч —  второй блок

#include <SoftwareSerial.h>   // Входит в состав Arduino IDE  
 SoftwareSerial rs485(11, 12);  // RO и DI       
 
 int buff,i;
 unsigned long times;
 
 
void setup() {
  Serial.begin(9600);rs485.begin(9600);         
  pinMode(10,OUTPUT);// rs - r/w 
  pinMode(13,OUTPUT);// rele_1 
  pinMode(2,OUTPUT); // led test OK        
}
 
void loop() {
 
///////// прием данных
  digitalWrite(10,LOW); // DE-RE прием данных
  if( rs485.available() ){ 
  while( rs485.available()> 0 ){buff = rs485.parseInt();}
  }
  Serial.println(buff,BIN);
  if(buff & 0b01 == 1){digitalWrite(13,HIGH);}else{digitalWrite(13,LOW);}
  digitalWrite(2,i);
  i++;if(i>1){i=0;}
 
}//loop

Приложение — app-debug.apk , исходник приложения — LabBluetooth-master (2)

Форум — http://forum.rcl-radio.ru/viewtopic.php?pid=2803#p2803

При загрузке скетча нужно временно отключить Bluetooth модуль HC-06.

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

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