/*подключаем библиотеки*/
 #include <Wire.h>//подключаем экран
 #include <LiquidCrystal_I2C.h>//подключаем экран
 #include <OneWire.h>//подключаем датчик температуры
 #include <DallasTemperature.h>//подключаем датчик температуры

 LiquidCrystal_I2C lcd(0x27, 16, 2);//подключаем экран
 OneWire ds_1(2), ds_2(3), ds_3(4);//подключаем шину для температурника
 DallasTemperature ds1(&ds_1), ds2(&ds_2), ds3(&ds_3);//задаем имя датчика комнаты
 DeviceAddress addr1, addr2, addr3;//хранение адреса датчика температуры для проверки


/*ввод переменных*/
 int TUS = 20;//ввод переменной для хранения установленной температуры
 #define up 7   //ввод переменных для кнопок
 #define down 9
 #define left 6
 #define right 8
 #define reln 13
 int curs = 0;//переменная для меню (курсор)
 int rel1, rel2, rel3;//переменные для реле
 unsigned long time;//переменная времени сработки кнопок
 bool flag = false;//вводим переменную для проверки нажатия кнопок
 bool light = 0;//переменная для управления подсветкой
 bool kn1, kn2, kn3, kn4;//переменные для кнопок
 char ten1 = 'a', ten2 = 'a', ten3 = 'a', nas = 'a';//переменные для хранения состояния тэн и насоса
 long randN;//рандом реле



void setup(){
  ds1.begin();//запуск датчика температуры
  ds2.begin();//запуск датчика температуры
  ds3.begin();//запуск датчика температуры
  lcd.init();//подключаем экран
  lcd.backlight();//включаем подсветку
  
  
  /*рандомируем реле*/
  randomSeed(analogRead(A3));
  randN = random(10, 13);
  rel1 = randN;
  do {randN = random(10, 13); rel2 = randN;} while (rel2 == rel1);
  do {randN = random(10, 13); rel3 = randN;} while (rel3 == rel2 || rel3 == rel1);
  /*рандом*/

/*назначаем пины*/  
  pinMode(6, INPUT_PULLUP);//подключаем кнопки
  pinMode(7, INPUT_PULLUP);//подключаем кнопки
  pinMode(8, INPUT_PULLUP);//подключаем кнопки
  pinMode(9, INPUT_PULLUP);//подключаем кнопки
  pinMode(10, OUTPUT);//подключаем реле
  pinMode(11, OUTPUT);//подключаем реле
  pinMode(12, OUTPUT);//подключаем реле
  pinMode(13, OUTPUT);//подключаем реле
  digitalWrite (rel1, LOW);//отключаем реле при запуске
  digitalWrite (rel2, LOW);//отключаем реле при запуске
  digitalWrite (rel3, LOW);//отключаем реле при запуске
  digitalWrite (reln, LOW);//отключаем реле при запуске
  

/*начало работы*/
  lcd.print("zapusk  vers1.0");
  delay(1000);
  lcd.setCursor(8, 1);//курсор на вторую строку
  lcd.print("proverka");
  delay(2000);

 /*проверка датчиков на работоспосоность*/
  if ( !ds1.getAddress(addr1, 0)){//опрос адреса 1 датчика, если нет ответа то
    lcd.clear();
    lcd.print("temp kom ne rab");
    delay(10000);
  }
  if (!ds2.getAddress(addr2, 0)){//опрос адреса 2 датчика, если нет ответа то
    lcd.clear();
    lcd.print("temp vod ne rab");
    delay(10000);
  }
  if (!ds3.getAddress(addr3, 0)){//опрос адреса датчика защиты, если нет ответа то
    lcd.clear();
    lcd.print("zachita ne rab");
    delay(10000);
    return;
  }
  lcd.clear();
  lcd.print("vse OK");
  delay(3000);
  lcd.clear();//очистка дисплея*/

/*показания (прорисовка внешнего вида) данных на экране*/
  lcd.home();
  lcd.print("tus");//температура установленная
  lcd.setCursor(3, 0);
  lcd.print(TUS);//пишем температуру
  lcd.setCursor(6, 0);
  lcd.print("tk");//температура комнаты
  lcd.setCursor(11, 0);
  lcd.print("tv");//температура воды
  lcd.setCursor(0, 1);
  lcd.print("1 ");//1 тэн
  lcd.setCursor(1, 1);
  lcd.print(ten1);//пишем состояние
  lcd.setCursor(4, 1);
  lcd.print("2 ");//2 тэн
  lcd.setCursor(5, 1);
  lcd.print(ten2);//пишем состояние
  lcd.setCursor(8, 1);
  lcd.print("3 ");//3 тэн
  lcd.setCursor(9, 1);
  lcd.print(ten3);//пишем состояние
  lcd.setCursor(13, 1);
  lcd.print("N ");//насос
  lcd.setCursor(14, 1);
  lcd.print(nas);
  ds1.requestTemperatures();//опрашиваем температуру на датчике комнаты
  ds2.requestTemperatures();//опрашиваем температуру на датчике воды
  ds3.requestTemperatures();//опрашиваем температуру на датчике защиты
  lcd.setCursor(8, 0);
  lcd.print(ds1.getTempCByIndex(0), 0);//вывод на экран температуры - 0-не пишется десятичные
  lcd.setCursor(13,0);
  lcd.print(ds2.getTempCByIndex(0), 0);//вывод на экран температуры

  time = millis();//записываем текущее значение счетчика
  
}






void loop(){
/*вывод данных на экран*/  
  if(time + 10000 <= millis()){//задержка опроса температуры
  ds1.requestTemperatures();//опрашиваем температуру на датчике
  ds2.requestTemperatures();//опрашиваем температуру на датчике
  ds3.requestTemperatures();
  lcd.setCursor(8, 0);
  lcd.print(ds1.getTempCByIndex(0), 0);//вывод на экран температуры - 0-не пишется десятичные
  lcd.setCursor(13,0);
  lcd.print(ds2.getTempCByIndex(0), 0);//вывод на экран температуры
  }

/*работа с кнопками*/
   
    /*кнопка увеличения температуры*/
  kn1 = !digitalRead(up);//считывание нажатия кнопки
  if (kn1 == !flag && curs == 0) {//проверка состояния
    lcd.backlight();//включение подсветки
    lcd.noCursor();
    time = millis();//записываем текущее значение счетчика
    TUS++;//прибавление температуры на 1
    lcd.setCursor(3, 0);
    lcd.print(TUS);//пишем новую температуру
    delay(200);
  }
 

    /*кнопка уменьшения температуры*/
  kn2 = !digitalRead(down);//считывание нажатия кнопки
  if (kn2 == !flag && curs == 0) {//проверка состояния
    lcd.backlight();//включение подсветки
    lcd.noCursor();
    time = millis();//записываем текущее значение счетчика
    TUS--;//убавление температуры на 1
    lcd.setCursor(3, 0);
    lcd.print(TUS);//пишем новую температуру
    delay(200);
  }
  
    /*кнопка влево (подсветка)*/
  kn4 = !digitalRead(left);//считывание нажатия кнопки
  if (kn4 == !flag && light == 0 && curs == 0) {//проверка состояния
    lcd.backlight();//включение подсветки
    light = 1;//запись в переменную что подсветка включена принудительно
    delay(200);}
     else if (kn4 == !flag && light == 1){
     lcd.noBacklight();//отключение подсветки
     light = 0;//отключение подсветки
     delay(200);
     }

    /*кнопка вправо(меню)*/
  kn3 = !digitalRead(right);//считывание нажатия кнопки
  if (kn3 == !flag && curs == 0) {//проверка состояния
    lcd.backlight();//включение подсветки
    time = millis();//записываем текущее значение счетчика
    lcd.setCursor(1, 1);//устанавливаем курсор
    lcd.cursor();//включение курсора
    curs = 1;//запись в переменную положение курсора
    delay(200);
   }

   /*управление 1 тэном*/
      else if (kn1 == !flag && curs == 1 && ten1 == 'a'){
      ten1 = '+';
      lcd.setCursor(1, 1);
      lcd.print(ten1);
      lcd.setCursor(1, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn1 == !flag && curs == 1 && ten1 == '+'){
      ten1 = '-';
      lcd.setCursor(1, 1);
      lcd.print(ten1);
      lcd.setCursor(1, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn1 == !flag && curs == 1 && ten1 == '-'){
      ten1 = 'a';
      lcd.setCursor(1, 1);
      lcd.print(ten1);
      lcd.setCursor(1, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      
       else if (kn2 == !flag && curs == 1 && ten1 == 'a'){
      ten1 = '-';
      lcd.print(ten1);
      lcd.setCursor(1, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn2 == !flag && curs == 1 && ten1 == '+'){
      ten1 = 'a';
      lcd.print(ten1);
      lcd.setCursor(1, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn2 == !flag && curs == 1 && ten1 == '-'){
      ten1 = '+';
      lcd.print(ten1);
      lcd.setCursor(1, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }


     /*управление 2 тэном*/
      else if (kn3 == !flag && curs == 1) {//проверка состояния
      time = millis();//записываем текущее значение счетчика
      lcd.setCursor(5, 1);//устанавливаем курсор
      lcd.cursor();//включение курсора
      curs = 2;//запись в переменную положение курсора
      delay(200);
   }
        else if (kn4 == !flag && curs == 2) {//проверка состояния
        time = millis();//записываем текущее значение счетчика
        lcd.setCursor(1, 1);//устанавливаем курсор
        lcd.cursor();//включение курсора
        curs = 1;//запись в переменную положение курсора
        delay(200);
        }

       /*управление 2 тэном*/
      else if (kn1 == !flag && curs == 2 && ten2 == 'a'){
      ten2 = '+';
      lcd.print(ten2);
      lcd.setCursor(5, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn1 == !flag && curs == 2 && ten2 == '+'){
      ten2 = '-';
      lcd.print(ten2);
      lcd.setCursor(5, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn1 == !flag && curs == 2 && ten2 == '-'){
      ten2 = 'a';
      lcd.print(ten2);
      lcd.setCursor(5, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      
       else if (kn2 == !flag && curs == 2 && ten2 == 'a'){
      ten2 = '-';
      lcd.print(ten2);
      lcd.setCursor(5, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn2 == !flag && curs == 2 && ten2 == '+'){
      ten2 = 'a';
      lcd.print(ten2);
      lcd.setCursor(5, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn2 == !flag && curs == 2 && ten2 == '-'){
      ten2 = '+';
      lcd.print(ten2);
      lcd.setCursor(5, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }


   /*управление 3 тэном*/
      else if (kn3 == !flag && curs == 2) {//проверка состояния
      time = millis();//записываем текущее значение счетчика
      lcd.setCursor(9, 1);//устанавливаем курсор
      lcd.cursor();//включение курсора
      curs = 3;//запись в переменную положение курсора
      delay(200);
   }
        else if (kn4 == !flag && curs == 3) {//проверка состояния
        time = millis();//записываем текущее значение счетчика
        lcd.setCursor(5, 1);//устанавливаем курсор
        lcd.cursor();//включение курсора
        curs = 2;//запись в переменную положение курсора
        delay(200);
   }
          /*управление 3 тэном*/
         else if (kn1 == !flag && curs == 3 && ten3 == 'a'){
      ten3 = '+';
      lcd.print(ten3);
      lcd.setCursor(9, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn1 == !flag && curs == 3 && ten3 == '+'){
      ten3 = '-';
      lcd.print(ten3);
      lcd.setCursor(9, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn1 == !flag && curs == 3 && ten3 == '-'){
      ten3 = 'a';
      lcd.print(ten3);
      lcd.setCursor(9, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      
       else if (kn2 == !flag && curs == 3 && ten3 == 'a'){
      ten3 = '-';
      lcd.print(ten3);
      lcd.setCursor(9, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn2 == !flag && curs == 3 && ten3 == '+'){
      ten3 = 'a';
      lcd.print(ten3);
      lcd.setCursor(9, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn2 == !flag && curs == 3 && ten3 == '-'){
      ten3 = '+';
      lcd.print(ten3);
      lcd.setCursor(9, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }


    /*управление насосом*/
      else if (kn3 == !flag && curs == 3) {//проверка состояния
      time = millis();//записываем текущее значение счетчика
      lcd.setCursor(14, 1);//устанавливаем курсор
      lcd.cursor();//включение курсора
      curs = 4;//запись в переменную положение курсора
      delay(200);
   }
        else if (kn4 == !flag && curs == 4) {//проверка состояния
        time = millis();//записываем текущее значение счетчика
        lcd.setCursor(9, 1);//устанавливаем курсор
        lcd.cursor();//включение курсора
        curs = 3;//запись в переменную положение курсора
        delay(200);
        }

       /*управление насососм*/
      else if (kn1 == !flag && curs == 4 && nas == 'a'){
      nas = '+';
      lcd.print(nas);
      lcd.setCursor(14, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn1 == !flag && curs == 4 && nas == '+'){
      nas = '-';
      lcd.print(nas);
      lcd.setCursor(14, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn1 == !flag && curs == 4 && nas == '-'){
      nas = 'a';
      lcd.print(nas);
      lcd.setCursor(14, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      
       else if (kn2 == !flag && curs == 4 && nas == 'a'){
      nas = '-';
      lcd.print(nas);
      lcd.setCursor(14, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
       else if (kn2 == !flag && curs == 4 && nas == '+'){
      nas = 'a';
      lcd.print(nas);
      lcd.setCursor(14, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }
      else if (kn2 == !flag && curs == 4 && nas == '-'){
      nas = '+';
      lcd.print(nas);
      lcd.setCursor(14, 1);
      time = millis();//записываем текущее значение счетчика
      delay(200);
      }

/*работа с кнопками конец*/
 
  
/*сброс действий*/  
  if(time + 10000 <= millis() && light == 0){//считаем время после включения или после нажатия кнопки
  lcd.noBacklight();//отключение подсветки
  }
  if(time + 5000 <= millis()){
  lcd.noCursor();//отключение курсора
  curs = 0;
}

/*защита от перегрева устройства*/
 while (ds3.getTempCByIndex(0) >= 70){
  digitalWrite (rel1, 0);
  digitalWrite (rel2, 0);
  digitalWrite (rel3, 0);
  digitalWrite (reln, 0);
  lcd.clear();
  lcd.backlight();
  lcd.print ("peregrev rele");
  delay(20000);
  ds3.requestTemperatures();
  
}


rele();

}



/*работа реле*/
void rele(){
  
 /*rele1*/
 if (ten1 == '+' && curs == 0){ 
     digitalWrite(rel1, 1);
     lcd.setCursor(2, 1);
     lcd.print('+');
     lcd.setCursor(2, 1);
     }
  if (ten1 == '-' && curs == 0){ 
     digitalWrite(rel1, 0);
     lcd.setCursor(2, 1);
     lcd.print('-');
     lcd.setCursor(2, 1);
     }
     if (ten1 == 'a' && curs == 0 && TUS > ds1.getTempCByIndex(0) && millis() > 15000){ 
     digitalWrite(rel1, 1);
     lcd.setCursor(2, 1);
     lcd.print('+');
     lcd.setCursor(2, 1);
     }
     if(ten1 == 'a' && curs == 0 && TUS <= ds1.getTempCByIndex(0) && millis() > 15000){
      digitalWrite(rel1, 0);
     lcd.setCursor(2, 1);
     lcd.print('-');
     lcd.setCursor(2, 1);
     }

 /*rele2*/
 if (ten2 == '+' && curs == 0){ 
     digitalWrite(rel2, 1);
     lcd.setCursor(6, 1);
     lcd.print('+');
     lcd.setCursor(6, 1);
     }
  if (ten2 == '-' && curs == 0){ 
     digitalWrite(rel2, 0);
     lcd.setCursor(6, 1);
     lcd.print('-');
     lcd.setCursor(6, 1);
     }
     if (ten2 == 'a' && curs == 0 && TUS-1 > ds1.getTempCByIndex(0) && millis() > 15000){ 
     digitalWrite(rel2, 1);
     lcd.setCursor(6, 1);
     lcd.print('+');
     lcd.setCursor(6, 1);
     }
     if(ten2 == 'a' && curs == 0 && TUS <= ds1.getTempCByIndex(0) && millis() > 15000){
      digitalWrite(rel2, 0);
     lcd.setCursor(6, 1);
     lcd.print('-');
     lcd.setCursor(6, 1);
     }

  /*rele3*/
  if (ten3 == '+' && curs == 0){ 
     digitalWrite(rel3, 1);
     lcd.setCursor(10, 1);
     lcd.print('+');
     lcd.setCursor(10, 1);
     }
  if (ten3 == '-' && curs == 0){ 
     digitalWrite(rel3, 0);
     lcd.setCursor(10, 1);
     lcd.print('-');
     lcd.setCursor(10, 1);
     }
     if (ten3 == 'a' && curs == 0 && TUS-2 > ds1.getTempCByIndex(0) && millis() > 15000){ 
     digitalWrite(rel3, 1);
     lcd.setCursor(10, 1);
     lcd.print('+');
     lcd.setCursor(10, 1);
     }
     if(ten3 == 'a' && curs == 0 && TUS <= ds1.getTempCByIndex(0) && millis() > 15000){
      digitalWrite(rel3, 0);
     lcd.setCursor(10, 1);
     lcd.print('-');
     lcd.setCursor(10, 1);
     }


  /*rele4*/
  if (nas == '+' && curs == 0){ 
     digitalWrite(reln, 1);
     lcd.setCursor(15, 1);
     lcd.print('+');
     lcd.setCursor(15, 1);
     }
  if (nas == '-' && curs == 0){ 
     digitalWrite(reln, 0);
     lcd.setCursor(15, 1);
     lcd.print('-');
     lcd.setCursor(15, 1);
     }
     if (nas == 'a' && curs == 0 && ds2.getTempCByIndex(0) >= 80 && millis() > 15000){ 
     digitalWrite(reln, 1);
     lcd.setCursor(15, 1);
     lcd.print('+');
     lcd.setCursor(15, 1);
     }
     if(nas == 'a' && curs == 0 && ds2.getTempCByIndex(0) <= 60 && millis() > 15000){
      digitalWrite(reln, 0);
     lcd.setCursor(15, 1);
     lcd.print('-');
     lcd.setCursor(15, 1);
     }
 }
$abcdeabcde151015202530354045505560fghijfghij
$abcdeabcde151015202530fghijfghij
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module
NOCOMNCVCCGNDINLED1PWRRelay Module