1

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

Основная статья - https://rcl-radio.ru/?p=91702

#include <SoftwareSerial.h>   // Входит в состав Arduino IDE  
#include <Wire.h> // Входит в состав Arduino IDE 
#include <EEPROM.h>  // Входит в состав Arduino IDE 
#include <Encoder.h>  // https://rcl-radio.ru/wp-content/uploads/2019/05/Encoder.zip
#include <MsTimer2.h> // https://rcl-radio.ru/wp-content/uploads/2018/11/MsTimer2.zip
#include <OneWire.h>  // https://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> // https://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 подключен к цыфровому входу 2
 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