Суточный термостат для газового котла

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011

ОК, продолжим лёгкий ликбез.
Надеюсь вы уже поняли что потери пропорциональны разнице температур.
И что котёл более эффективно ( экономично) работает на низкой температуре.

И  что количество тепла производимого котлом
необходимо немножко больше чем оно теряется в окружающую среду.
И вот этим  " немножко больше" мы можем управлять с помощью термоголовок на радиаторах

Теперь что такое тампература в комнате.
Там где стоят радиаторы температура под потолком будет выше чем у пола.
И будет сильная циркуляция воздуха.
Там где тёплый пол там температура под потолком будет ниже чем у пола
и практически отсутствует циркуляция воздуха.

Совет где повесить датчик.......
Мой совет не использовать температуру внутри для регулировки
Сам соседям лично выкидывал комнатные термостаты " втюханные" разными сантехниками.
А люди доверчивы, кнопочки жимкают, видиш, говорят: я тут температуру поставил, всё должно само работать
А у них то холодно то жарко.
А надо  установившийся режим. Плавный, непрерывное регулирование.
И релейным отключением-включением котла на длительное время этого не добиться.
 

rekrut007
Offline
Зарегистрирован: 19.10.2014

По поводу непрерывного регулирования согласен при условии, что у котла модулируемая горелка, мощность которой можно изменять в режиме нормальной работы. Однако у некоторых котлов с модулируемой горелкой ее мощность можно изменять только в режиме "сервиса", но никак не в рабочем режиме. А что по поводу датчика на столбе? Каково Ваше мнение по поводу его месторасположения?

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011

Котёл сам разбирается со своей горелкой.
И сам снижает мощьность когда видит что температура стала слишком быстро расти.
Мы туда не залезем просто никак и нельзя этого делать
Я , например, просто ограничил максимальную мощьность как раз в сервисе.
До 33 % от 28 килоВатт , меньше не было ,  9.24 кВатт
Так как при самых лютых морозах (20 и ниже) больше 16 кубов в сутки  ( и то при разгоне, потом 12) не видел.
А 16 куб Х 8 = 128  . 128  делим на 24= 5.3 средней .  двойной запас.
А вот темературу регулировать без вмешательства во внутренности мы можем двумя способами:
Используя вход контактов комнатного термостата или поворачивая ручку температуры ( например сервой).

Ставьте на столб. Градусник.  Будет точно показывать среднюю температуру по больнице.

Купите http://www.banggood.com/GM300-Digital-Laser-Point-Infrared-Thermometer-Temperature-Meter-Gun-p-85756.html

Увидите очень много интересного по температуре пола, потолка, стёкол и углов дома.
И столба.... :)

rekrut007
Offline
Зарегистрирован: 19.10.2014

Спасибо.

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011
rekrut007
Offline
Зарегистрирован: 19.10.2014

Может кому-нибудь помогут результаты моей работы. Также прошу высказывать мысли по поводу оптимизации.

[code]
/* Программа "Комнатный термостат"
Допоборудование - ds18b20(вывод 2 )- 3 датчика (комнатный, уличный, на котловую воду), ds3231(выводы 5-SCL и 4-SDA) и lcd1602.
Функция - замеряет температуру в помещении и на основании ее сравнения с установленными пользователями включает или выключает нагрузку.
Принцип работы:
1) пользователем устанавливаются время начала временных периода - ночного, утреннего и дневного.
2) пользователем устанавливаются температуры каждого временного периода - ночью, утром и днем.
3) в основном цикле программы постоянно считываются данные с часов ds3231, которые заносятся в соответствующие переменные.
4) через устанавливаемый пользователем в тексте программы интервал (сейчас равен 30 с.) считывается температура с датчика (три замера, высчитывается среднеарифмитическая).
5) затем определяется текущий временной период (ночь, утро или день).
6) считанная температура проверяется на наличие ошибки, то есть сравнивается с последней сохранненной в памяти. 
7) считанная температура сравнивается с установленной пользователем температурой текущего временного периода и при выходе температуры за границы включается ил выключатеся котел.
*/
////////////////////////////////////////////////////////////////
// подключение необходимых библиотек
#include <OneWire.h>                                    // для протокола 1-Wire
#include <Wire.h>                                       // для протокола I2C
#include <LiquidCrystal.h>                              // для lcd
#include <EEPROM.h>                                     // для обращения к энергонезависимой памяти
#include <wdt.h>                                        // библиотека сторожевого таймера
// адреса EEPROM, по которым хранятся задаваемые пользователем параметры: 
// 0-часы начала ночного периода, 1-минуты начала ночного периода, 2-часы начала утреннего периода, 3 - минуты начала утреннего периода, 4-часы начала дневного периода, 
// 5-минуты начала дневного периода, 6-температура ночного периода, 7-температура утреннего периода, 8-температура дневного периода.
// 10-17 - адрес комнатного датчика температуры, 20-27 - адрес уличного датчика температуры, 30-37 - адрес датчика температуры котловой воды

////////////////////////////////////////////////////////////////
// определяем вывод для протокола 1-Wire
OneWire ds(2);                                          // для Uno (провод припаянн на 2 вывод                  
// определяем вывод, который будет управлять включением/выключением котла по результатам сравнения температур
byte relekotla=3;                                       //  то же для Uno.
// определяем вывод для lcd
//LiquidCrystal lcd(RS, E, DB4, DB5, DB6, DB7)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);                // LCD для Uno - Keypad Schild
////////////////////////////////////////////////////////////////
// формируем 3 знака (маленькая, средняя и большая стрелки вверх), которые будут отражаться на lcd
// и свидетельствовать, что на выходе управления установлен HIGH, то есть котел включен на обогрев.
enum {symbol_height=8};
byte znak_lcd_plamya[symbol_height]=    // знак в виде пламени. Если нужен другой, то закомментировать.
{
  B00010,                                        
  B00110,
  B01100,
  B11100,
  B11110,
  B01111,
  B01110,
  B00100,
};
byte znak_lcd_gradus[symbol_height]=   // знак градус.     
{                           
  B00100,
  B01010,
  B00100,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
};
byte znak_lcd_D_Rus[symbol_height]=   // буква "Д".     
{                                  
  B01111,
  B00101,
  B00101,
  B00101,
  B01001,
  B10001,
  B11111,
  B10001,
};
byte znak_lcd_b_Rus[symbol_height]=   // буква "ь".     
{                                  
  B00000,
  B00000,
  B10000,
  B10000,
  B11110,
  B10001,
  B11110,
  B00000,
};
byte znak_lcd_n_Rus[symbol_height]=   // буква "н" .     
{                                  
  B00000,
  B00000,
  B10001,
  B10001,
  B11111,
  B10001,
  B10001,
  B00000,
};
byte znak_lcd_ch_Rus[symbol_height]=   // буква "ч" .     
{                                  
  B00000,
  B00000,
  B10001,
  B10001,
  B01111,
  B00001,
  B00001,
  B00000,
};
byte znak_lcd_u_Rus[symbol_height]=   // буква "У" .     
{                                  
  B10001,
  B10001,
  B10001,
  B01010,
  B00100,
  B01000,
  B10000,
  B00000,
};
byte znak_lcd_t_Rus[symbol_height]=   // буква "т" .     
{                                  
  B00000,
  B00000,
  B11111,
  B00100,
  B00100,
  B00100,
  B00100,
  B00000,
};
/*
byte znak_lcd_l_Rus[symbol_height]=   // буква "л" .     
{                                  
  B00000,
  B00000,
  B01111,
  B00101,
  B00101,
  B10101,
  B01001,
  B00000,
};
byte znak_lcd_CH_Rus[symbol_height]=   // буква "Ч" .     
{                                  
  B10001,
  B10001,
  B10001,
  B01111,
  B00001,
  B00001,
  B00001,
  B00000,
};
byte znak_lcd_bl_Rus[symbol_height]=   // буква "ы" .     
{                                  
  B00000,
  B00000,
  B10001,
  B10001,
  B11101,
  B10011,
  B11101,
  B00000,
};
*/
                          

////////////////////////////////////////////////////////////////
// объявляем переменные
// временные переменные для считывания адресов с подключенных датчиков
  byte temp_adres[8];                                
  byte temp_adres_datch_1[8];                            // для считывания адреса 1-го подключенного датчика
  byte temp_adres_datch_2[8];
  byte temp_adres_datch_3[8];
  byte kolvo_new_datch=0;                                // содержит кол-во новых подключенных датчиков
  boolean status_schit_datch_new[3];
  byte sss[8];
  
// для подпрограммы formirovanie_intervala(). 
  unsigned int interval_zapuska_dat_room=30000;           // интервал в милисекундах, через который будут запускаться подпрограмма по считыванию температуры с комнатного датчика. Он равен 30 сек.
  unsigned long interval_zapuska_dat_street=180000;       // интервал в милисекундах, через который будут запускаться подпрограмма по считыванию температуры с уличного датчика. Он равен 3 мин.
  unsigned int interval_wychoda_menu=15000;               // интервал в милисекундах, через который будет осуществляться выход из подпрограммы программирования
  unsigned long time_snachala_progi;                      // содержит текущие данные о времени, прошедшем сначала запуска программы. Для формирования интеравала .
  unsigned long time_snach_progi_dat_room=0;              // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала запуска для перехода к подпрограмме считывания комнатной температуры
  unsigned long time_snach_progi_dat_street=0;            // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала запуска для перехода к подпрограмме считывания уличной температуры
  unsigned long time_snach_progi_wychoda_menu=0;          // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала выхода из подпрограммы программирования
  unsigned long time_snach_progi_migania_dvoet=0;         // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала мигания двоеточия
  unsigned long time_snach_progi_migania_sost_kotla=0;    // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала мигания состояния котла
  unsigned long time_snach_progi_parametra_menu=0;        // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала мигания выбранного параметра меню
  unsigned long time_snach_progi_problem_datch_room=0;    // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала отсутствия ответа от комнатного датчика температуры
  unsigned long time_snach_progi_wychod_predel_temp=0;
  boolean miganie_parametra_programmirovaniya=true;       // когда true светится выбранный параметр, false - вместо параметра пробелы. 
  
// содержит предыдущие данные о времени, прошедшем с начала запуска программы для формирования мигания
// для работы с температурой
  byte adres_dat_temp_room[8];                            // для хранения адреса комнатаного датчика температуры
  byte adres_dat_temp_street[8];                          // для хранения адреса уличного датчика температуры
  byte adres_dat_temp_water[8];                           // для хранения адреса датчика температуры котловой воды
  float temperatura_room;                                 // считанная с комнатного датчика температура
  float temperatura_street;                               // считанная с уличного датчика температура
  float temperatura_water;                                // считанная с датчика котловой воды температура
  float temperatura_room_pamyat[3];                       // последние 3 считанных температуры (для проверки считанной температуры на наличие ошибок и исключения тактования)
  byte temperatura_room_ustanovka[3];                     // в них считываются из EEPROM задаваемые пользователем температуры временных периодов: 0-ночь, 1-утро, 2-день.
  float gisteresis=0.2;                                   // задаваемый пользователем гистерезис для определения температурных границ управления выходом
  boolean proverka_temperatura_room_status;               // содержит информацию о том, прошла ли считанная температура проверку на наличие грубых ошибок: true-да; false-нет.
  float temperatura_room_predyd=0, temperatura_street_predyd=0;   // используются для исключения постоянного вывода на lcd неизменнных данных  

// для работы со временем
  bool Century=false;                                     // для часов. Пока не знаю??????????????????????
  bool h12;                                               // для часов. Пока не знаю??????????????????????
  bool PM;                                                // для часов. Пока не знаю??????????????????????
  byte year, month, date, hour, minute, second;           // в них записываются полученные от часов данные о времени
  byte hour_predyd=0, minute_predyd=0;                    // используются для исключения постоянного вывода на lcd неизменнных данных
  byte nachalo_periodov[6];                               // в них считываются из EEPROM часы и минуты начала периодов: 0-часы ночи, 1-минуты ночи, 2-часы утра, 3-минуты утра, 4-часы дня, 5-минуты дня. 
  byte period_time;                                       // для храненения сведений о временном периоде (ночь-0, утро-1, день-2)
  int summa_minut[4];                                     // общие суммы минут: 0-текущего времени, 1-начала ночного периода, 2-начала утреннего периода, 3-начала дневного периода, для удобства сравнения
  byte obnovl_peremen=0;                                  // необходима для ежечасного считывания данных из EEPROM и их записи в соответствующие переменные

// для подпрограммы программирования
  byte status_programmirovaniya=1;                        // содержит число на основании которого устанавливается тот или иной параметр
  boolean knopka_verch=false;                             // содержит состояние кнопки "ВВЕРХ", по умолчанию false
  boolean knopka_vniz=false;                              // содержит состояние кнопки "ВНИЗ", по умолчанию false
  boolean knopka_pravo=false;                             // содержит состояние кнопки "ПРАВО" по умолчанию false
  boolean knopka_levo=false;                              // содержит состояние кнопки "ЛЕВО", по умолчанию false
  boolean knopka_select=false;                            // содержит состояние кнопки select, по умолчанию false
  int nashat_knopka=1023;                                 // содержит данные с аналогового входа 0
  boolean status_wybora_delete=false;                     // содержит состояние необходимости удаления датчика температуры из  EEPROM
  boolean status_wybora_save=false;                       // содержит состояние необходимости сохранения измененных параметров
  byte wybor_status_zapis_datch=1;                        // содержит число (1, 2 или 3), свидетельствующее о том, каким именно (комнатным, уличным или водяным) записывается новый датчик в EEPROM

///////////////////////////////////////////////////////////////
// подпрограмма формирования задаваемого интервала между обращениями к подпрограммам считывания температуры с датчика и получения времени с часов. 
unsigned long formirovanie_intervala(unsigned long time_snachala_progi_time_pred)
{
  time_snachala_progi=millis();                         // получаем количество милисекунд с начала выполнения программы
// Проверяем, не проскочил ли счетчик прошедшего времени через 0, если предыдущие показания не достигли максимума. 
// Если проскочил то к обоим сравниваемым переменным добавляем число из tempintervalzapuska и 100, чтобы вторая переменная также перескочила через 0.  
  if (time_snachala_progi_time_pred>time_snachala_progi)   // если текущие сведения о прошедшем времени меньше предыдущих данных, то это свидетельствует о том, что счетчик перескочил через 0.
  {
    time_snachala_progi_time_pred=time_snachala_progi_time_pred+185000;   // 185000 необходимо для максимального интервала 3 минуты.
    time_snachala_progi=time_snachala_progi+185000;
  }
  unsigned long time_interval=time_snachala_progi-time_snachala_progi_time_pred;      // высчитываем пройденный интервал
  return time_interval;
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания температуры с  датчика. 
float schit_datchik_temperatury(byte time_adres_dat_temp[], byte i)
{
  float time_temperatura[i];                               // объявляем переменные для временного хранения температуры из 3 последовательных замеров
  for(byte cikl=0; cikl<i; cikl++)
  {
    ds.reset(); 
    ds.write(0xCC);                                        // игнорируем адреса всех датчиков для следующей команды                             
    ds.write(0x44);                                        // запуск преобразования температуры всеми датчиками.
    delay(200);    
    ds.reset();
    ds.select(time_adres_dat_temp);                        // следующая команда предназначется только комнатному датчику
    ds.write(0xBE);                                        // чтение двух байт с данными температуры из памяти датчика                          
    byte data[2];
    data[0]=ds.read();                                     // присваивание переменной data[0] данных первого байта, полученного от датчика                     
    data[1]=ds.read();                                     // присваивание переменной data[1] данных второго байта, полученного от датчика
    time_temperatura[cikl]=((data[1] << 8)|data[0])/16.0;  // высчитываем температуру и заносим во временную переменную
  }
  float temperatura;
  switch(i)
  {
    case 1:
    temperatura=time_temperatura[0];
    break;
    case 3:
    temperatura=(time_temperatura[0]+time_temperatura[1]+time_temperatura[2])/3;
    break;
  }
  return temperatura;
}  


/////////////////////////////////////////////////////////////////////////////
// подпрограмма получения времени с часов ds3231 и их присваивание переменным. 
void poluchenie_wremeni()
{
// считываем данные с часов  
  byte tempBuffer;
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x00));
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7);
  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  tempBuffer = Wire.read();
  h12 = tempBuffer & 0b01000000;
  if (h12) 
  {
    PM = tempBuffer & 0b00100000;
    hour = bcdToDec(tempBuffer & 0b00011111);
  }
  else 
  {
    hour = bcdToDec(tempBuffer & 0b00111111);
  }
  byte DoW = Wire.read();
  date = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read() & 0b01111111);
  year = bcdToDec(Wire.read()); 
// Ежечасно сохраняем в переменные содержащиеся в EEPROM установленные: время начала временных периодов и их температуры, адреса датчиков температур
  if(minute!=24)
  {
    obnovl_peremen==0;                                  // обнуляем переменную, если минуты не равны 24.
  }
  if(minute==24 && obnovl_peremen==0)                   // 
  {
    nachal_ustanovki();
    obnovl_peremen++;                                   // для исключения обращения к подпрограмме nachal_ustanovki() более одного раза когда минуты равны 24.
  }
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма записи времени в часы ds3231. 
void zapis_wremeni()
{
  byte time_hour=hour;
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x02));
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1);
  h12 = (Wire.read() & 0b01000000);
  if (h12) 
  {
    if(time_hour > 12) 
    {
      time_hour = decToBcd(time_hour-12) | 0b01100000;
    } 
    else 
    {
      time_hour = decToBcd(time_hour) & 0b11011111;
    }
  }
  else 
  {   
    time_hour = decToBcd(time_hour) & 0b10111111;
  }
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x00));
  Wire.write(0x00);
  Wire.write(decToBcd(minute));	
  Wire.write(time_hour);
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x04));
  Wire.write(decToBcd(date));	
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));	
  Wire.endTransmission();
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма преобразования данных полученных с часов
byte bcdToDec(byte val) 
{
  return ((val/16*10) + (val%16));
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма преобразования данных для записи в часы
byte decToBcd(byte val) 
{
  return ((val/10*16) + (val%10));
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания из EEPROM часов и минут начала временных режимов
void read_eeprom_time_periodov()
{
  for(byte z=0; z<6; z++)
  {
    nachalo_periodov[z]=EEPROM.read(z);
  } 
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания из EEPROM установленных температур
void read_eeprom_ustan_temper()
{
  for(byte z=6; z<9; z++)
  {
    nachalo_periodov[z]=EEPROM.read(z);
  } 
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания из EEPROM адресов датчиков температур
void read_eeprom_adres_datch()
{
  for(byte z=0; z<8; z++)
  {
    adres_dat_temp_room[z]=EEPROM.read(z+10);             // адрес комнатного датчика
    adres_dat_temp_street[z]=EEPROM.read(z+20);           // адрес уличного датчика             
    adres_dat_temp_water[z]=EEPROM.read(z+30);            // адрес датчика котловой воды
  }
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма определения временного периода (ночного, утреннего или дневного).
void opredelenie_perioda_wremeni()
{
// перевод часов и минут в минуты для удобства последующего сравнения 
  summa_minut[0]=hour*60+minute;                               // для последующего сравнения часы и минуты текущего времени, полученных с часов, переводим в общее количество минут
  summa_minut[1]=nachalo_periodov[0]*60+nachalo_periodov[1];   // общая сумма минут начала ночного периода
  summa_minut[2]=nachalo_periodov[2]*60+nachalo_periodov[3];   // общая сумма минут начала утреннего периода
  summa_minut[3]=nachalo_periodov[4]*60+nachalo_periodov[5];   // общая сумма минут начала дневного периода
// определениe ночного периода и сохранение в переменной period_time значения 0, что означает ночь.
  if(summa_minut[0]>=summa_minut[1] || summa_minut[0]<summa_minut[2])
  {
    period_time=0;
  }                          
// определениe утреннего периода и сохранение в переменной period_time значения 1, что означает утро.
  if(summa_minut[0]>=summa_minut[2] && summa_minut[0]<summa_minut[3])
  {
    period_time=1;
  }
// определениe дневного периода и сохранение в переменной period_time значения 2, что означает день.
  if(summa_minut[0]>=summa_minut[3] && summa_minut[0]<summa_minut[1])
  {
    period_time=2;
  }
}


//////////////////////////////////////////////////////////////////////////////
// подпрограмма грубой проверки считанной температуры
/* 
   Считанная температура сверяется с последней записанной в память температурой (защита от грубых ошибок). 
   Если разница более чем на 3 градуса как в большую так и в меньшую сторону, то запускаем повторное считывание температуры, 
   иначе статусу проверки присваиваем true и завершается подпрограмма.
   Если повторно считанная температура также более чем на 3 градуса как в большую так и в меньшую сторону, то статусу проверки
   выставляем false, иначе true и возвращаемся в основное тело проги.
*/ 
void proverka_temperatury_room()
{
  if(temperatura_room>=temperatura_room_pamyat[2]-3 && temperatura_room<=temperatura_room_pamyat[2]+3)
  {
     proverka_temperatura_room_status=true;
  }
  else
  {   
     temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3);
     if(temperatura_room>=temperatura_room_pamyat[2]-3 && temperatura_room<=temperatura_room_pamyat[2]+3)
     {
       proverka_temperatura_room_status=true;
     }
     else
     {
       proverka_temperatura_room_status=false; 
     }
  }
}


///////////////////////////////////////////////////////////////////////////// 
// подпрограмма определения выхода комнатной температуры за установленный пользователем предел более чем на 1 градус и гистерезис и включения звукого уведомления
void wyhod_temp_room_predel()
{
  byte schetchik_wyhoda_temp_room_predel;
  if(temperatura_room<18 || temperatura_room>26)
  { 
    schetchik_wyhoda_temp_room_predel++;
  }  
  switch(schetchik_wyhoda_temp_room_predel)
  {
    case 1:
    time_snach_progi_wychod_predel_temp=millis();
    break;
    case 10:
    if(formirovanie_intervala(time_snach_progi_wychod_predel_temp)-time_snachala_progi<360000)
    {
      // здесь указать, что будет выполняться, если в течение 6 минут комнатная температура выходила за пределы
      schetchik_wyhoda_temp_room_predel=0;
      time_snach_progi_wychod_predel_temp=time_snachala_progi;
    }
    else
    {  
      schetchik_wyhoda_temp_room_predel=0;
      time_snach_progi_wychod_predel_temp=time_snachala_progi;
    }
    break;
  }
}

  

///////////////////////////////////////////////////////////////////////////// 
// подпрограмма определения отсутствия в течение длительного времени данных от комнатного датчика температуры, то есть наличия проблем с ним.
void problem_datch_room()
{
  time_snach_progi_problem_datch_room;

  
}


///////////////////////////////////////////////////////////////////////////// 
// подпрограмма сравнения полученной с датчика температуры и хранящихся в памяти последних 3 показаний с границами заданной пользователем температуры и управление выходом.
// с целью исключения тактования и возможных краткосрочных незначительных измерений температуры (например открытие окна или двери, дуновение ветра) переключение выхода
// происходит только, если 3 последних показаний температуры также находятся за границами заданной пользователем температуры.
void sravnenie_temp_room_upravl_wychod()
{
  if(proverka_temperatura_room_status==true)             // сначла проверяем прохождение проверки на наличие грубок ошибок. Если да, то переходим к сравнению.
  {
 // если считанная температура и последние 3 показания меньше нижней границы заданной пользователем температуры и на управляемом выходе 0, то данный выход переключается в 1 (котел включается). 
    if(digitalRead(relekotla)==LOW)
    {
      if(temperatura_room<temperatura_room_ustanovka[period_time]-gisteresis && temperatura_room_pamyat[0]<temperatura_room_ustanovka[period_time]-gisteresis && temperatura_room_pamyat[1]<temperatura_room_ustanovka[period_time]-gisteresis && temperatura_room_pamyat[2]<temperatura_room_ustanovka[period_time]-gisteresis)
      {
        digitalWrite(relekotla, HIGH);
      }
    } 
 // если считанная температура и последние 3 показания большее верхней границы заданной пользователем температуры и на управляемом выходе 1, то данный выход переключается в 0 (котел выключается).
    if(digitalRead(relekotla)==HIGH)
    {
      if(temperatura_room>temperatura_room_ustanovka[period_time]+gisteresis && temperatura_room_pamyat[0]>temperatura_room_ustanovka[period_time]+gisteresis && temperatura_room_pamyat[1]>temperatura_room_ustanovka[period_time]+gisteresis && temperatura_room_pamyat[2]>temperatura_room_ustanovka[period_time]+gisteresis)
      {
        digitalWrite(relekotla, LOW);
      }
    }
 // сдвиг хранящейся темпрературы. При этом считанную температуру записываем в самую последнюю переменную
    temperatura_room_pamyat[0]=temperatura_room_pamyat[1];
    temperatura_room_pamyat[1]=temperatura_room_pamyat[2];
    temperatura_room_pamyat[2]=temperatura_room;
  }
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма первоначальных установок начала временных периодов и температур
/* Если при считывании из EEPROM задаваемые пользователем время начала периодов и температуры выходят за рамки 
   установленных программой пределов,то устанавливаются заложенные программой данные.
*/
void nachal_ustanovki()
{
// считываем данные из EEPROM установленные данные (часы и минуты начала временных периодов и температуры)
  read_eeprom_time_periodov();
  read_eeprom_ustan_temper();
  read_eeprom_adres_datch();
// Часы и минуты начала временных периодов проверяем на наличие ошибок(не соответствие временному интервалу) и при необходимости записываем в соответствующие переменные.
  if(nachalo_periodov[0]<18 || nachalo_periodov[0]>23)        // Если считанные из EEPROM часы начала ночи меньше 18 или больше 23, тогда в память и переменную записывам 21.
  {                                                            
    EEPROM.write(0, 21);                                      
    delay(100);
    nachalo_periodov[0]=21;                                    
  } 
  if(nachalo_periodov[1]<0 || nachalo_periodov[1]>59)         // Если считанные из EEPROM минуты меньше 0 или больше 59, тогда в память и переменную записывам 30.
  {
    EEPROM.write(1, 30);                                      
    delay(100);
    nachalo_periodov[1]=30;
  }
  if(nachalo_periodov[2]>10 || nachalo_periodov[2]<3)         // Если считанные из EEPROM часы начала утра меньше 3 или больше 10 часов, тогда в память и переменную записывам 6.
  {
    EEPROM.write(2, 6);                                       
    delay(100);
    nachalo_periodov[2]=6;
  }  
   if(nachalo_periodov[3]<0 || nachalo_periodov[3]>59)         // Если считанные из EEPROM минуты меньше 0 или больше 59, тогда в память и переменную записывам 0.
  {
    EEPROM.write(3, 0);                                       
    delay(100);
    nachalo_periodov[3]=0;
  }
  if(nachalo_periodov[4]>12 || nachalo_periodov[4]<6)         // Если считанные из EEPROM часы начала дня меньше 6 или больше 12 часов, тогда в память и переменную записывам 9.
  {  
    EEPROM.write(4, 9);                                       
    delay(100);
    nachalo_periodov[4]=9;
  }  
    if(nachalo_periodov[5]<0 || nachalo_periodov[5]>59)        // Если считанные из EEPROM минуты меньше 0 или больше 59, тогда в память и переменную записывам 0.
  {
    EEPROM.write(5, 0);                                        
    delay(100);
    nachalo_periodov[5]=0;
  }
  
 // Температуры проверям на соответствие периоду 10-35 градусов и при необходимости записываем в соответствующие переменные.
  if(temperatura_room_ustanovka[0]>35 || temperatura_room_ustanovka[0]<10)   // если считанная из EEPROM температура ночного периода меньше 10 или выше 35 градусов,   
  {                                                                          // тогда в память и переменную записывам 19.
    EEPROM.write(6, 19);                                      
    delay(100);
    temperatura_room_ustanovka[0]=19;                         
  }  
  if(temperatura_room_ustanovka[1]>35 || temperatura_room_ustanovka[1]<10)   // если считанная из EEPROM температура утреннего периода меньше 10 или выше 35 градусов,  
  {                                                                          // тогда в память и переменную записывам 23.
    EEPROM.write(7, 23);                                      
    delay(100);
    temperatura_room_ustanovka[1]=23;                         
  }
  if(temperatura_room_ustanovka[2]>35 || temperatura_room_ustanovka[2]<10)   // если считанная из EEPROM температура дневного период меньше 10 или выше 35 градусов, 
  {                                                                          // тогда в память и переменную записывам 21.
    EEPROM.write(8, 21);                                      
    delay(100);
    temperatura_room_ustanovka[2]=21;                         
  }
}   
 
/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd слова "Ночь"
void wywod_na_lcd_slova_Noch()
{
  lcd.print("Ho");
  lcd.write(6);
  lcd.write(4);
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd слова "Утро"
void wywod_na_lcd_slova_Utro()
{
  lcd.write(7);
  lcd.write(8);
  lcd.print("po");
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd слова "День"
void wywod_na_lcd_slova_Den()
{
  lcd.write(3);
  lcd.print("e");
  lcd.write(5);
  lcd.write(4);
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd температуры со значком градуса
void wywod_na_lcd_temper(float wywod_temper)
{
  if(wywod_temper<10)
  {
    lcd.print(" ");
  }
  lcd.print(wywod_temper, 1);
  lcd.write(2);   
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd времени-часов
void wywod_na_lcd_hour(byte wywod_hour)
{
  if(wywod_hour<10)
  {
    lcd.print(" ");
  }
  lcd.print(wywod_hour);
} 
 
 
 /////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd времени-минут
void wywod_na_lcd_min(byte wywod_minute)
{
  if(wywod_minute<10)
  {
    lcd.print("0");
  }
  lcd.print(wywod_minute);
} 

  
/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода текущих данных на lcd дисплей при переходе из основной программы
// с целью исключения повтороного вывода на дисплей информации, которая не изенилась с прошлого обращения к подпрограмме, производиться ее сравнение
void wywod_na_lcd_tekusch()
{
// формируем сначала вывод информации, которая меняется относительно редко (часы, минуты, температура)
//////////////// верхняя строка lcd  
// вывод текущего времени
  if(hour!=hour_predyd)
  {
    lcd.setCursor(0, 0);
    wywod_na_lcd_hour(hour);                                 // переход к подпрограмме вывода на lcd текущего времени - часов 
    hour_predyd=hour;
  }
  if(minute!=minute_predyd)
  {
    lcd.setCursor(3, 0);
    wywod_na_lcd_min(minute);                                // переход к подпрограмме вывода на lcd текущего времени - минут
    minute_predyd=minute;
  }
// вывод комнатной температуры и значка градус
  if(temperatura_room!=temperatura_room_predyd)
  {
    lcd.setCursor(11, 0);
    wywod_na_lcd_temper(temperatura_room);                   // переход к подпрограмме вывода на lcd температуры со значком градуса 
    lcd.setCursor(15, 0);                                    // обрезаем второй знак после запятой и ставим вместо него значок градуса
    lcd.write(2); 
    temperatura_room_predyd=temperatura_room;
  }
//////////////// нижняя строка lcd  
// вывод уличной температуры
  if(temperatura_street!=temperatura_street_predyd)
  {
    lcd.setCursor(7, 1);
    lcd.print("Out");
    lcd.setCursor(11, 1);
    if(temperatura_street>=0)
    {
      lcd.print(" ");
    }
    lcd.print(temperatura_street, 1);
    lcd.setCursor(15, 1);
    lcd.write(2);
    temperatura_street_predyd=temperatura_street;
  //  
  }
// формирование мигающего двоеточия между часами и минутами (0,75 сек. светятся, 0,45 не светятся)
  unsigned long miganie_dvoet=formirovanie_intervala(time_snach_progi_migania_dvoet);
  lcd.setCursor(2, 0);
  if(miganie_dvoet<750)    // 0,75 сек знаки светятся
  {
    lcd.print(":");
  }
  else
  {
    lcd.print(" ");
  }
  if(miganie_dvoet>1200)
  {
    time_snach_progi_migania_dvoet=time_snachala_progi;
  }  
// последовательный вывод названия временного периода и, если котел включен, то сведения об этом
// первые 0,5 сек. ничего нет
  unsigned long miganie_sost_kotla=formirovanie_intervala(time_snach_progi_migania_sost_kotla);
  lcd.setCursor(6, 0);
  // первые 0,5 сек. ничего нет 
  if(miganie_sost_kotla<500)
  {
    lcd.print("    ");
  }
// вывод первой буквы названия режима
  if(miganie_sost_kotla>500 && miganie_sost_kotla<=1250)
  {    
    switch(period_time)
    {
      case 0:
      lcd.print("H");
      break;
      case 1:
      lcd.write(7);
      break;
      case 2:
      lcd.write(3);
      break;
    }
    lcd.print("   ");
  }
 // вывод 1-й и 2-й букв названия режима  
  if(miganie_sost_kotla>1250 && miganie_sost_kotla<=2000)
  {    
    switch(period_time)
    {
      case 0:
      lcd.print("Ho");
      break;
      case 1:
      lcd.write(7);
      lcd.write(8);
      break;
      case 2:
      lcd.write(3);
      lcd.print("e");
      break;
    }
    lcd.print("  ");
  }
 // вывод 1-й, 2-й и 3-й букв названия режима  
  if(miganie_sost_kotla>2000 && miganie_sost_kotla<=2750)
  {               
    switch (period_time)
    {
      case 0:
      lcd.print("Ho");
      lcd.write(6);
      break;
      case 1:
      lcd.write(7);
      lcd.write(8);
      lcd.print("p");
      break;
      case 2:
      lcd.write(3);
      lcd.print("e");
      lcd.write(5);
      break;
    }
    lcd.print(" ");
  }
 // вывод всего слова названия режима 
  if(miganie_sost_kotla>2750 && miganie_sost_kotla<=3500)
  {     
    switch (period_time)
    {
      case 0:
      lcd.print("Ho");
      lcd.write(6);
      lcd.write(4);
      break;
      case 1:
      lcd.write(7);
      lcd.write(8);
      lcd.print("po");
      break;
      case 2:
      lcd.write(3);
      lcd.print("e");
      lcd.write(5);
      lcd.write(4);
      break;
    }
  }
 // Если на выходе котла 0, то обнуляем временной интервал для повторного вывода временного периода 
  if(miganie_sost_kotla>3500 && digitalRead(relekotla)==LOW)
  { 
    time_snach_progi_migania_sost_kotla=time_snachala_progi;
    miganie_sost_kotla=formirovanie_intervala(time_snach_progi_migania_sost_kotla);
  }
// 0,5 сек. ничего нет 
  
  if(miganie_sost_kotla>3500 && miganie_sost_kotla<=4000)
  {
    
    lcd.print("    ");
  }
// далее, если на выход котла 1, то выводим значки пламени
  if(miganie_sost_kotla>4000 && miganie_sost_kotla<=4750)
  {
    
    lcd.write(1);
    lcd.print("   ");
  }  
// следующие 0,75 сек. рисуем два значка пламени  
  if(miganie_sost_kotla>4750 && miganie_sost_kotla<=5500)
  {
    
    lcd.write(1);
    lcd.write(1);
    lcd.print("  ");
  }
// следующие 0,75 сек. рисуем три значка пламени   
  if(miganie_sost_kotla>5500 && miganie_sost_kotla<=6250)
  {
    
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.print(" "); 
  }   
// следующие 0,75 сек. рисуем четыре значка пламени   
  if(miganie_sost_kotla>6250 && miganie_sost_kotla<=7000)
  {
    
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
  }
 // обнуляем временной показатель 
  if(miganie_sost_kotla>7000)
  { 
    time_snach_progi_migania_sost_kotla=time_snachala_progi;
  }
} 


////////////////////////////////////////////////////////////////////////////
// подпрограмма формирования интервала мигания выбранного для изменения параметра при нахождении в меню программирования
void miganie_parametra_lcd()
{
  unsigned long miganie_parametra=formirovanie_intervala(time_snach_progi_parametra_menu);       
  if(miganie_parametra<=750)
  {
    miganie_parametra_programmirovaniya=true;
  }
  else
  {
    miganie_parametra_programmirovaniya=false;
  }
  if(miganie_parametra>1200)
  {
    time_snach_progi_parametra_menu=time_snachala_progi;
  }   
}

  
////////////////////////////////////////////////////////////////////////////
// подпрограмма программирования - установки времени, начала временных периодов(ночи, утра и дня), температуры временных периодов и записи (удаления) адресов датчиков температуры
void programmirovanie()
{
  // считываем из EEPROM часы и минуты начала временных периодов, установленных температур и адреса датчиков, а также текущие дату и время
  read_eeprom_time_periodov();
  read_eeprom_ustan_temper();
  read_eeprom_adres_datch();
  poluchenie_wremeni();                                   // переход к подпрограмме считывания времени с часов
  time_snach_progi_wychoda_menu=millis();                 // для формирования интервала с нуля. 
  time_snach_progi_parametra_menu=time_snach_progi_wychoda_menu;   // для формирования интервала мигания выбранного для изменения параметра
  lcd.clear();
  delay(1000);
// создаем циклический опрос нажатия кнопок, вывод изображения данных на lcd
  cikl_programm:
    wdt_reset(); 
    if(formirovanie_intervala(time_snach_progi_wychoda_menu)>interval_wychoda_menu || status_programmirovaniya==0)
    {
      goto na_wychod;                                   // если интервал достиг задаваемого программистом и не нажата ни одна кнопка, то осуществляется выход из подпрограммы программирования
    }
    opredel_nashat_knopok();                            // переход к подпрограмме определения нажатия кнопок
    nashata_knopka_pravo();                             // переход к подпрограмме и выполнение действий при нажатии кнопки право
    nashata_knopka_levo();                              // переход к подпрограмме и выполнение действий при нажатии кнопки лево
    nashata_knopka_verch();                             // переход к подпрограмме и выполнение действий при нажатии кнопки верх
    nashata_knopka_vniz();                              // переход к подпрограмме и выполнение действий при нажатии кнопки вниз
    nashata_knopka_select();                            // переход к подпрограмме и выполнение действий при нажатии кнопки select
    miganie_parametra_lcd();                            // переход к подпрограмме определения продожительности мигания выбранного в меню параметра
    opredel_stranizy_lcd();                             // переход к подпрограмме, которая определяет, какую из двух страниц выводить на lcd
  goto cikl_programm;
// завершение цикла опроса кнопок и т.д. 
  na_wychod:
  status_programmirovaniya=1;
  lcd.clear();
// первоначальный вывод на lcd текущих данных
  lcd.setCursor(0, 0);
  wywod_na_lcd_hour(hour);                                 // переход к подпрограмме вывода на lcd текущего времени - часов 
  lcd.setCursor(3, 0);
  wywod_na_lcd_min(minute);                                // переход к подпрограмме вывода на lcd текущего времени - минут
  lcd.setCursor(11, 0);
  wywod_na_lcd_temper(temperatura_room);                   // переход к подпрограмме вывода на lcd температуры со значком градуса 
  lcd.setCursor(15, 0);                                    // обрезаем второй знак после запятой и ставим вместо него значок градуса
  lcd.write(2); 
  lcd.setCursor(7, 1);
  lcd.print("Out");
  lcd.setCursor(10, 1);
  if(temperatura_street>=0)
  {
    lcd.print(" ");
  }
  wywod_na_lcd_temper(temperatura_street);
}    

        
//////////////////////////////////////////////////////////////////////////////
// подпрограмма определения нажатия кнопок
void opredel_nashat_knopok()
{
  int temp_temp=1023;
  temp_temp=analogRead(0);                                     // считываем данные
//определяем нажатие кнопки "ВВЕРХ" (показатель 99)
  if(temp_temp>50 && temp_temp<150)   
  {
    knopka_verch=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования 
  } 
//определяем нажатие кнопки "ВНИЗ" (показатель 255)
  if(temp_temp>200 && temp_temp<300)  
  {
    knopka_vniz=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования
  }  
//определяем нажатие кнопки "ПРАВО" (показатель 0) 
  if(temp_temp<30)                         
  {
    knopka_pravo=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования
  }  
//определяем нажатие кнопки "ЛЕВО" (показатель 409)  
  if(temp_temp>350 && temp_temp<500)  
  {
    knopka_levo=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования
  }
// определяем нажатие кнопки Select (показатель 639) 
  if(temp_temp>550 && temp_temp<750)  
  {
    knopka_select=true;
    time_snach_progi_wychoda_menu=millis();     
  }
  temp_temp=1023;
  delay(200);
}

    
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка право
void nashata_knopka_pravo()
{
  if(knopka_pravo==true)
  {
    knopka_pravo=false;
// на 1-й странице
    if(status_programmirovaniya>=1 && status_programmirovaniya<=6)
    {  
      if(status_programmirovaniya==6)
      {
        status_programmirovaniya=1;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 2-й странице
    if(status_programmirovaniya>=11 && status_programmirovaniya<=15)
    {
      if(status_programmirovaniya==15)
      {
        status_programmirovaniya=11;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 3-й странице
    if(status_programmirovaniya>=21 && status_programmirovaniya<=25)
    {
      if(status_programmirovaniya==25)
      {
        status_programmirovaniya=21;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 4-й странице
    if(status_programmirovaniya>=31 && status_programmirovaniya<=35)
    {
      if(status_programmirovaniya==35)
      {
        status_programmirovaniya=31;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 5-й странице
    if(status_programmirovaniya>=41 && status_programmirovaniya<=47)
    {
      if(status_programmirovaniya==47)
      {
        status_programmirovaniya=41;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 6-й странице
    if(status_programmirovaniya>=51 && status_programmirovaniya<=55)
    {
      if(status_programmirovaniya==55)
      {
        status_programmirovaniya=51;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 7-й странице
    if(status_programmirovaniya==61 || status_programmirovaniya==62)
    {
      if(status_programmirovaniya==62)
      {
        status_programmirovaniya=61;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 8-й странице
    if(status_programmirovaniya==71 || status_programmirovaniya==72)
    {
      if(status_programmirovaniya==72)
      {
        status_programmirovaniya=71;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 9-й странице
    if(status_programmirovaniya==81 || status_programmirovaniya==82)
    {
      if(status_programmirovaniya==82)
      {
        status_programmirovaniya=81;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 11-й странице
    if(status_programmirovaniya>100 && status_programmirovaniya<104)
    {
      if(status_programmirovaniya==103)
      {
        status_programmirovaniya=101;
      }
      else
      {
        status_programmirovaniya++;
      }
    }        
  }
}
  
  
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка лево
void nashata_knopka_levo()
{
  if(knopka_levo==true)
  {
    knopka_levo=false;
// на 1-й странице
    if(status_programmirovaniya>=1 && status_programmirovaniya<=6)
    {  
      if(status_programmirovaniya==1)
      {
        status_programmirovaniya=6;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 2-й странице
    if(status_programmirovaniya>=11 && status_programmirovaniya<=15)
    {
      if(status_programmirovaniya==11)
      {
        status_programmirovaniya=15;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 3-й странице
    if(status_programmirovaniya>=21 && status_programmirovaniya<=25)
    {
      if(status_programmirovaniya==21)
      {
        status_programmirovaniya=25;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 4-й странице
    if(status_programmirovaniya>=31 && status_programmirovaniya<=35)
    {
      if(status_programmirovaniya==31)
      {
        status_programmirovaniya=35;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 5-й странице
    if(status_programmirovaniya>=41 && status_programmirovaniya<=47)
    {
      if(status_programmirovaniya==41)
      {
        status_programmirovaniya=47;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 6-й странице
    if(status_programmirovaniya>=51 && status_programmirovaniya<=55)
    {
      if(status_programmirovaniya==51)
      {
        status_programmirovaniya=55;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 7-й странице
    if(status_programmirovaniya==61 || status_programmirovaniya==62)
    {
      if(status_programmirovaniya==61)
      {
        status_programmirovaniya=62;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 8-й странице
    if(status_programmirovaniya==71 || status_programmirovaniya==72)
    {
      if(status_programmirovaniya==71)
      {
        status_programmirovaniya=72;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 9-й странице
    if(status_programmirovaniya==81 || status_programmirovaniya==82)
    {
      if(status_programmirovaniya==81)
      {
        status_programmirovaniya=82;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 11-й странице
    if(status_programmirovaniya>100 && status_programmirovaniya<104)
    {
      if(status_programmirovaniya==101)
      {
        status_programmirovaniya=103;
      }
      else
      {
        status_programmirovaniya--;
      }
    }    
  }
} 
  
  
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка верх
void nashata_knopka_verch()
{   
  if(knopka_verch==true)
  {
    knopka_verch=false;  
    if(status_programmirovaniya==14 || status_programmirovaniya==24 || status_programmirovaniya==34 || status_programmirovaniya==46 || status_programmirovaniya==102)
    {
      if(status_wybora_save==false)
      {
        status_wybora_save=true;
      }
      else
      {
        status_wybora_save=false;
      }
    }  
    switch(status_programmirovaniya)
    {
   // увеличиваем часы начала ночного периода
      case 11:
      if(nachalo_periodov[0]==23)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[0]=0;
      }
      else
      {
        nachalo_periodov[0]++;                                // увеличиваем показатель
      }
      break;    
   // увеличиваем минуты начала ночного периода
      case 12:
      if(nachalo_periodov[1]==59)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[1]=0;
      }
      else
      {
        nachalo_periodov[1]++;                               // увеличиваем показатель
      }
      break;
   // увеличиваем температуру ночного периода
      case 13:
      if(temperatura_room_ustanovka[0]==35)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[0]=10;
      }
      else
      {
        temperatura_room_ustanovka[0]++;                           // увеличиваем показатель
      }
      break;
   // увеличиваем часы начала утреннего периода
      case 21:
      if(nachalo_periodov[2]==23)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[2]=0;
      }
      else
      {
        nachalo_periodov[2]++;                                // увеличиваем показатель
      }
      break;
   // увеличиваем минуты начала утреннего периода
      case 22:
      if(nachalo_periodov[3]==59)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[3]=0;
      }
      else
      {
        nachalo_periodov[3]++;                               // увеличиваем показатель
      }
      break;
   // увеличиваем температуру утреннего периода
      case 23:
      if(temperatura_room_ustanovka[1]==35)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[1]=10;
      }
      else
      {
        temperatura_room_ustanovka[1]++;                           // увеличиваем показатель
      }
      break;    
   // увеличиваем часы начала дневного периода
      case 31:
      if(nachalo_periodov[4]==23)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[4]=0;
      }
      else
      {
        nachalo_periodov[4]++;                                // увеличиваем показатель
      }
      break;
   // увеличиваем минуты начала утреннего периода
      case 32:
      if(nachalo_periodov[5]==59)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[5]=0;
      }
      else
      {
        nachalo_periodov[5]++;                               // увеличиваем показатель
      }
      break;
   // увеличиваем температуру утреннего периода
      case 33:
      if(temperatura_room_ustanovka[2]==35)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[2]=10;
      }
      else
      {
        temperatura_room_ustanovka[2]++;                           // увеличиваем показатель
      }
      break;
   // увеличиваем часы текущего времени
      case 41:
      if(hour==23)                                           // часы должны быть в пределах от 0 до 24.
      {
        hour=0;
      }
      else
      {
        hour++;                                               // увеличиваем показатель
      }
      break;
   // увеличиваем минуты текущего времени
      case 42:
      if(minute==59)                                         // минуты должны быть в пределах от 0 по 59.
      {
        minute=0;
      }
      else
      {
        minute++;                                             // увеличиваем показатель
      }
      break;
   // увеличиваем текущую дату
      case 43:
      if(date==31)                                          // число должно быть в пределах от 1 до 31.
      {
        date=1;
      }
      else
      {
        date++;                                               // увеличиваем показатель
      }
      break;
   // увеличиваем текущий месяц
      case 44:
      if(month==12)
      {
        month=1; 
      }
      else
      {
        month++;                                              // увеличиваем показатель
      }
      break;
   // увеличиваем текущий год
      case 45:
      if(year==99)                                           // год не может быть больше 99.
      {
        year=0;
      }
      else
      {
        year++;                                              // увеличиваем показатель
      }
      break;
   // изменяем присваемый подключенныому датчику статус - комнатный, уличный или водяной
      case 101:
      if(wybor_status_zapis_datch==3)
      {
        wybor_status_zapis_datch=1;
      }
      else
      {
        wybor_status_zapis_datch++;
      }
      break;     
    }    
  }
}
 
 
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка вниз
void nashata_knopka_vniz()
{    
  if(knopka_vniz==true)
  {
    knopka_vniz=false;
    if(status_programmirovaniya==14 || status_programmirovaniya==24 || status_programmirovaniya==34 || status_programmirovaniya==46 || status_programmirovaniya==102)
    {
      if(status_wybora_save==false)
      {
        status_wybora_save=true;
      }
      else
      {
        status_wybora_save=false;
      }
    }  
    switch(status_programmirovaniya)
    {
   // уменьшаем часы начала ночного периода
      case 11:
      if(nachalo_periodov[0]==0)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[0]=23;
      }
      else
      {
        nachalo_periodov[0]--;                                // увеличиваем показатель
      }
      break;    
   // уменьшаем минуты начала ночного периода
      case 12:
      if(nachalo_periodov[1]==0)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[1]=59;
      }
      else
      {
        nachalo_periodov[1]--;                               // увеличиваем показатель
      }
      break;
   // уменьшаем температуру ночного периода
      case 13:
      if(temperatura_room_ustanovka[0]==10)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[0]=35;
      }
      else
      {
        temperatura_room_ustanovka[0]--;                           // увеличиваем показатель
      }
      break;
   // уменьшаем часы начала утреннего периода
      case 21:
      if(nachalo_periodov[2]==0)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[2]=23;
      }
      else
      {
        nachalo_periodov[2]--;                                // увеличиваем показатель
      }
      break;
   // уменьшаем минуты начала утреннего периода
      case 22:
      if(nachalo_periodov[3]==0)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[3]=59;
      }
      else
      {
        nachalo_periodov[3]--;                               // увеличиваем показатель
      }
      break;
   // уменьшаем температуру утреннего периода
      case 23:
      if(temperatura_room_ustanovka[1]==10)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[1]=35;
      }
      else
      {
        temperatura_room_ustanovka[1]--;                           // увеличиваем показатель
      }
      break;  
   // уменьшаем часы начала дневного периода
      case 31:
      if(nachalo_periodov[4]==0)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[4]=23;
      }
      else
      {
        nachalo_periodov[4]--;                                // увеличиваем показатель
      }
      break;
   // уменьшаем минуты начала утреннего периода
      case 32:
      if(nachalo_periodov[5]==0)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[5]=59;
      }
      else
      {
        nachalo_periodov[5]--;                               // увеличиваем показатель
      }
      break;
   // уменьшаем температуру утреннего периода
      case 33:
      if(temperatura_room_ustanovka[2]==10)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[2]=35;
      }
      else
      {
        temperatura_room_ustanovka[2]--;                           // увеличиваем показатель
      }
      break;
   // уменьшаем часы текущего времени
      case 41:
      if(hour==0)                                           // часы должны быть в пределах от 0 до 24.
      {
        hour=23;
      }
      else
      {
        hour--;                                               // увеличиваем показатель
      }
      break;
   // уменьшаем минуты текущего времени
      case 42:
      if(minute==0)                                         // минуты должны быть в пределах от 0 по 59.
      {
        minute=59;
      }
      else
      {
        minute--;                                             // увеличиваем показатель
      }
      break;
  // уменьшаем текущую дату
      case 43:
      if(date==1)                                          // число должно быть в пределах от 1 до 31.
      {
        date=31;
      }
      else
      {
        date--;                                               // увеличиваем показатель
      }
      break;
   // уменьшаем текущий месяц
      case 44:
      if(month==1)
      {
        month=12; 
      }
      else
      {
        month--;                                              // увеличиваем показатель
      }
      break;
   // уменьшаем текущий год
      case 45:
      if(year==0)                                           // год не может быть больше 99.
      {
        year=99;
      }
      else
      {
        year--;                                              // увеличиваем показатель
      }
      break;
   // изменяем присваемый подключенныому датчику статус - комнатный, уличный или водяной
      case 101:
      if(wybor_status_zapis_datch==1)
      {
        wybor_status_zapis_datch=3;
      }
      else
      {
        wybor_status_zapis_datch--;
      }
      break;          
    }
  } 
} 

  
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка select
void nashata_knopka_select()
{      
  if(knopka_select==true)
  {
    knopka_select=false;                        // для исключения учитывания факта нажатой кнопки при переходах из меню в подменю и обратно
    switch(status_programmirovaniya)   
    {
   // переходы в подменю или выход из меню
      case 1:
      status_programmirovaniya=11;              // переход в подменю установок параметров ночного режима
      break;
      case 2:
      status_programmirovaniya=21;              // переход в подменю установок параметров утреннего режима
      break;
      case 3:
      status_programmirovaniya=31;              // переход в подменю установок параметров дневного режима
      break;
      case 4:
      status_programmirovaniya=41;              // переход в подменю установок текущих даты и времени
      break;
      case 5:
      status_programmirovaniya=51;              // переход в подменю датчики
      break;
      case 6:
      status_programmirovaniya=0;               // команда на выход
      break;             
   // сохранение параметров ночного периода, при условии выбора Yes 
      case 14:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        EEPROM.write(0, nachalo_periodov[0]);
        delay(100);
        EEPROM.write(1, nachalo_periodov[1]);
        delay(100);
        EEPROM.write(6, temperatura_room_ustanovka[0]);
        delay(100);
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю ночного периода в основное меню
      case 15:
      status_programmirovaniya=1;
      break;  
   // сохранение параметров утреннего периода, при условии выбора Yes 
      case 24:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        EEPROM.write(2, nachalo_periodov[2]);
        delay(100);
        EEPROM.write(3, nachalo_periodov[3]);
        delay(100);
        EEPROM.write(7, temperatura_room_ustanovka[1]);
        delay(100);
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю утреннего периода в основное меню
      case 25:
      status_programmirovaniya=1;
      break;     
   // сохранение параметров дневного периода, при условии выбора Yes 
      case 34:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        EEPROM.write(4, nachalo_periodov[4]);
        delay(100);
        EEPROM.write(5, nachalo_periodov[5]);
        delay(100);
        EEPROM.write(8, temperatura_room_ustanovka[8]);
        delay(100);
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю дневного периода в основное меню
      case 35:
      status_programmirovaniya=1;
      break;     
   // сохранение текущих даты и времени, при условии выбора Yes 
      case 46:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        zapis_wremeni();
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю часов в основное меню
      case 47:
      status_programmirovaniya=1;
      break;       
   // переход из подменю датчики в подменю комнантный датчик  
      case 51:
      status_programmirovaniya=62;             
      break;
   // переход из подменю датчики в подменю уличный датчик   
      case 52:
      status_programmirovaniya=72;             
      break;
   // переход из подменю датчики в подменю водяной датчик
      case 53:
      status_programmirovaniya=82;             
      break;
   // переход из подменю датчики в подменю новый датчик  
      case 54:
      proverka_podkluch_datchikov_temp();           // сначала переход в подпрограмму определения новых подключенных датчиков
      status_programmirovaniya=91;                  // переход в подменю новый датчик
      break;
   // переход из подменю датчики в основное меню     
      case 55:
      status_programmirovaniya=1;
      break;
   // удаление комнатного датчика    
      case 61:
      for(byte h1=0; h1<8; h1++)
      {
        EEPROM.write(h1+10, 255);
        adres_dat_temp_room[h1]=255;
        delay(100);
      }
      break;
   // переход из подменю уличный датчик в основное меню     
      case 62:
      status_programmirovaniya=51;
      break;       
   // удаление уличного датчика
      case 71:
      for(byte h2=0; h2<8; h2++)
      {
        EEPROM.write(h2+20, 255);
        adres_dat_temp_street[h2]=255;
        delay(100);
      }
      break;
   // переход из подменю уличный датчик в основное меню     
      case 72:
      status_programmirovaniya=51;
      break;       
   // удаление водяного датчика 
      case 81:
      for(byte h3=0; h3<8; h3++)
      {
        EEPROM.write(h3+30, 255);
        adres_dat_temp_water[h3]=255;
        delay(100);
      }
      break; 
   // переход из подменю водяной датчик в основное меню     
      case 82:
      status_programmirovaniya=51;
      break;
   // переход из подменю новый датчик в подменю датчики    
      case 91:
      status_programmirovaniya=51;
      break;
   // сохранение выбранного статуса датчику температуры и запись его адреса в EEPROM, при условии выбора Yes 
      case 102:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        for(byte x1=0; x1<8; x1++)
        {
          if(status_schit_datch_new[0]==true)
          {
            temp_adres[x1]=temp_adres_datch_1[x1];    
          }
          if(status_schit_datch_new[1]==true)
          {           
            temp_adres[x1]=temp_adres_datch_2[x1];
          }       
          if(status_schit_datch_new[2]==true)
          {
            temp_adres[x1]=temp_adres_datch_3[x1];
          }
          EEPROM.write(x1+wybor_status_zapis_datch*10, temp_adres[x1]);
          delay(100);
        }
      }
      status_programmirovaniya=51;
      break;
   // переход из записи нового датчика в подменю датчики    
      case 103:
      status_programmirovaniya=51;
      break;    
    }
  }     
}

    
//////////////////////////////////////////////////////////
// подпрограмма определения выводимой на lcd страницы с учетом нажатых кнопок "ПРАВО", "ЛЕВО" и "Select"
void opredel_stranizy_lcd()
{
  if(status_programmirovaniya>0 && status_programmirovaniya<7)
  {
    straniza_programmirovaniya_1();
  }
  if(status_programmirovaniya>10 && status_programmirovaniya<16)
  {
    straniza_programmirovaniya_2();
  }
  if(status_programmirovaniya>20 && status_programmirovaniya<26)
  {
    straniza_programmirovaniya_3();
  }
  if(status_programmirovaniya>30 && status_programmirovaniya<36)
  {
    straniza_programmirovaniya_4();
  }
  if(status_programmirovaniya>40 && status_programmirovaniya<48)
  {
    straniza_programmirovaniya_5();
  }
  if(status_programmirovaniya>50 && status_programmirovaniya<56)
  {
    straniza_programmirovaniya_6();
  }
  if(status_programmirovaniya>60 && status_programmirovaniya<63)
  {
    straniza_programmirovaniya_7();
  }
  if(status_programmirovaniya>70 && status_programmirovaniya<73)
  {
    straniza_programmirovaniya_8();
  }
  if(status_programmirovaniya>80 && status_programmirovaniya<83)
  {
    straniza_programmirovaniya_9();
  }
  if(status_programmirovaniya>90 && status_programmirovaniya<92)
  {
    straniza_programmirovaniya_10();
  }
  if(status_programmirovaniya>100 && status_programmirovaniya<104)
  {
    straniza_programmirovaniya_11();
  }
} 


////////////////////////////////////////
// подпрограмма формирования изображения 1-й страницы на lcd (1 строка - ночь, день, утро; 2 строка - часы, датчики, выход из программирования)
void straniza_programmirovaniya_1()
{
// 1 строка
// с 0 позиции - Ночь
  lcd.setCursor(0, 0);
  if(status_programmirovaniya==1 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                  // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_slova_Noch();                // переход к подпрограмме вывода слова "Ночь"
  }
  lcd.print("  ");
// с 6 позиции - Утро
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==2 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_slova_Utro();                // переход к подпрограмме вывода слова "Утро"
  }
  lcd.print("  ");
// с 12 позиции - День
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==3 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_slova_Den();                   // переход к подпрограмме вывода слова "День"
  }
// 2 строка
// с 0 позиции - Часы
  lcd.setCursor(0, 1);
  if(status_programmirovaniya==4 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Time  ");
  }
// с 6 позиции - Датчики
  lcd.setCursor(6, 1);
  if(status_programmirovaniya==5 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.write(3);
    lcd.print("a");
    lcd.write(8);
    lcd.write(6);
    lcd.print("  ");
  }  
// с 12 позиции - Выход
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==6 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}
  
  
/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 2-й страницы на lcd (1 строка - ночь, часы, минуты, температура; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_2()
{
// 1 строка
// с 0 позиции - Ночь 
  lcd.setCursor(0, 0);
  wywod_na_lcd_slova_Noch();                                           // переход к подпрограмме вывода слова "Ночь"
  lcd.print(" ");
// с 5 позиции - часы начала ночного периода
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==11 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(nachalo_periodov[0]);                           // переход к подпрограмме вывода времени начала периода - часов
  }
  lcd.print(":");
 // с 8 позиции - минуты начала ночного периода 
  lcd.setCursor(8, 0);
  if(status_programmirovaniya==12 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(nachalo_periodov[1]);                       // переход к подпрограмме вывода времени начала периода - минут
  }  
  lcd.print(" ");
// с 11 позиции - температура ночного периода
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==13 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_temper(temperatura_room_ustanovka[0]);                  // переход к подпрограмме вывода температуры
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==14 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==15 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}
  
  
/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 3-й страницы на lcd (1 строка - утро, часы, минуты, температура; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_3()
{
// 1 строка
// с 0 позиции - Утро 
  lcd.setCursor(0, 0);
  wywod_na_lcd_slova_Utro();                                           // переход к подпрограмме вывода слова "Утро"
  lcd.print(" ");
// с 5 позиции - часы начала утреннего периода
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==21 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(nachalo_periodov[2]);                           // переход к подпрограмме вывода времени начала периода - часов
  }
  lcd.print(":");
 // с 8 позиции - минуты начала утреннего периода 
  lcd.setCursor(8, 0);
  if(status_programmirovaniya==22 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(nachalo_periodov[3]);                       // переход к подпрограмме вывода времени начала периода - минут
  }  
  lcd.print(" ");
// с 11 позиции - температура утреннего периода
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==23 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_temper(temperatura_room_ustanovka[1]);                  // переход к подпрограмме вывода температуры
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==24 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==25 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 4-й страницы на lcd (1 строка - день, часы, минуты, температура; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_4()
{
// 1 строка
// с 0 позиции - День 
  lcd.setCursor(0, 0);
  wywod_na_lcd_slova_Den();                                            // переход к подпрограмме вывода слова "День"
  lcd.print(" ");
// с 5 позиции - часы и минуты начала дневного периода
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==31 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(nachalo_periodov[4]);                           // переход к подпрограмме вывода времени начала периода - часов
  }
  lcd.print(":");
 // с 8 позиции - минуты начала утреннего периода 
  lcd.setCursor(8, 0);
  if(status_programmirovaniya==32 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(nachalo_periodov[5]);                       // переход к подпрограмме вывода времени начала периода - минут
  }  
  lcd.print(" ");
// с 11 позиции - температура дневного периода
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==33 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_temper(temperatura_room_ustanovka[2]);                  // переход к подпрограмме вывода температуры
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==34 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==35 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}  
  
  
/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 5-й страницы на lcd (1 строка - текущие часы, минуты, число, месяц и год; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_5()
{  
// 1 строка
// с 0 позиции - часы 
  lcd.setCursor(0, 0);
  if(status_programmirovaniya==41 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(hour);                     // переход к подпрограмме вывода на lcd текущего времени - часов и минут через двоеточие
  }
  lcd.print(":");
  lcd.setCursor(3, 0);
  if(status_programmirovaniya==42 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(minute);                     // переход к подпрограмме вывода на lcd текущего времени - часов и минут через двоеточие
  }
  lcd.print(" ");  
// с 6 позиции - текущее число
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==43 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(date<10)
    {
      lcd.print(" ");
    }
    lcd.print(date);
  }
  lcd.print("-");
// с 9 позиции - текущий месяц
  lcd.setCursor(9, 0);
  if(status_programmirovaniya==44 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(month<10)
    {
      lcd.print("0");
    }
    lcd.print(month);
  }
  lcd.print("-20");
// с 14 позиции - текущий год
  lcd.setCursor(14, 0);
  if(status_programmirovaniya==45 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(year<10)
    {
      lcd.print("0");
    }
    lcd.print(year);
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==46 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==47 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}  


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 6-й страницы на lcd (1 строка -  комнатный, уличный и водяной датчики; 2 строка - новый датчик, выход на 1 стр.)
void straniza_programmirovaniya_6()
{  
// 1 строка
// с 0 позиции -  комнатный датчик D-room
  lcd.setCursor(0, 0);
  if(status_programmirovaniya==51 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Room");
  }
  lcd.setCursor(4, 0);
  lcd.print(" ");
// с  5 позиции - уличный 
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==52 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Stret ");
  }
// с  11 позиции - водяной 
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==53 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Water");
  }
// 1 строка
// с позиции 0 - новый датчик - New
  lcd.setCursor(0, 1);
  if(status_programmirovaniya==54 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("New         ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==55 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Exit");
  }
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 7-й страницы на lcd (1 строка -  комнатный датчик, удалить, выход на 1 стр.; 2 строка - адрес комнатного датчика)
void straniza_programmirovaniya_7()
{  
// 1 строка
// с 0 позиции -  комнатный датчик Room
  lcd.setCursor(0, 0);
  lcd.print("Room  ");
// с  6 позиции 
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==61 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Delet ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==62 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Exit");
  }
// 2 строка
// с позиции 0 - адрес датчика
  lcd.setCursor(0, 1);
  for(byte f1=0; f1<8; f1++)
  {
    lcd.print(adres_dat_temp_room[f1], HEX);
  }
  lcd.print("       ");
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 8-й страницы на lcd (1 строка -  уличный датчик, удалить, выход на 1 стр.; 2 строка - адрес комнатного датчика)
void straniza_programmirovaniya_8()
{  
// 1 строка
// с 0 позиции -  уличный датчик Stret
  lcd.setCursor(0, 0);
  lcd.print("Stret ");
// с  6 позиции 
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==71 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Delet ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==72 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
// 2 строка
// с позиции 0 - адрес датчика
  lcd.setCursor(0, 1);
  for(byte f2=0; f2<8; f2++)
  {
    lcd.print(adres_dat_temp_street[f2], HEX);
  }
  lcd.print("       ");
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 9-й страницы на lcd (1 строка -  датчик котловой воды, удалить, выход на 1 стр.; 2 строка - адрес комнатного датчика)
void straniza_programmirovaniya_9()
{  
// 1 строка
// с 0 позиции -  уличный датчик Stret
  lcd.setCursor(0, 0);
  lcd.print("Water ");
// с  6 позиции 
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==81 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Delet ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==82 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
// 2 строка
// с позиции 0 - адрес датчика
  lcd.setCursor(0, 1);
  for(byte f3=0; f3<8; f3++)
  {
    lcd.print(adres_dat_temp_water[f3], HEX);
  }
  lcd.print("       ");
}


//////////////////////////////////////////////////////////
// подпрограмма формирования страницы 10-й страницы на lcd (1 строка -  надпись, что новых датчиков нет или их больше одного. 2 строка - выход)
void straniza_programmirovaniya_10()
{
  if(kolvo_new_datch==0)
  {
    lcd.setCursor(0, 0);
    lcd.print("No new datchik  ");
    lcd.setCursor(0, 1);
    if(status_programmirovaniya==91 && miganie_parametra_programmirovaniya==false)
    {
      lcd.print("                ");                     // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
    }
    else
    {
      lcd.print("Exit            ");
    }
  }
// вывод инфы на дисплей о подключении более 1 нового датчика и необходимости выключения и выключения устройства с 1 новым датчиком для его записи в EEPROM и присвоения ему статуса: комнатного, уличного и котловой воды
  if(kolvo_new_datch>1)
  {
    lcd.setCursor(0, 0);
    lcd.print("New datch > 1   ");
    lcd.setCursor(0,1);
    if(status_programmirovaniya==91 && miganie_parametra_programmirovaniya==false)
    {
      lcd.print("                ");                     // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
    }
    else
    {
      lcd.print("Exit            ");
    }
  }
  if(kolvo_new_datch==1)
  {
    status_programmirovaniya=101;
  }
} 


//////////////////////////////////////////////////////////
// подпрограмма формирования страницы 11-й страницы на lcd (1 строка -  надпись, что новых датчиков нет или их больше одного. 2 строка - выход)
void straniza_programmirovaniya_11()
{
// 1 строка  
  lcd.setCursor(0, 0);
  lcd.print("NewDat Vid:");
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==101 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    switch(wybor_status_zapis_datch)
    {
      case 1:
      lcd.print("Room ");
      break;
      case 2:
      lcd.print("Stret");
      break;
      case 3:
      lcd.print("Water");
      break;
    }
  }
// 2 строка  
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==102 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==103 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}  
  

/////////////////////////////////////////////////////////////////////////////
// подпрограмма проверки адресов подключенных датчиков температуры на их соответствие данным, содержащимся в EEPROM. 
void proverka_podkluch_datchikov_temp()
{
// считываем адреса датчиков, содержащиеся в EEPROM
  read_eeprom_adres_datch();
// считываем адреса подключенных датчиков температуры  
  for(byte b=1; b<4; b++)
  {
    ds.reset();
    ds.search(temp_adres);
    for(byte i=0; i<8; i++)
    {
      switch(b)
      {
        case 1:
        temp_adres_datch_1[i]=temp_adres[i];
        break;
        case 2:
        temp_adres_datch_2[i]=temp_adres[i];
        break;
        case 3:
        temp_adres_datch_3[i]=temp_adres[i];
        break;                                                
      }
    }
  }
  ds.reset();
  ds.search(sss);                            // нужна для исключения ошибок, так как командой search последний датчик считывывается два раза. Результат этой команды не используется
////////////////////////////////////
// Проверяем на отсутствие какого-либо датчика и исключения дальнейших ошибок от возможной записи в в несколько переменных одного и того же адреса
// Если в адресе 3 считанного датчика содержится адрес 2 считанного датчика, то записываем нули
  if(temp_adres_datch_3[0]==temp_adres_datch_2[0] && temp_adres_datch_3[1]==temp_adres_datch_2[1] && temp_adres_datch_3[2]==temp_adres_datch_2[2] && temp_adres_datch_3[3]==temp_adres_datch_2[3] &&
     temp_adres_datch_3[4]==temp_adres_datch_2[4] && temp_adres_datch_3[5]==temp_adres_datch_2[5] && temp_adres_datch_3[6]==temp_adres_datch_2[6] && temp_adres_datch_3[7]==temp_adres_datch_2[7])
  {
    for(byte qwerty=0; qwerty<8; qwerty++)
    {
      temp_adres_datch_3[qwerty]=0;
    }
  } 
// Если в адресе 3 считанного датчика содержится адрес 1 считанного датчика, то записываем нули
  if(temp_adres_datch_3[0]==temp_adres_datch_1[0] && temp_adres_datch_3[1]==temp_adres_datch_1[1] && temp_adres_datch_3[2]==temp_adres_datch_1[2] && temp_adres_datch_3[3]==temp_adres_datch_1[3] &&
     temp_adres_datch_3[4]==temp_adres_datch_1[4] && temp_adres_datch_3[5]==temp_adres_datch_1[5] && temp_adres_datch_3[6]==temp_adres_datch_1[6] && temp_adres_datch_3[7]==temp_adres_datch_1[7])
  {
    for(byte qwerty=0; qwerty<8; qwerty++)
    {
      temp_adres_datch_3[qwerty]=0;
    }
  } 
// Если в адресе 2 считанного датчика содержится адрес 1 считанного датчика, то записываем нули
  if(temp_adres_datch_2[0]==temp_adres_datch_1[0] && temp_adres_datch_2[1]==temp_adres_datch_1[1] && temp_adres_datch_2[2]==temp_adres_datch_1[2] && temp_adres_datch_2[3]==temp_adres_datch_1[3] &&
     temp_adres_datch_2[4]==temp_adres_datch_1[4] && temp_adres_datch_2[5]==temp_adres_datch_1[5] && temp_adres_datch_2[6]==temp_adres_datch_1[6] && temp_adres_datch_2[7]==temp_adres_datch_1[7])
  {
    for(byte qwerty=0; qwerty<8; qwerty++)
    {
      temp_adres_datch_2[qwerty]=0;
    }
  } 
  kolvo_new_datch=0;
// сравниваем считанные адреса подключенных датчиков и содержащиеся в памяти
// датчик с адресом temp_adres_datch_1
  if(temp_adres_datch_1[0]==0x28)
  {
    if(temp_adres_datch_1[0]==adres_dat_temp_room[0] && temp_adres_datch_1[1]==adres_dat_temp_room[1] && temp_adres_datch_1[2]==adres_dat_temp_room[2] && temp_adres_datch_1[3]==adres_dat_temp_room[3] &&
       temp_adres_datch_1[4]==adres_dat_temp_room[4] && temp_adres_datch_1[5]==adres_dat_temp_room[5] && temp_adres_datch_1[6]==adres_dat_temp_room[6] && temp_adres_datch_1[7]==adres_dat_temp_room[7])
    {
      status_schit_datch_new[0]=false;
    }
    else
    {
      if(temp_adres_datch_1[0]==adres_dat_temp_street[0] && temp_adres_datch_1[1]==adres_dat_temp_street[1] && temp_adres_datch_1[2]==adres_dat_temp_street[2] && temp_adres_datch_1[3]==adres_dat_temp_street[3] &&
         temp_adres_datch_1[4]==adres_dat_temp_street[4] && temp_adres_datch_1[5]==adres_dat_temp_street[5] && temp_adres_datch_1[6]==adres_dat_temp_street[6] && temp_adres_datch_1[7]==adres_dat_temp_street[7])
      {
        status_schit_datch_new[0]=false;
      }
      else
      {
        if(temp_adres_datch_1[0]==adres_dat_temp_water[0] && temp_adres_datch_1[1]==adres_dat_temp_water[1] && temp_adres_datch_1[2]==adres_dat_temp_water[2] && temp_adres_datch_1[3]==adres_dat_temp_water[3] &&
           temp_adres_datch_1[4]==adres_dat_temp_water[4] && temp_adres_datch_1[5]==adres_dat_temp_water[5] && temp_adres_datch_1[6]==adres_dat_temp_water[6] && temp_adres_datch_1[7]==adres_dat_temp_water[7])
        {
          status_schit_datch_new[0]=false;
        }
        else
        {
          status_schit_datch_new[0]=true;
          kolvo_new_datch++;
        } 
      }
    }
  }
  else
  {
    status_schit_datch_new[0]=false;
  }
// датчик с адресом temp_adres_datch_2
 if(temp_adres_datch_2[0]==0x28)
  {
    if(temp_adres_datch_2[0]==adres_dat_temp_room[0] && temp_adres_datch_2[1]==adres_dat_temp_room[1] && temp_adres_datch_2[2]==adres_dat_temp_room[2] && temp_adres_datch_2[3]==adres_dat_temp_room[3] &&
       temp_adres_datch_2[4]==adres_dat_temp_room[4] && temp_adres_datch_2[5]==adres_dat_temp_room[5] && temp_adres_datch_2[6]==adres_dat_temp_room[6] && temp_adres_datch_2[7]==adres_dat_temp_room[7])
    {
      status_schit_datch_new[1]=false;
    }
    else
    {
      if(temp_adres_datch_2[0]==adres_dat_temp_street[0] && temp_adres_datch_2[1]==adres_dat_temp_street[1] && temp_adres_datch_2[2]==adres_dat_temp_street[2] && temp_adres_datch_2[3]==adres_dat_temp_street[3] &&
         temp_adres_datch_2[4]==adres_dat_temp_street[4] && temp_adres_datch_2[5]==adres_dat_temp_street[5] && temp_adres_datch_2[6]==adres_dat_temp_street[6] && temp_adres_datch_2[7]==adres_dat_temp_street[7])
      {
        status_schit_datch_new[1]=false;
      }
      else
      {
        if(temp_adres_datch_2[0]==adres_dat_temp_water[0] && temp_adres_datch_2[1]==adres_dat_temp_water[1] && temp_adres_datch_2[2]==adres_dat_temp_water[2] && temp_adres_datch_2[3]==adres_dat_temp_water[3] &&
           temp_adres_datch_2[4]==adres_dat_temp_water[4] && temp_adres_datch_2[5]==adres_dat_temp_water[5] && temp_adres_datch_2[6]==adres_dat_temp_water[6] && temp_adres_datch_2[7]==adres_dat_temp_water[7])
        {
          status_schit_datch_new[1]=false;
        }
        else
        {
          status_schit_datch_new[1]=true;
          kolvo_new_datch++;
        }
      }
    }
  }
  else
  {
    status_schit_datch_new[1]=false;
  }
// датчик с адресом temp_adres_datch_3
  if(temp_adres_datch_3[0]==0x28)
  {
    if(temp_adres_datch_3[0]==adres_dat_temp_room[0] && temp_adres_datch_3[1]==adres_dat_temp_room[1] && temp_adres_datch_3[2]==adres_dat_temp_room[2] && temp_adres_datch_3[3]==adres_dat_temp_room[3] &&
       temp_adres_datch_3[4]==adres_dat_temp_room[4] && temp_adres_datch_3[5]==adres_dat_temp_room[5] && temp_adres_datch_3[6]==adres_dat_temp_room[6] && temp_adres_datch_3[7]==adres_dat_temp_room[7])
    {
      status_schit_datch_new[2]=false;
    }
    else
    {
      if(temp_adres_datch_3[0]==adres_dat_temp_street[0] && temp_adres_datch_3[1]==adres_dat_temp_street[1] && temp_adres_datch_3[2]==adres_dat_temp_street[2] && temp_adres_datch_3[3]==adres_dat_temp_street[3] &&
         temp_adres_datch_3[4]==adres_dat_temp_street[4] && temp_adres_datch_3[5]==adres_dat_temp_street[5] && temp_adres_datch_3[6]==adres_dat_temp_street[6] && temp_adres_datch_3[7]==adres_dat_temp_street[7])
      {
        status_schit_datch_new[2]=false;
      }
      else
      {
        if(temp_adres_datch_3[0]==adres_dat_temp_water[0] && temp_adres_datch_3[1]==adres_dat_temp_water[1] && temp_adres_datch_3[2]==adres_dat_temp_water[2] && temp_adres_datch_3[3]==adres_dat_temp_water[3] &&
           temp_adres_datch_3[4]==adres_dat_temp_water[4] && temp_adres_datch_3[5]==adres_dat_temp_water[5] && temp_adres_datch_3[6]==adres_dat_temp_water[6] && temp_adres_datch_3[7]==adres_dat_temp_water[7])
        {
          status_schit_datch_new[2]=false;
        }
        else
        {
          status_schit_datch_new[2]=true;
          kolvo_new_datch++;
        }
      }
    }
  }
  else
  {
    status_schit_datch_new[2]=false;
  }
}

 
/////////////////////////////////////////////////////////////////////////////
void setup()
{
  wdt_disable();                                            // останавливаем таймер перезагрузки
  Wire.begin();                                             // старт интерфейса I2C (выводы 4 и 5 для UNO). Необходим для часов.
 // инициализация выхода управления реле котла
  pinMode(relekotla, OUTPUT);                               // вывод, предназначенный для управления котлом, устанавливаем как выход
  digitalWrite(relekotla, LOW);                             // устанавливаем на выходе управления котлом 0
  lcd.begin(16, 2);                                         // включаем lcd
  lcd.createChar(1, znak_lcd_plamya);                       // региструем индивидуальный знак в виде пламени
  lcd.createChar(2, znak_lcd_gradus);                       // региструем индивидуальный знак в виде градуса
  lcd.createChar(3, znak_lcd_D_Rus); 
  lcd.createChar(4, znak_lcd_b_Rus); 
  lcd.createChar(5, znak_lcd_n_Rus);
  lcd.createChar(6, znak_lcd_ch_Rus);                        
  lcd.createChar(7, znak_lcd_u_Rus);
  lcd.createChar(8, znak_lcd_t_Rus);
  poluchenie_wremeni();                                     // считываем время с часов
  opredelenie_perioda_wremeni();                            // для моментального отражения на Lcd временного периода после включения и не ждать истечения задаваемого интервала
  nachal_ustanovki();                                       // переход к подпрограмме считывания данных из EEPROM и их проверке
  lcd.clear(); 
  temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3); 
  for(byte rrr=0; rrr<3; rrr++)
  {
    temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3);             // 3 раза считываем температуру и записываемх их в переменные temperatura_pamyat[] для исключения ошибок при сравнении. 
    temperatura_room_pamyat[rrr]=temperatura_room;
  }
  temperatura_street=schit_datchik_temperatury(adres_dat_temp_street, 1);
  lcd.clear();
  wdt_enable(WDTO_8S);                                      // запускае таймер перезагрузки с длительностью 8 сек.
}  

///////////////////////////////////////////////////////////////////
void loop()
{
  
  nashat_knopka=analogRead(0);                           // постоянно считываем данные с аналогового входа
// определяем факт нажатия кнопки Select (показатель 639) в течение 3 секунд для перехода к подпрограмме программирования
  if(nashat_knopka>550&&nashat_knopka<750)
  {
    nashat_knopka=1023;                                  // для исключения ошибок присваиваем переменной значение, равное состоянию, когда ни одна из кнопок не нажата
    delay(3000);                                         // необходиая длительность удержания кнопки Select для перехода в режим программирования
    nashat_knopka=analogRead(0);
    if(nashat_knopka>550&&nashat_knopka<750)
    {
      nashat_knopka=1023;                                // для исключения ошибок присваиваем переменной значение, равное состоянию, когда ни одна из кнопок не нажата
      programmirovanie();
    }                    
  }
  wywod_na_lcd_tekusch();                                // переход к подпрограмме вывода текущих данных на дисплей.       
//////
  poluchenie_wremeni();                                  // переход к подпрограмме считывания времени с ds3231
  opredelenie_perioda_wremeni();                         // переход к подпрограмме определения временного периода (ночного, утреннего или дневного) и присваивания переменной "temperatura_sravnenia" заданной пользователем температуры для последующего сравненния со считанной.
// проверяем достижение необходимого интервала для запуска подпрограммы считывания комнатной температуры
  if(formirovanie_intervala(time_snach_progi_dat_room)>interval_zapuska_dat_room)
  {
    time_snach_progi_dat_room=time_snachala_progi;
    temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3);       // переход к подпрограмме считывания температуры с уличного датчика температуры. 3 - кол-во считываний
    wyhod_temp_room_predel();                            // переход к подпрограмме определения выхода температуры за установленный пользователем предел более чем на 1 градус и гистерезис и включения звукого уведомления
  }
  
// проверяем достижение необходимого интервала для запуска подпрограммы считывания уличной температуры
  if(formirovanie_intervala(time_snach_progi_dat_street)>interval_zapuska_dat_street)
  {
    time_snach_progi_dat_street=time_snachala_progi;
    temperatura_street=schit_datchik_temperatury(adres_dat_temp_street, 1);    // переход к подпрограмме считывания температуры с уличного датчика температуры. 1 - кол-во считываний
  }
  proverka_temperatury_room();                           // переход к подпрограмме проверки считанной температуры на наличие грубых ошибок
  sravnenie_temp_room_upravl_wychod();                   // переход к подпрограмме сравнения полученной с датчика температуры с установленными пользователем температурами с учетом времени и выполнение команд на включение или выключение котла
  problem_datch_room();                                  // переход к подпрограмме определения отсутствия ответа от комнатного датчика в течение длительного времени
  wdt_reset();                                           // обнуляем таймер перезагрузки
}

[/code]

 

rekrut007
Offline
Зарегистрирован: 19.10.2014

[code]
/* Программа "Комнатный термостат"
Допоборудование - ds18b20(вывод 2 )- 3 датчика (комнатный, уличный, на котловую воду), ds3231(выводы 5-SCL и 4-SDA) и lcd1602.
Функция - замеряет температуру в помещении и на основании ее сравнения с установленными пользователями включает или выключает нагрузку.
Принцип работы:
1) пользователем устанавливаются время начала временных периода - ночного, утреннего и дневного.
2) пользователем устанавливаются температуры каждого временного периода - ночью, утром и днем.
3) в основном цикле программы постоянно считываются данные с часов ds3231, которые заносятся в соответствующие переменные.
4) через устанавливаемый пользователем в тексте программы интервал (сейчас равен 30 с.) считывается температура с датчика (три замера, высчитывается среднеарифмитическая).
5) затем определяется текущий временной период (ночь, утро или день).
6) считанная температура проверяется на наличие ошибки, то есть сравнивается с последней сохранненной в памяти. 
7) считанная температура сравнивается с установленной пользователем температурой текущего временного периода и при выходе температуры за границы включается ил выключатеся котел.
*/
////////////////////////////////////////////////////////////////
// подключение необходимых библиотек
#include <OneWire.h>                                    // для протокола 1-Wire
#include <Wire.h>                                       // для протокола I2C
#include <LiquidCrystal.h>                              // для lcd
#include <EEPROM.h>                                     // для обращения к энергонезависимой памяти
#include <wdt.h>                                        // библиотека сторожевого таймера
// адреса EEPROM, по которым хранятся задаваемые пользователем параметры: 
// 0-часы начала ночного периода, 1-минуты начала ночного периода, 2-часы начала утреннего периода, 3 - минуты начала утреннего периода, 4-часы начала дневного периода, 
// 5-минуты начала дневного периода, 6-температура ночного периода, 7-температура утреннего периода, 8-температура дневного периода.
// 10-17 - адрес комнатного датчика температуры, 20-27 - адрес уличного датчика температуры, 30-37 - адрес датчика температуры котловой воды

////////////////////////////////////////////////////////////////
// определяем вывод для протокола 1-Wire
OneWire ds(2);                                          // для Uno (провод припаянн на 2 вывод                  
// определяем вывод, который будет управлять включением/выключением котла по результатам сравнения температур
byte relekotla=3;                                       //  то же для Uno.
// определяем вывод для lcd
//LiquidCrystal lcd(RS, E, DB4, DB5, DB6, DB7)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);                // LCD для Uno - Keypad Schild
////////////////////////////////////////////////////////////////
// формируем 3 знака (маленькая, средняя и большая стрелки вверх), которые будут отражаться на lcd
// и свидетельствовать, что на выходе управления установлен HIGH, то есть котел включен на обогрев.
enum {symbol_height=8};
byte znak_lcd_plamya[symbol_height]=    // знак в виде пламени. Если нужен другой, то закомментировать.
{
  B00010,                                        
  B00110,
  B01100,
  B11100,
  B11110,
  B01111,
  B01110,
  B00100,
};
byte znak_lcd_gradus[symbol_height]=   // знак градус.     
{                           
  B00100,
  B01010,
  B00100,
  B00000,
  B00000,
  B00000,
  B00000,
  B00000,
};
byte znak_lcd_D_Rus[symbol_height]=   // буква "Д".     
{                                  
  B01111,
  B00101,
  B00101,
  B00101,
  B01001,
  B10001,
  B11111,
  B10001,
};
byte znak_lcd_b_Rus[symbol_height]=   // буква "ь".     
{                                  
  B00000,
  B00000,
  B10000,
  B10000,
  B11110,
  B10001,
  B11110,
  B00000,
};
byte znak_lcd_n_Rus[symbol_height]=   // буква "н" .     
{                                  
  B00000,
  B00000,
  B10001,
  B10001,
  B11111,
  B10001,
  B10001,
  B00000,
};
byte znak_lcd_ch_Rus[symbol_height]=   // буква "ч" .     
{                                  
  B00000,
  B00000,
  B10001,
  B10001,
  B01111,
  B00001,
  B00001,
  B00000,
};
byte znak_lcd_u_Rus[symbol_height]=   // буква "У" .     
{                                  
  B10001,
  B10001,
  B10001,
  B01010,
  B00100,
  B01000,
  B10000,
  B00000,
};
byte znak_lcd_t_Rus[symbol_height]=   // буква "т" .     
{                                  
  B00000,
  B00000,
  B11111,
  B00100,
  B00100,
  B00100,
  B00100,
  B00000,
};
/*
byte znak_lcd_l_Rus[symbol_height]=   // буква "л" .     
{                                  
  B00000,
  B00000,
  B01111,
  B00101,
  B00101,
  B10101,
  B01001,
  B00000,
};
byte znak_lcd_CH_Rus[symbol_height]=   // буква "Ч" .     
{                                  
  B10001,
  B10001,
  B10001,
  B01111,
  B00001,
  B00001,
  B00001,
  B00000,
};
byte znak_lcd_bl_Rus[symbol_height]=   // буква "ы" .     
{                                  
  B00000,
  B00000,
  B10001,
  B10001,
  B11101,
  B10011,
  B11101,
  B00000,
};
*/
                          

////////////////////////////////////////////////////////////////
// объявляем переменные
// временные переменные для считывания адресов с подключенных датчиков
  byte temp_adres[8];                                
  byte temp_adres_datch_1[8];                            // для считывания адреса 1-го подключенного датчика
  byte temp_adres_datch_2[8];
  byte temp_adres_datch_3[8];
  byte kolvo_new_datch=0;                                // содержит кол-во новых подключенных датчиков
  boolean status_schit_datch_new[3];
  byte sss[8];
  
// для подпрограммы formirovanie_intervala(). 
  unsigned int interval_zapuska_dat_room=30000;           // интервал в милисекундах, через который будут запускаться подпрограмма по считыванию температуры с комнатного датчика. Он равен 30 сек.
  unsigned long interval_zapuska_dat_street=180000;       // интервал в милисекундах, через который будут запускаться подпрограмма по считыванию температуры с уличного датчика. Он равен 3 мин.
  unsigned int interval_wychoda_menu=15000;               // интервал в милисекундах, через который будет осуществляться выход из подпрограммы программирования
  unsigned long time_snachala_progi;                      // содержит текущие данные о времени, прошедшем сначала запуска программы. Для формирования интеравала .
  unsigned long time_snach_progi_dat_room=0;              // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала запуска для перехода к подпрограмме считывания комнатной температуры
  unsigned long time_snach_progi_dat_street=0;            // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала запуска для перехода к подпрограмме считывания уличной температуры
  unsigned long time_snach_progi_wychoda_menu=0;          // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала выхода из подпрограммы программирования
  unsigned long time_snach_progi_migania_dvoet=0;         // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала мигания двоеточия
  unsigned long time_snach_progi_migania_sost_kotla=0;    // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала мигания состояния котла
  unsigned long time_snach_progi_parametra_menu=0;        // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала мигания выбранного параметра меню
  unsigned long time_snach_progi_problem_datch_room=0;    // содержит предыдущие данные о времении, прошедшем с начала запуска проги для исчисления интервала отсутствия ответа от комнатного датчика температуры
  unsigned long time_snach_progi_wychod_predel_temp=0;
  boolean miganie_parametra_programmirovaniya=true;       // когда true светится выбранный параметр, false - вместо параметра пробелы. 
  
// содержит предыдущие данные о времени, прошедшем с начала запуска программы для формирования мигания
// для работы с температурой
  byte adres_dat_temp_room[8];                            // для хранения адреса комнатаного датчика температуры
  byte adres_dat_temp_street[8];                          // для хранения адреса уличного датчика температуры
  byte adres_dat_temp_water[8];                           // для хранения адреса датчика температуры котловой воды
  float temperatura_room;                                 // считанная с комнатного датчика температура
  float temperatura_street;                               // считанная с уличного датчика температура
  float temperatura_water;                                // считанная с датчика котловой воды температура
  float temperatura_room_pamyat[3];                       // последние 3 считанных температуры (для проверки считанной температуры на наличие ошибок и исключения тактования)
  byte temperatura_room_ustanovka[3];                     // в них считываются из EEPROM задаваемые пользователем температуры временных периодов: 0-ночь, 1-утро, 2-день.
  float gisteresis=0.2;                                   // задаваемый пользователем гистерезис для определения температурных границ управления выходом
  boolean proverka_temperatura_room_status;               // содержит информацию о том, прошла ли считанная температура проверку на наличие грубых ошибок: true-да; false-нет.
  float temperatura_room_predyd=0, temperatura_street_predyd=0;   // используются для исключения постоянного вывода на lcd неизменнных данных  

// для работы со временем
  bool Century=false;                                     // для часов. Пока не знаю??????????????????????
  bool h12;                                               // для часов. Пока не знаю??????????????????????
  bool PM;                                                // для часов. Пока не знаю??????????????????????
  byte year, month, date, hour, minute, second;           // в них записываются полученные от часов данные о времени
  byte hour_predyd=0, minute_predyd=0;                    // используются для исключения постоянного вывода на lcd неизменнных данных
  byte nachalo_periodov[6];                               // в них считываются из EEPROM часы и минуты начала периодов: 0-часы ночи, 1-минуты ночи, 2-часы утра, 3-минуты утра, 4-часы дня, 5-минуты дня. 
  byte period_time;                                       // для храненения сведений о временном периоде (ночь-0, утро-1, день-2)
  int summa_minut[4];                                     // общие суммы минут: 0-текущего времени, 1-начала ночного периода, 2-начала утреннего периода, 3-начала дневного периода, для удобства сравнения
  byte obnovl_peremen=0;                                  // необходима для ежечасного считывания данных из EEPROM и их записи в соответствующие переменные

// для подпрограммы программирования
  byte status_programmirovaniya=1;                        // содержит число на основании которого устанавливается тот или иной параметр
  boolean knopka_verch=false;                             // содержит состояние кнопки "ВВЕРХ", по умолчанию false
  boolean knopka_vniz=false;                              // содержит состояние кнопки "ВНИЗ", по умолчанию false
  boolean knopka_pravo=false;                             // содержит состояние кнопки "ПРАВО" по умолчанию false
  boolean knopka_levo=false;                              // содержит состояние кнопки "ЛЕВО", по умолчанию false
  boolean knopka_select=false;                            // содержит состояние кнопки select, по умолчанию false
  int nashat_knopka=1023;                                 // содержит данные с аналогового входа 0
  boolean status_wybora_delete=false;                     // содержит состояние необходимости удаления датчика температуры из  EEPROM
  boolean status_wybora_save=false;                       // содержит состояние необходимости сохранения измененных параметров
  byte wybor_status_zapis_datch=1;                        // содержит число (1, 2 или 3), свидетельствующее о том, каким именно (комнатным, уличным или водяным) записывается новый датчик в EEPROM

///////////////////////////////////////////////////////////////
// подпрограмма формирования задаваемого интервала между обращениями к подпрограммам считывания температуры с датчика и получения времени с часов. 
unsigned long formirovanie_intervala(unsigned long time_snachala_progi_time_pred)
{
  time_snachala_progi=millis();                         // получаем количество милисекунд с начала выполнения программы
// Проверяем, не проскочил ли счетчик прошедшего времени через 0, если предыдущие показания не достигли максимума. 
// Если проскочил то к обоим сравниваемым переменным добавляем число из tempintervalzapuska и 100, чтобы вторая переменная также перескочила через 0.  
  if (time_snachala_progi_time_pred>time_snachala_progi)   // если текущие сведения о прошедшем времени меньше предыдущих данных, то это свидетельствует о том, что счетчик перескочил через 0.
  {
    time_snachala_progi_time_pred=time_snachala_progi_time_pred+185000;   // 185000 необходимо для максимального интервала 3 минуты.
    time_snachala_progi=time_snachala_progi+185000;
  }
  unsigned long time_interval=time_snachala_progi-time_snachala_progi_time_pred;      // высчитываем пройденный интервал
  return time_interval;
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания температуры с  датчика. 
float schit_datchik_temperatury(byte time_adres_dat_temp[], byte i)
{
  float time_temperatura[i];                               // объявляем переменные для временного хранения температуры из 3 последовательных замеров
  for(byte cikl=0; cikl<i; cikl++)
  {
    ds.reset(); 
    ds.write(0xCC);                                        // игнорируем адреса всех датчиков для следующей команды                             
    ds.write(0x44);                                        // запуск преобразования температуры всеми датчиками.
    delay(200);    
    ds.reset();
    ds.select(time_adres_dat_temp);                        // следующая команда предназначется только комнатному датчику
    ds.write(0xBE);                                        // чтение двух байт с данными температуры из памяти датчика                          
    byte data[2];
    data[0]=ds.read();                                     // присваивание переменной data[0] данных первого байта, полученного от датчика                     
    data[1]=ds.read();                                     // присваивание переменной data[1] данных второго байта, полученного от датчика
    time_temperatura[cikl]=((data[1] << 8)|data[0])/16.0;  // высчитываем температуру и заносим во временную переменную
  }
  float temperatura;
  switch(i)
  {
    case 1:
    temperatura=time_temperatura[0];
    break;
    case 3:
    temperatura=(time_temperatura[0]+time_temperatura[1]+time_temperatura[2])/3;
    break;
  }
  return temperatura;
}  


/////////////////////////////////////////////////////////////////////////////
// подпрограмма получения времени с часов ds3231 и их присваивание переменным. 
void poluchenie_wremeni()
{
// считываем данные с часов  
  byte tempBuffer;
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x00));
  Wire.endTransmission();
  Wire.requestFrom(0x68, 7);
  second = bcdToDec(Wire.read());
  minute = bcdToDec(Wire.read());
  tempBuffer = Wire.read();
  h12 = tempBuffer & 0b01000000;
  if (h12) 
  {
    PM = tempBuffer & 0b00100000;
    hour = bcdToDec(tempBuffer & 0b00011111);
  }
  else 
  {
    hour = bcdToDec(tempBuffer & 0b00111111);
  }
  byte DoW = Wire.read();
  date = bcdToDec(Wire.read());
  month = bcdToDec(Wire.read() & 0b01111111);
  year = bcdToDec(Wire.read()); 
// Ежечасно сохраняем в переменные содержащиеся в EEPROM установленные: время начала временных периодов и их температуры, адреса датчиков температур
  if(minute!=24)
  {
    obnovl_peremen==0;                                  // обнуляем переменную, если минуты не равны 24.
  }
  if(minute==24 && obnovl_peremen==0)                   // 
  {
    nachal_ustanovki();
    obnovl_peremen++;                                   // для исключения обращения к подпрограмме nachal_ustanovki() более одного раза когда минуты равны 24.
  }
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма записи времени в часы ds3231. 
void zapis_wremeni()
{
  byte time_hour=hour;
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x02));
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1);
  h12 = (Wire.read() & 0b01000000);
  if (h12) 
  {
    if(time_hour > 12) 
    {
      time_hour = decToBcd(time_hour-12) | 0b01100000;
    } 
    else 
    {
      time_hour = decToBcd(time_hour) & 0b11011111;
    }
  }
  else 
  {   
    time_hour = decToBcd(time_hour) & 0b10111111;
  }
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x00));
  Wire.write(0x00);
  Wire.write(decToBcd(minute));	
  Wire.write(time_hour);
  Wire.endTransmission();
  Wire.beginTransmission(0x68);
  Wire.write(uint8_t(0x04));
  Wire.write(decToBcd(date));	
  Wire.write(decToBcd(month));
  Wire.write(decToBcd(year));	
  Wire.endTransmission();
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма преобразования данных полученных с часов
byte bcdToDec(byte val) 
{
  return ((val/16*10) + (val%16));
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма преобразования данных для записи в часы
byte decToBcd(byte val) 
{
  return ((val/10*16) + (val%10));
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания из EEPROM часов и минут начала временных режимов
void read_eeprom_time_periodov()
{
  for(byte z=0; z<6; z++)
  {
    nachalo_periodov[z]=EEPROM.read(z);
  } 
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания из EEPROM установленных температур
void read_eeprom_ustan_temper()
{
  for(byte z=6; z<9; z++)
  {
    nachalo_periodov[z]=EEPROM.read(z);
  } 
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма считывания из EEPROM адресов датчиков температур
void read_eeprom_adres_datch()
{
  for(byte z=0; z<8; z++)
  {
    adres_dat_temp_room[z]=EEPROM.read(z+10);             // адрес комнатного датчика
    adres_dat_temp_street[z]=EEPROM.read(z+20);           // адрес уличного датчика             
    adres_dat_temp_water[z]=EEPROM.read(z+30);            // адрес датчика котловой воды
  }
}


////////////////////////////////////////////////////////////////////////////
// подпрограмма определения временного периода (ночного, утреннего или дневного).
void opredelenie_perioda_wremeni()
{
// перевод часов и минут в минуты для удобства последующего сравнения 
  summa_minut[0]=hour*60+minute;                               // для последующего сравнения часы и минуты текущего времени, полученных с часов, переводим в общее количество минут
  summa_minut[1]=nachalo_periodov[0]*60+nachalo_periodov[1];   // общая сумма минут начала ночного периода
  summa_minut[2]=nachalo_periodov[2]*60+nachalo_periodov[3];   // общая сумма минут начала утреннего периода
  summa_minut[3]=nachalo_periodov[4]*60+nachalo_periodov[5];   // общая сумма минут начала дневного периода
// определениe ночного периода и сохранение в переменной period_time значения 0, что означает ночь.
  if(summa_minut[0]>=summa_minut[1] || summa_minut[0]<summa_minut[2])
  {
    period_time=0;
  }                          
// определениe утреннего периода и сохранение в переменной period_time значения 1, что означает утро.
  if(summa_minut[0]>=summa_minut[2] && summa_minut[0]<summa_minut[3])
  {
    period_time=1;
  }
// определениe дневного периода и сохранение в переменной period_time значения 2, что означает день.
  if(summa_minut[0]>=summa_minut[3] && summa_minut[0]<summa_minut[1])
  {
    period_time=2;
  }
}


//////////////////////////////////////////////////////////////////////////////
// подпрограмма грубой проверки считанной температуры
/* 
   Считанная температура сверяется с последней записанной в память температурой (защита от грубых ошибок). 
   Если разница более чем на 3 градуса как в большую так и в меньшую сторону, то запускаем повторное считывание температуры, 
   иначе статусу проверки присваиваем true и завершается подпрограмма.
   Если повторно считанная температура также более чем на 3 градуса как в большую так и в меньшую сторону, то статусу проверки
   выставляем false, иначе true и возвращаемся в основное тело проги.
*/ 
void proverka_temperatury_room()
{
  if(temperatura_room>=temperatura_room_pamyat[2]-3 && temperatura_room<=temperatura_room_pamyat[2]+3)
  {
     proverka_temperatura_room_status=true;
  }
  else
  {   
     temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3);
     if(temperatura_room>=temperatura_room_pamyat[2]-3 && temperatura_room<=temperatura_room_pamyat[2]+3)
     {
       proverka_temperatura_room_status=true;
     }
     else
     {
       proverka_temperatura_room_status=false; 
     }
  }
}


///////////////////////////////////////////////////////////////////////////// 
// подпрограмма определения выхода комнатной температуры за установленный пользователем предел более чем на 1 градус и гистерезис и включения звукого уведомления
void wyhod_temp_room_predel()
{
  byte schetchik_wyhoda_temp_room_predel;
  if(temperatura_room<18 || temperatura_room>26)
  { 
    schetchik_wyhoda_temp_room_predel++;
  }  
  switch(schetchik_wyhoda_temp_room_predel)
  {
    case 1:
    time_snach_progi_wychod_predel_temp=millis();
    break;
    case 10:
    if(formirovanie_intervala(time_snach_progi_wychod_predel_temp)-time_snachala_progi<360000)
    {
      // здесь указать, что будет выполняться, если в течение 6 минут комнатная температура выходила за пределы
      schetchik_wyhoda_temp_room_predel=0;
      time_snach_progi_wychod_predel_temp=time_snachala_progi;
    }
    else
    {  
      schetchik_wyhoda_temp_room_predel=0;
      time_snach_progi_wychod_predel_temp=time_snachala_progi;
    }
    break;
  }
}

  

///////////////////////////////////////////////////////////////////////////// 
// подпрограмма определения отсутствия в течение длительного времени данных от комнатного датчика температуры, то есть наличия проблем с ним.
void problem_datch_room()
{
  time_snach_progi_problem_datch_room;

  
}


///////////////////////////////////////////////////////////////////////////// 
// подпрограмма сравнения полученной с датчика температуры и хранящихся в памяти последних 3 показаний с границами заданной пользователем температуры и управление выходом.
// с целью исключения тактования и возможных краткосрочных незначительных измерений температуры (например открытие окна или двери, дуновение ветра) переключение выхода
// происходит только, если 3 последних показаний температуры также находятся за границами заданной пользователем температуры.
void sravnenie_temp_room_upravl_wychod()
{
  if(proverka_temperatura_room_status==true)             // сначла проверяем прохождение проверки на наличие грубок ошибок. Если да, то переходим к сравнению.
  {
 // если считанная температура и последние 3 показания меньше нижней границы заданной пользователем температуры и на управляемом выходе 0, то данный выход переключается в 1 (котел включается). 
    if(digitalRead(relekotla)==LOW)
    {
      if(temperatura_room<temperatura_room_ustanovka[period_time]-gisteresis && temperatura_room_pamyat[0]<temperatura_room_ustanovka[period_time]-gisteresis && temperatura_room_pamyat[1]<temperatura_room_ustanovka[period_time]-gisteresis && temperatura_room_pamyat[2]<temperatura_room_ustanovka[period_time]-gisteresis)
      {
        digitalWrite(relekotla, HIGH);
      }
    } 
 // если считанная температура и последние 3 показания большее верхней границы заданной пользователем температуры и на управляемом выходе 1, то данный выход переключается в 0 (котел выключается).
    if(digitalRead(relekotla)==HIGH)
    {
      if(temperatura_room>temperatura_room_ustanovka[period_time]+gisteresis && temperatura_room_pamyat[0]>temperatura_room_ustanovka[period_time]+gisteresis && temperatura_room_pamyat[1]>temperatura_room_ustanovka[period_time]+gisteresis && temperatura_room_pamyat[2]>temperatura_room_ustanovka[period_time]+gisteresis)
      {
        digitalWrite(relekotla, LOW);
      }
    }
 // сдвиг хранящейся темпрературы. При этом считанную температуру записываем в самую последнюю переменную
    temperatura_room_pamyat[0]=temperatura_room_pamyat[1];
    temperatura_room_pamyat[1]=temperatura_room_pamyat[2];
    temperatura_room_pamyat[2]=temperatura_room;
  }
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма первоначальных установок начала временных периодов и температур
/* Если при считывании из EEPROM задаваемые пользователем время начала периодов и температуры выходят за рамки 
   установленных программой пределов,то устанавливаются заложенные программой данные.
*/
void nachal_ustanovki()
{
// считываем данные из EEPROM установленные данные (часы и минуты начала временных периодов и температуры)
  read_eeprom_time_periodov();
  read_eeprom_ustan_temper();
  read_eeprom_adres_datch();
// Часы и минуты начала временных периодов проверяем на наличие ошибок(не соответствие временному интервалу) и при необходимости записываем в соответствующие переменные.
  if(nachalo_periodov[0]<18 || nachalo_periodov[0]>23)        // Если считанные из EEPROM часы начала ночи меньше 18 или больше 23, тогда в память и переменную записывам 21.
  {                                                            
    EEPROM.write(0, 21);                                      
    delay(100);
    nachalo_periodov[0]=21;                                    
  } 
  if(nachalo_periodov[1]<0 || nachalo_periodov[1]>59)         // Если считанные из EEPROM минуты меньше 0 или больше 59, тогда в память и переменную записывам 30.
  {
    EEPROM.write(1, 30);                                      
    delay(100);
    nachalo_periodov[1]=30;
  }
  if(nachalo_periodov[2]>10 || nachalo_periodov[2]<3)         // Если считанные из EEPROM часы начала утра меньше 3 или больше 10 часов, тогда в память и переменную записывам 6.
  {
    EEPROM.write(2, 6);                                       
    delay(100);
    nachalo_periodov[2]=6;
  }  
   if(nachalo_periodov[3]<0 || nachalo_periodov[3]>59)         // Если считанные из EEPROM минуты меньше 0 или больше 59, тогда в память и переменную записывам 0.
  {
    EEPROM.write(3, 0);                                       
    delay(100);
    nachalo_periodov[3]=0;
  }
  if(nachalo_periodov[4]>12 || nachalo_periodov[4]<6)         // Если считанные из EEPROM часы начала дня меньше 6 или больше 12 часов, тогда в память и переменную записывам 9.
  {  
    EEPROM.write(4, 9);                                       
    delay(100);
    nachalo_periodov[4]=9;
  }  
    if(nachalo_periodov[5]<0 || nachalo_periodov[5]>59)        // Если считанные из EEPROM минуты меньше 0 или больше 59, тогда в память и переменную записывам 0.
  {
    EEPROM.write(5, 0);                                        
    delay(100);
    nachalo_periodov[5]=0;
  }
  
 // Температуры проверям на соответствие периоду 10-35 градусов и при необходимости записываем в соответствующие переменные.
  if(temperatura_room_ustanovka[0]>35 || temperatura_room_ustanovka[0]<10)   // если считанная из EEPROM температура ночного периода меньше 10 или выше 35 градусов,   
  {                                                                          // тогда в память и переменную записывам 19.
    EEPROM.write(6, 19);                                      
    delay(100);
    temperatura_room_ustanovka[0]=19;                         
  }  
  if(temperatura_room_ustanovka[1]>35 || temperatura_room_ustanovka[1]<10)   // если считанная из EEPROM температура утреннего периода меньше 10 или выше 35 градусов,  
  {                                                                          // тогда в память и переменную записывам 23.
    EEPROM.write(7, 23);                                      
    delay(100);
    temperatura_room_ustanovka[1]=23;                         
  }
  if(temperatura_room_ustanovka[2]>35 || temperatura_room_ustanovka[2]<10)   // если считанная из EEPROM температура дневного период меньше 10 или выше 35 градусов, 
  {                                                                          // тогда в память и переменную записывам 21.
    EEPROM.write(8, 21);                                      
    delay(100);
    temperatura_room_ustanovka[2]=21;                         
  }
}   
 
/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd слова "Ночь"
void wywod_na_lcd_slova_Noch()
{
  lcd.print("Ho");
  lcd.write(6);
  lcd.write(4);
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd слова "Утро"
void wywod_na_lcd_slova_Utro()
{
  lcd.write(7);
  lcd.write(8);
  lcd.print("po");
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd слова "День"
void wywod_na_lcd_slova_Den()
{
  lcd.write(3);
  lcd.print("e");
  lcd.write(5);
  lcd.write(4);
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd температуры со значком градуса
void wywod_na_lcd_temper(float wywod_temper)
{
  if(wywod_temper<10)
  {
    lcd.print(" ");
  }
  lcd.print(wywod_temper, 1);
  lcd.write(2);   
}


/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd времени-часов
void wywod_na_lcd_hour(byte wywod_hour)
{
  if(wywod_hour<10)
  {
    lcd.print(" ");
  }
  lcd.print(wywod_hour);
} 
 
 
 /////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода на lcd времени-минут
void wywod_na_lcd_min(byte wywod_minute)
{
  if(wywod_minute<10)
  {
    lcd.print("0");
  }
  lcd.print(wywod_minute);
} 

  
/////////////////////////////////////////////////////////////////////////////
// подпрограмма вывода текущих данных на lcd дисплей при переходе из основной программы
// с целью исключения повтороного вывода на дисплей информации, которая не изенилась с прошлого обращения к подпрограмме, производиться ее сравнение
void wywod_na_lcd_tekusch()
{
// формируем сначала вывод информации, которая меняется относительно редко (часы, минуты, температура)
//////////////// верхняя строка lcd  
// вывод текущего времени
  if(hour!=hour_predyd)
  {
    lcd.setCursor(0, 0);
    wywod_na_lcd_hour(hour);                                 // переход к подпрограмме вывода на lcd текущего времени - часов 
    hour_predyd=hour;
  }
  if(minute!=minute_predyd)
  {
    lcd.setCursor(3, 0);
    wywod_na_lcd_min(minute);                                // переход к подпрограмме вывода на lcd текущего времени - минут
    minute_predyd=minute;
  }
// вывод комнатной температуры и значка градус
  if(temperatura_room!=temperatura_room_predyd)
  {
    lcd.setCursor(11, 0);
    wywod_na_lcd_temper(temperatura_room);                   // переход к подпрограмме вывода на lcd температуры со значком градуса 
    lcd.setCursor(15, 0);                                    // обрезаем второй знак после запятой и ставим вместо него значок градуса
    lcd.write(2); 
    temperatura_room_predyd=temperatura_room;
  }
//////////////// нижняя строка lcd  
// вывод уличной температуры
  if(temperatura_street!=temperatura_street_predyd)
  {
    lcd.setCursor(7, 1);
    lcd.print("Out");
    lcd.setCursor(11, 1);
    if(temperatura_street>=0)
    {
      lcd.print(" ");
    }
    lcd.print(temperatura_street, 1);
    lcd.setCursor(15, 1);
    lcd.write(2);
    temperatura_street_predyd=temperatura_street;
  //  
  }
// формирование мигающего двоеточия между часами и минутами (0,75 сек. светятся, 0,45 не светятся)
  unsigned long miganie_dvoet=formirovanie_intervala(time_snach_progi_migania_dvoet);
  lcd.setCursor(2, 0);
  if(miganie_dvoet<750)    // 0,75 сек знаки светятся
  {
    lcd.print(":");
  }
  else
  {
    lcd.print(" ");
  }
  if(miganie_dvoet>1200)
  {
    time_snach_progi_migania_dvoet=time_snachala_progi;
  }  
// последовательный вывод названия временного периода и, если котел включен, то сведения об этом
// первые 0,5 сек. ничего нет
  unsigned long miganie_sost_kotla=formirovanie_intervala(time_snach_progi_migania_sost_kotla);
  lcd.setCursor(6, 0);
  // первые 0,5 сек. ничего нет 
  if(miganie_sost_kotla<500)
  {
    lcd.print("    ");
  }
// вывод первой буквы названия режима
  if(miganie_sost_kotla>500 && miganie_sost_kotla<=1250)
  {    
    switch(period_time)
    {
      case 0:
      lcd.print("H");
      break;
      case 1:
      lcd.write(7);
      break;
      case 2:
      lcd.write(3);
      break;
    }
    lcd.print("   ");
  }
 // вывод 1-й и 2-й букв названия режима  
  if(miganie_sost_kotla>1250 && miganie_sost_kotla<=2000)
  {    
    switch(period_time)
    {
      case 0:
      lcd.print("Ho");
      break;
      case 1:
      lcd.write(7);
      lcd.write(8);
      break;
      case 2:
      lcd.write(3);
      lcd.print("e");
      break;
    }
    lcd.print("  ");
  }
 // вывод 1-й, 2-й и 3-й букв названия режима  
  if(miganie_sost_kotla>2000 && miganie_sost_kotla<=2750)
  {               
    switch (period_time)
    {
      case 0:
      lcd.print("Ho");
      lcd.write(6);
      break;
      case 1:
      lcd.write(7);
      lcd.write(8);
      lcd.print("p");
      break;
      case 2:
      lcd.write(3);
      lcd.print("e");
      lcd.write(5);
      break;
    }
    lcd.print(" ");
  }
 // вывод всего слова названия режима 
  if(miganie_sost_kotla>2750 && miganie_sost_kotla<=3500)
  {     
    switch (period_time)
    {
      case 0:
      lcd.print("Ho");
      lcd.write(6);
      lcd.write(4);
      break;
      case 1:
      lcd.write(7);
      lcd.write(8);
      lcd.print("po");
      break;
      case 2:
      lcd.write(3);
      lcd.print("e");
      lcd.write(5);
      lcd.write(4);
      break;
    }
  }
 // Если на выходе котла 0, то обнуляем временной интервал для повторного вывода временного периода 
  if(miganie_sost_kotla>3500 && digitalRead(relekotla)==LOW)
  { 
    time_snach_progi_migania_sost_kotla=time_snachala_progi;
    miganie_sost_kotla=formirovanie_intervala(time_snach_progi_migania_sost_kotla);
  }
// 0,5 сек. ничего нет 
  
  if(miganie_sost_kotla>3500 && miganie_sost_kotla<=4000)
  {
    
    lcd.print("    ");
  }
// далее, если на выход котла 1, то выводим значки пламени
  if(miganie_sost_kotla>4000 && miganie_sost_kotla<=4750)
  {
    
    lcd.write(1);
    lcd.print("   ");
  }  
// следующие 0,75 сек. рисуем два значка пламени  
  if(miganie_sost_kotla>4750 && miganie_sost_kotla<=5500)
  {
    
    lcd.write(1);
    lcd.write(1);
    lcd.print("  ");
  }
// следующие 0,75 сек. рисуем три значка пламени   
  if(miganie_sost_kotla>5500 && miganie_sost_kotla<=6250)
  {
    
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.print(" "); 
  }   
// следующие 0,75 сек. рисуем четыре значка пламени   
  if(miganie_sost_kotla>6250 && miganie_sost_kotla<=7000)
  {
    
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
    lcd.write(1);
  }
 // обнуляем временной показатель 
  if(miganie_sost_kotla>7000)
  { 
    time_snach_progi_migania_sost_kotla=time_snachala_progi;
  }
} 


////////////////////////////////////////////////////////////////////////////
// подпрограмма формирования интервала мигания выбранного для изменения параметра при нахождении в меню программирования
void miganie_parametra_lcd()
{
  unsigned long miganie_parametra=formirovanie_intervala(time_snach_progi_parametra_menu);       
  if(miganie_parametra<=750)
  {
    miganie_parametra_programmirovaniya=true;
  }
  else
  {
    miganie_parametra_programmirovaniya=false;
  }
  if(miganie_parametra>1200)
  {
    time_snach_progi_parametra_menu=time_snachala_progi;
  }   
}

  
////////////////////////////////////////////////////////////////////////////
// подпрограмма программирования - установки времени, начала временных периодов(ночи, утра и дня), температуры временных периодов и записи (удаления) адресов датчиков температуры
void programmirovanie()
{
  // считываем из EEPROM часы и минуты начала временных периодов, установленных температур и адреса датчиков, а также текущие дату и время
  read_eeprom_time_periodov();
  read_eeprom_ustan_temper();
  read_eeprom_adres_datch();
  poluchenie_wremeni();                                   // переход к подпрограмме считывания времени с часов
  time_snach_progi_wychoda_menu=millis();                 // для формирования интервала с нуля. 
  time_snach_progi_parametra_menu=time_snach_progi_wychoda_menu;   // для формирования интервала мигания выбранного для изменения параметра
  lcd.clear();
  delay(1000);
// создаем циклический опрос нажатия кнопок, вывод изображения данных на lcd
  cikl_programm:
    wdt_reset(); 
    if(formirovanie_intervala(time_snach_progi_wychoda_menu)>interval_wychoda_menu || status_programmirovaniya==0)
    {
      goto na_wychod;                                   // если интервал достиг задаваемого программистом и не нажата ни одна кнопка, то осуществляется выход из подпрограммы программирования
    }
    opredel_nashat_knopok();                            // переход к подпрограмме определения нажатия кнопок
    nashata_knopka_pravo();                             // переход к подпрограмме и выполнение действий при нажатии кнопки право
    nashata_knopka_levo();                              // переход к подпрограмме и выполнение действий при нажатии кнопки лево
    nashata_knopka_verch();                             // переход к подпрограмме и выполнение действий при нажатии кнопки верх
    nashata_knopka_vniz();                              // переход к подпрограмме и выполнение действий при нажатии кнопки вниз
    nashata_knopka_select();                            // переход к подпрограмме и выполнение действий при нажатии кнопки select
    miganie_parametra_lcd();                            // переход к подпрограмме определения продожительности мигания выбранного в меню параметра
    opredel_stranizy_lcd();                             // переход к подпрограмме, которая определяет, какую из двух страниц выводить на lcd
  goto cikl_programm;
// завершение цикла опроса кнопок и т.д. 
  na_wychod:
  status_programmirovaniya=1;
  lcd.clear();
// первоначальный вывод на lcd текущих данных
  lcd.setCursor(0, 0);
  wywod_na_lcd_hour(hour);                                 // переход к подпрограмме вывода на lcd текущего времени - часов 
  lcd.setCursor(3, 0);
  wywod_na_lcd_min(minute);                                // переход к подпрограмме вывода на lcd текущего времени - минут
  lcd.setCursor(11, 0);
  wywod_na_lcd_temper(temperatura_room);                   // переход к подпрограмме вывода на lcd температуры со значком градуса 
  lcd.setCursor(15, 0);                                    // обрезаем второй знак после запятой и ставим вместо него значок градуса
  lcd.write(2); 
  lcd.setCursor(7, 1);
  lcd.print("Out");
  lcd.setCursor(10, 1);
  if(temperatura_street>=0)
  {
    lcd.print(" ");
  }
  wywod_na_lcd_temper(temperatura_street);
}    

        
//////////////////////////////////////////////////////////////////////////////
// подпрограмма определения нажатия кнопок
void opredel_nashat_knopok()
{
  int temp_temp=1023;
  temp_temp=analogRead(0);                                     // считываем данные
//определяем нажатие кнопки "ВВЕРХ" (показатель 99)
  if(temp_temp>50 && temp_temp<150)   
  {
    knopka_verch=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования 
  } 
//определяем нажатие кнопки "ВНИЗ" (показатель 255)
  if(temp_temp>200 && temp_temp<300)  
  {
    knopka_vniz=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования
  }  
//определяем нажатие кнопки "ПРАВО" (показатель 0) 
  if(temp_temp<30)                         
  {
    knopka_pravo=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования
  }  
//определяем нажатие кнопки "ЛЕВО" (показатель 409)  
  if(temp_temp>350 && temp_temp<500)  
  {
    knopka_levo=true;
    time_snach_progi_wychoda_menu=millis();   // для обнуления интервала бездействия и выхода из режима программирования
  }
// определяем нажатие кнопки Select (показатель 639) 
  if(temp_temp>550 && temp_temp<750)  
  {
    knopka_select=true;
    time_snach_progi_wychoda_menu=millis();     
  }
  temp_temp=1023;
  delay(200);
}

    
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка право
void nashata_knopka_pravo()
{
  if(knopka_pravo==true)
  {
    knopka_pravo=false;
// на 1-й странице
    if(status_programmirovaniya>=1 && status_programmirovaniya<=6)
    {  
      if(status_programmirovaniya==6)
      {
        status_programmirovaniya=1;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 2-й странице
    if(status_programmirovaniya>=11 && status_programmirovaniya<=15)
    {
      if(status_programmirovaniya==15)
      {
        status_programmirovaniya=11;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 3-й странице
    if(status_programmirovaniya>=21 && status_programmirovaniya<=25)
    {
      if(status_programmirovaniya==25)
      {
        status_programmirovaniya=21;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 4-й странице
    if(status_programmirovaniya>=31 && status_programmirovaniya<=35)
    {
      if(status_programmirovaniya==35)
      {
        status_programmirovaniya=31;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 5-й странице
    if(status_programmirovaniya>=41 && status_programmirovaniya<=47)
    {
      if(status_programmirovaniya==47)
      {
        status_programmirovaniya=41;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 6-й странице
    if(status_programmirovaniya>=51 && status_programmirovaniya<=55)
    {
      if(status_programmirovaniya==55)
      {
        status_programmirovaniya=51;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 7-й странице
    if(status_programmirovaniya==61 || status_programmirovaniya==62)
    {
      if(status_programmirovaniya==62)
      {
        status_programmirovaniya=61;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 8-й странице
    if(status_programmirovaniya==71 || status_programmirovaniya==72)
    {
      if(status_programmirovaniya==72)
      {
        status_programmirovaniya=71;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 9-й странице
    if(status_programmirovaniya==81 || status_programmirovaniya==82)
    {
      if(status_programmirovaniya==82)
      {
        status_programmirovaniya=81;
      }
      else
      {
        status_programmirovaniya++;
      }
    }
// на 11-й странице
    if(status_programmirovaniya>100 && status_programmirovaniya<104)
    {
      if(status_programmirovaniya==103)
      {
        status_programmirovaniya=101;
      }
      else
      {
        status_programmirovaniya++;
      }
    }        
  }
}
  
  
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка лево
void nashata_knopka_levo()
{
  if(knopka_levo==true)
  {
    knopka_levo=false;
// на 1-й странице
    if(status_programmirovaniya>=1 && status_programmirovaniya<=6)
    {  
      if(status_programmirovaniya==1)
      {
        status_programmirovaniya=6;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 2-й странице
    if(status_programmirovaniya>=11 && status_programmirovaniya<=15)
    {
      if(status_programmirovaniya==11)
      {
        status_programmirovaniya=15;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 3-й странице
    if(status_programmirovaniya>=21 && status_programmirovaniya<=25)
    {
      if(status_programmirovaniya==21)
      {
        status_programmirovaniya=25;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 4-й странице
    if(status_programmirovaniya>=31 && status_programmirovaniya<=35)
    {
      if(status_programmirovaniya==31)
      {
        status_programmirovaniya=35;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 5-й странице
    if(status_programmirovaniya>=41 && status_programmirovaniya<=47)
    {
      if(status_programmirovaniya==41)
      {
        status_programmirovaniya=47;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 6-й странице
    if(status_programmirovaniya>=51 && status_programmirovaniya<=55)
    {
      if(status_programmirovaniya==51)
      {
        status_programmirovaniya=55;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 7-й странице
    if(status_programmirovaniya==61 || status_programmirovaniya==62)
    {
      if(status_programmirovaniya==61)
      {
        status_programmirovaniya=62;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 8-й странице
    if(status_programmirovaniya==71 || status_programmirovaniya==72)
    {
      if(status_programmirovaniya==71)
      {
        status_programmirovaniya=72;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 9-й странице
    if(status_programmirovaniya==81 || status_programmirovaniya==82)
    {
      if(status_programmirovaniya==81)
      {
        status_programmirovaniya=82;
      }
      else
      {
        status_programmirovaniya--;
      }
    }
// на 11-й странице
    if(status_programmirovaniya>100 && status_programmirovaniya<104)
    {
      if(status_programmirovaniya==101)
      {
        status_programmirovaniya=103;
      }
      else
      {
        status_programmirovaniya--;
      }
    }    
  }
} 
  
  
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка верх
void nashata_knopka_verch()
{   
  if(knopka_verch==true)
  {
    knopka_verch=false;  
    if(status_programmirovaniya==14 || status_programmirovaniya==24 || status_programmirovaniya==34 || status_programmirovaniya==46 || status_programmirovaniya==102)
    {
      if(status_wybora_save==false)
      {
        status_wybora_save=true;
      }
      else
      {
        status_wybora_save=false;
      }
    }  
    switch(status_programmirovaniya)
    {
   // увеличиваем часы начала ночного периода
      case 11:
      if(nachalo_periodov[0]==23)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[0]=0;
      }
      else
      {
        nachalo_periodov[0]++;                                // увеличиваем показатель
      }
      break;    
   // увеличиваем минуты начала ночного периода
      case 12:
      if(nachalo_periodov[1]==59)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[1]=0;
      }
      else
      {
        nachalo_periodov[1]++;                               // увеличиваем показатель
      }
      break;
   // увеличиваем температуру ночного периода
      case 13:
      if(temperatura_room_ustanovka[0]==35)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[0]=10;
      }
      else
      {
        temperatura_room_ustanovka[0]++;                           // увеличиваем показатель
      }
      break;
   // увеличиваем часы начала утреннего периода
      case 21:
      if(nachalo_periodov[2]==23)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[2]=0;
      }
      else
      {
        nachalo_periodov[2]++;                                // увеличиваем показатель
      }
      break;
   // увеличиваем минуты начала утреннего периода
      case 22:
      if(nachalo_periodov[3]==59)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[3]=0;
      }
      else
      {
        nachalo_periodov[3]++;                               // увеличиваем показатель
      }
      break;
   // увеличиваем температуру утреннего периода
      case 23:
      if(temperatura_room_ustanovka[1]==35)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[1]=10;
      }
      else
      {
        temperatura_room_ustanovka[1]++;                           // увеличиваем показатель
      }
      break;    
   // увеличиваем часы начала дневного периода
      case 31:
      if(nachalo_periodov[4]==23)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[4]=0;
      }
      else
      {
        nachalo_periodov[4]++;                                // увеличиваем показатель
      }
      break;
   // увеличиваем минуты начала утреннего периода
      case 32:
      if(nachalo_periodov[5]==59)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[5]=0;
      }
      else
      {
        nachalo_periodov[5]++;                               // увеличиваем показатель
      }
      break;
   // увеличиваем температуру утреннего периода
      case 33:
      if(temperatura_room_ustanovka[2]==35)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[2]=10;
      }
      else
      {
        temperatura_room_ustanovka[2]++;                           // увеличиваем показатель
      }
      break;
   // увеличиваем часы текущего времени
      case 41:
      if(hour==23)                                           // часы должны быть в пределах от 0 до 24.
      {
        hour=0;
      }
      else
      {
        hour++;                                               // увеличиваем показатель
      }
      break;
   // увеличиваем минуты текущего времени
      case 42:
      if(minute==59)                                         // минуты должны быть в пределах от 0 по 59.
      {
        minute=0;
      }
      else
      {
        minute++;                                             // увеличиваем показатель
      }
      break;
   // увеличиваем текущую дату
      case 43:
      if(date==31)                                          // число должно быть в пределах от 1 до 31.
      {
        date=1;
      }
      else
      {
        date++;                                               // увеличиваем показатель
      }
      break;
   // увеличиваем текущий месяц
      case 44:
      if(month==12)
      {
        month=1; 
      }
      else
      {
        month++;                                              // увеличиваем показатель
      }
      break;
   // увеличиваем текущий год
      case 45:
      if(year==99)                                           // год не может быть больше 99.
      {
        year=0;
      }
      else
      {
        year++;                                              // увеличиваем показатель
      }
      break;
   // изменяем присваемый подключенныому датчику статус - комнатный, уличный или водяной
      case 101:
      if(wybor_status_zapis_datch==3)
      {
        wybor_status_zapis_datch=1;
      }
      else
      {
        wybor_status_zapis_datch++;
      }
      break;     
    }    
  }
}
 
 
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка вниз
void nashata_knopka_vniz()
{    
  if(knopka_vniz==true)
  {
    knopka_vniz=false;
    if(status_programmirovaniya==14 || status_programmirovaniya==24 || status_programmirovaniya==34 || status_programmirovaniya==46 || status_programmirovaniya==102)
    {
      if(status_wybora_save==false)
      {
        status_wybora_save=true;
      }
      else
      {
        status_wybora_save=false;
      }
    }  
    switch(status_programmirovaniya)
    {
   // уменьшаем часы начала ночного периода
      case 11:
      if(nachalo_periodov[0]==0)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[0]=23;
      }
      else
      {
        nachalo_periodov[0]--;                                // увеличиваем показатель
      }
      break;    
   // уменьшаем минуты начала ночного периода
      case 12:
      if(nachalo_periodov[1]==0)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[1]=59;
      }
      else
      {
        nachalo_periodov[1]--;                               // увеличиваем показатель
      }
      break;
   // уменьшаем температуру ночного периода
      case 13:
      if(temperatura_room_ustanovka[0]==10)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[0]=35;
      }
      else
      {
        temperatura_room_ustanovka[0]--;                           // увеличиваем показатель
      }
      break;
   // уменьшаем часы начала утреннего периода
      case 21:
      if(nachalo_periodov[2]==0)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[2]=23;
      }
      else
      {
        nachalo_periodov[2]--;                                // увеличиваем показатель
      }
      break;
   // уменьшаем минуты начала утреннего периода
      case 22:
      if(nachalo_periodov[3]==0)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[3]=59;
      }
      else
      {
        nachalo_periodov[3]--;                               // увеличиваем показатель
      }
      break;
   // уменьшаем температуру утреннего периода
      case 23:
      if(temperatura_room_ustanovka[1]==10)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[1]=35;
      }
      else
      {
        temperatura_room_ustanovka[1]--;                           // увеличиваем показатель
      }
      break;  
   // уменьшаем часы начала дневного периода
      case 31:
      if(nachalo_periodov[4]==0)                            // часы должны быть в пределах от 0 до 24.
      {
        nachalo_periodov[4]=23;
      }
      else
      {
        nachalo_periodov[4]--;                                // увеличиваем показатель
      }
      break;
   // уменьшаем минуты начала утреннего периода
      case 32:
      if(nachalo_periodov[5]==0)                            // минуты должны быть в пределах от 0 по 59.
      {
        nachalo_periodov[5]=59;
      }
      else
      {
        nachalo_periodov[5]--;                               // увеличиваем показатель
      }
      break;
   // уменьшаем температуру утреннего периода
      case 33:
      if(temperatura_room_ustanovka[2]==10)                 // температура должна быть в пределах от 10 до 35.
      {
        temperatura_room_ustanovka[2]=35;
      }
      else
      {
        temperatura_room_ustanovka[2]--;                           // увеличиваем показатель
      }
      break;
   // уменьшаем часы текущего времени
      case 41:
      if(hour==0)                                           // часы должны быть в пределах от 0 до 24.
      {
        hour=23;
      }
      else
      {
        hour--;                                               // увеличиваем показатель
      }
      break;
   // уменьшаем минуты текущего времени
      case 42:
      if(minute==0)                                         // минуты должны быть в пределах от 0 по 59.
      {
        minute=59;
      }
      else
      {
        minute--;                                             // увеличиваем показатель
      }
      break;
  // уменьшаем текущую дату
      case 43:
      if(date==1)                                          // число должно быть в пределах от 1 до 31.
      {
        date=31;
      }
      else
      {
        date--;                                               // увеличиваем показатель
      }
      break;
   // уменьшаем текущий месяц
      case 44:
      if(month==1)
      {
        month=12; 
      }
      else
      {
        month--;                                              // увеличиваем показатель
      }
      break;
   // уменьшаем текущий год
      case 45:
      if(year==0)                                           // год не может быть больше 99.
      {
        year=99;
      }
      else
      {
        year--;                                              // увеличиваем показатель
      }
      break;
   // изменяем присваемый подключенныому датчику статус - комнатный, уличный или водяной
      case 101:
      if(wybor_status_zapis_datch==1)
      {
        wybor_status_zapis_datch=3;
      }
      else
      {
        wybor_status_zapis_datch--;
      }
      break;          
    }
  } 
} 

  
///////////////////////////////////////////////////////////////////////// 
// подпрограмма выполнения действий, если нажата кнопка select
void nashata_knopka_select()
{      
  if(knopka_select==true)
  {
    knopka_select=false;                        // для исключения учитывания факта нажатой кнопки при переходах из меню в подменю и обратно
    switch(status_programmirovaniya)   
    {
   // переходы в подменю или выход из меню
      case 1:
      status_programmirovaniya=11;              // переход в подменю установок параметров ночного режима
      break;
      case 2:
      status_programmirovaniya=21;              // переход в подменю установок параметров утреннего режима
      break;
      case 3:
      status_programmirovaniya=31;              // переход в подменю установок параметров дневного режима
      break;
      case 4:
      status_programmirovaniya=41;              // переход в подменю установок текущих даты и времени
      break;
      case 5:
      status_programmirovaniya=51;              // переход в подменю датчики
      break;
      case 6:
      status_programmirovaniya=0;               // команда на выход
      break;             
   // сохранение параметров ночного периода, при условии выбора Yes 
      case 14:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        EEPROM.write(0, nachalo_periodov[0]);
        delay(100);
        EEPROM.write(1, nachalo_periodov[1]);
        delay(100);
        EEPROM.write(6, temperatura_room_ustanovka[0]);
        delay(100);
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю ночного периода в основное меню
      case 15:
      status_programmirovaniya=1;
      break;  
   // сохранение параметров утреннего периода, при условии выбора Yes 
      case 24:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        EEPROM.write(2, nachalo_periodov[2]);
        delay(100);
        EEPROM.write(3, nachalo_periodov[3]);
        delay(100);
        EEPROM.write(7, temperatura_room_ustanovka[1]);
        delay(100);
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю утреннего периода в основное меню
      case 25:
      status_programmirovaniya=1;
      break;     
   // сохранение параметров дневного периода, при условии выбора Yes 
      case 34:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        EEPROM.write(4, nachalo_periodov[4]);
        delay(100);
        EEPROM.write(5, nachalo_periodov[5]);
        delay(100);
        EEPROM.write(8, temperatura_room_ustanovka[8]);
        delay(100);
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю дневного периода в основное меню
      case 35:
      status_programmirovaniya=1;
      break;     
   // сохранение текущих даты и времени, при условии выбора Yes 
      case 46:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        zapis_wremeni();
      }
      status_programmirovaniya=1;
      break;
   // выход из подменю часов в основное меню
      case 47:
      status_programmirovaniya=1;
      break;       
   // переход из подменю датчики в подменю комнантный датчик  
      case 51:
      status_programmirovaniya=62;             
      break;
   // переход из подменю датчики в подменю уличный датчик   
      case 52:
      status_programmirovaniya=72;             
      break;
   // переход из подменю датчики в подменю водяной датчик
      case 53:
      status_programmirovaniya=82;             
      break;
   // переход из подменю датчики в подменю новый датчик  
      case 54:
      proverka_podkluch_datchikov_temp();           // сначала переход в подпрограмму определения новых подключенных датчиков
      status_programmirovaniya=91;                  // переход в подменю новый датчик
      break;
   // переход из подменю датчики в основное меню     
      case 55:
      status_programmirovaniya=1;
      break;
   // удаление комнатного датчика    
      case 61:
      for(byte h1=0; h1<8; h1++)
      {
        EEPROM.write(h1+10, 255);
        adres_dat_temp_room[h1]=255;
        delay(100);
      }
      break;
   // переход из подменю уличный датчик в основное меню     
      case 62:
      status_programmirovaniya=51;
      break;       
   // удаление уличного датчика
      case 71:
      for(byte h2=0; h2<8; h2++)
      {
        EEPROM.write(h2+20, 255);
        adres_dat_temp_street[h2]=255;
        delay(100);
      }
      break;
   // переход из подменю уличный датчик в основное меню     
      case 72:
      status_programmirovaniya=51;
      break;       
   // удаление водяного датчика 
      case 81:
      for(byte h3=0; h3<8; h3++)
      {
        EEPROM.write(h3+30, 255);
        adres_dat_temp_water[h3]=255;
        delay(100);
      }
      break; 
   // переход из подменю водяной датчик в основное меню     
      case 82:
      status_programmirovaniya=51;
      break;
   // переход из подменю новый датчик в подменю датчики    
      case 91:
      status_programmirovaniya=51;
      break;
   // сохранение выбранного статуса датчику температуры и запись его адреса в EEPROM, при условии выбора Yes 
      case 102:
      if(status_wybora_save==true)
      {
        status_wybora_save=false;
        for(byte x1=0; x1<8; x1++)
        {
          if(status_schit_datch_new[0]==true)
          {
            temp_adres[x1]=temp_adres_datch_1[x1];    
          }
          if(status_schit_datch_new[1]==true)
          {           
            temp_adres[x1]=temp_adres_datch_2[x1];
          }       
          if(status_schit_datch_new[2]==true)
          {
            temp_adres[x1]=temp_adres_datch_3[x1];
          }
          EEPROM.write(x1+wybor_status_zapis_datch*10, temp_adres[x1]);
          delay(100);
        }
      }
      status_programmirovaniya=51;
      break;
   // переход из записи нового датчика в подменю датчики    
      case 103:
      status_programmirovaniya=51;
      break;    
    }
  }     
}

    
//////////////////////////////////////////////////////////
// подпрограмма определения выводимой на lcd страницы с учетом нажатых кнопок "ПРАВО", "ЛЕВО" и "Select"
void opredel_stranizy_lcd()
{
  if(status_programmirovaniya>0 && status_programmirovaniya<7)
  {
    straniza_programmirovaniya_1();
  }
  if(status_programmirovaniya>10 && status_programmirovaniya<16)
  {
    straniza_programmirovaniya_2();
  }
  if(status_programmirovaniya>20 && status_programmirovaniya<26)
  {
    straniza_programmirovaniya_3();
  }
  if(status_programmirovaniya>30 && status_programmirovaniya<36)
  {
    straniza_programmirovaniya_4();
  }
  if(status_programmirovaniya>40 && status_programmirovaniya<48)
  {
    straniza_programmirovaniya_5();
  }
  if(status_programmirovaniya>50 && status_programmirovaniya<56)
  {
    straniza_programmirovaniya_6();
  }
  if(status_programmirovaniya>60 && status_programmirovaniya<63)
  {
    straniza_programmirovaniya_7();
  }
  if(status_programmirovaniya>70 && status_programmirovaniya<73)
  {
    straniza_programmirovaniya_8();
  }
  if(status_programmirovaniya>80 && status_programmirovaniya<83)
  {
    straniza_programmirovaniya_9();
  }
  if(status_programmirovaniya>90 && status_programmirovaniya<92)
  {
    straniza_programmirovaniya_10();
  }
  if(status_programmirovaniya>100 && status_programmirovaniya<104)
  {
    straniza_programmirovaniya_11();
  }
} 


////////////////////////////////////////
// подпрограмма формирования изображения 1-й страницы на lcd (1 строка - ночь, день, утро; 2 строка - часы, датчики, выход из программирования)
void straniza_programmirovaniya_1()
{
// 1 строка
// с 0 позиции - Ночь
  lcd.setCursor(0, 0);
  if(status_programmirovaniya==1 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                  // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_slova_Noch();                // переход к подпрограмме вывода слова "Ночь"
  }
  lcd.print("  ");
// с 6 позиции - Утро
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==2 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_slova_Utro();                // переход к подпрограмме вывода слова "Утро"
  }
  lcd.print("  ");
// с 12 позиции - День
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==3 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_slova_Den();                   // переход к подпрограмме вывода слова "День"
  }
// 2 строка
// с 0 позиции - Часы
  lcd.setCursor(0, 1);
  if(status_programmirovaniya==4 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Time  ");
  }
// с 6 позиции - Датчики
  lcd.setCursor(6, 1);
  if(status_programmirovaniya==5 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.write(3);
    lcd.print("a");
    lcd.write(8);
    lcd.write(6);
    lcd.print("  ");
  }  
// с 12 позиции - Выход
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==6 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}
  
  
/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 2-й страницы на lcd (1 строка - ночь, часы, минуты, температура; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_2()
{
// 1 строка
// с 0 позиции - Ночь 
  lcd.setCursor(0, 0);
  wywod_na_lcd_slova_Noch();                                           // переход к подпрограмме вывода слова "Ночь"
  lcd.print(" ");
// с 5 позиции - часы начала ночного периода
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==11 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(nachalo_periodov[0]);                           // переход к подпрограмме вывода времени начала периода - часов
  }
  lcd.print(":");
 // с 8 позиции - минуты начала ночного периода 
  lcd.setCursor(8, 0);
  if(status_programmirovaniya==12 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(nachalo_periodov[1]);                       // переход к подпрограмме вывода времени начала периода - минут
  }  
  lcd.print(" ");
// с 11 позиции - температура ночного периода
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==13 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_temper(temperatura_room_ustanovka[0]);                  // переход к подпрограмме вывода температуры
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==14 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==15 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}
  
  
/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 3-й страницы на lcd (1 строка - утро, часы, минуты, температура; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_3()
{
// 1 строка
// с 0 позиции - Утро 
  lcd.setCursor(0, 0);
  wywod_na_lcd_slova_Utro();                                           // переход к подпрограмме вывода слова "Утро"
  lcd.print(" ");
// с 5 позиции - часы начала утреннего периода
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==21 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(nachalo_periodov[2]);                           // переход к подпрограмме вывода времени начала периода - часов
  }
  lcd.print(":");
 // с 8 позиции - минуты начала утреннего периода 
  lcd.setCursor(8, 0);
  if(status_programmirovaniya==22 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(nachalo_periodov[3]);                       // переход к подпрограмме вывода времени начала периода - минут
  }  
  lcd.print(" ");
// с 11 позиции - температура утреннего периода
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==23 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_temper(temperatura_room_ustanovka[1]);                  // переход к подпрограмме вывода температуры
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==24 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==25 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 4-й страницы на lcd (1 строка - день, часы, минуты, температура; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_4()
{
// 1 строка
// с 0 позиции - День 
  lcd.setCursor(0, 0);
  wywod_na_lcd_slova_Den();                                            // переход к подпрограмме вывода слова "День"
  lcd.print(" ");
// с 5 позиции - часы и минуты начала дневного периода
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==31 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(nachalo_periodov[4]);                           // переход к подпрограмме вывода времени начала периода - часов
  }
  lcd.print(":");
 // с 8 позиции - минуты начала утреннего периода 
  lcd.setCursor(8, 0);
  if(status_programmirovaniya==32 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(nachalo_periodov[5]);                       // переход к подпрограмме вывода времени начала периода - минут
  }  
  lcd.print(" ");
// с 11 позиции - температура дневного периода
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==33 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_temper(temperatura_room_ustanovka[2]);                  // переход к подпрограмме вывода температуры
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==34 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==35 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}  
  
  
/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 5-й страницы на lcd (1 строка - текущие часы, минуты, число, месяц и год; 2 строка - сохранение, выход на 1 стр.)
void straniza_programmirovaniya_5()
{  
// 1 строка
// с 0 позиции - часы 
  lcd.setCursor(0, 0);
  if(status_programmirovaniya==41 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_hour(hour);                     // переход к подпрограмме вывода на lcd текущего времени - часов и минут через двоеточие
  }
  lcd.print(":");
  lcd.setCursor(3, 0);
  if(status_programmirovaniya==42 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    wywod_na_lcd_min(minute);                     // переход к подпрограмме вывода на lcd текущего времени - часов и минут через двоеточие
  }
  lcd.print(" ");  
// с 6 позиции - текущее число
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==43 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(date<10)
    {
      lcd.print(" ");
    }
    lcd.print(date);
  }
  lcd.print("-");
// с 9 позиции - текущий месяц
  lcd.setCursor(9, 0);
  if(status_programmirovaniya==44 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(month<10)
    {
      lcd.print("0");
    }
    lcd.print(month);
  }
  lcd.print("-20");
// с 14 позиции - текущий год
  lcd.setCursor(14, 0);
  if(status_programmirovaniya==45 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("  ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(year<10)
    {
      lcd.print("0");
    }
    lcd.print(year);
  }
// 2 строка
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==46 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==47 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}  


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 6-й страницы на lcd (1 строка -  комнатный, уличный и водяной датчики; 2 строка - новый датчик, выход на 1 стр.)
void straniza_programmirovaniya_6()
{  
// 1 строка
// с 0 позиции -  комнатный датчик D-room
  lcd.setCursor(0, 0);
  if(status_programmirovaniya==51 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Room");
  }
  lcd.setCursor(4, 0);
  lcd.print(" ");
// с  5 позиции - уличный 
  lcd.setCursor(5, 0);
  if(status_programmirovaniya==52 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Stret ");
  }
// с  11 позиции - водяной 
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==53 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Water");
  }
// 1 строка
// с позиции 0 - новый датчик - New
  lcd.setCursor(0, 1);
  if(status_programmirovaniya==54 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("New         ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==55 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Exit");
  }
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 7-й страницы на lcd (1 строка -  комнатный датчик, удалить, выход на 1 стр.; 2 строка - адрес комнатного датчика)
void straniza_programmirovaniya_7()
{  
// 1 строка
// с 0 позиции -  комнатный датчик Room
  lcd.setCursor(0, 0);
  lcd.print("Room  ");
// с  6 позиции 
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==61 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Delet ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==62 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Exit");
  }
// 2 строка
// с позиции 0 - адрес датчика
  lcd.setCursor(0, 1);
  for(byte f1=0; f1<8; f1++)
  {
    lcd.print(adres_dat_temp_room[f1], HEX);
  }
  lcd.print("       ");
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 8-й страницы на lcd (1 строка -  уличный датчик, удалить, выход на 1 стр.; 2 строка - адрес комнатного датчика)
void straniza_programmirovaniya_8()
{  
// 1 строка
// с 0 позиции -  уличный датчик Stret
  lcd.setCursor(0, 0);
  lcd.print("Stret ");
// с  6 позиции 
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==71 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
  lcd.print("Delet ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==72 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
// 2 строка
// с позиции 0 - адрес датчика
  lcd.setCursor(0, 1);
  for(byte f2=0; f2<8; f2++)
  {
    lcd.print(adres_dat_temp_street[f2], HEX);
  }
  lcd.print("       ");
}


/////////////////////////////////////////////////////////////
// подпрограмма формирования изображения 9-й страницы на lcd (1 строка -  датчик котловой воды, удалить, выход на 1 стр.; 2 строка - адрес комнатного датчика)
void straniza_programmirovaniya_9()
{  
// 1 строка
// с 0 позиции -  уличный датчик Stret
  lcd.setCursor(0, 0);
  lcd.print("Water ");
// с  6 позиции 
  lcd.setCursor(6, 0);
  if(status_programmirovaniya==81 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("      ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Delet ");
  }
// с позиции 12 - выход  
  lcd.setCursor(12, 0);
  if(status_programmirovaniya==82 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
// 2 строка
// с позиции 0 - адрес датчика
  lcd.setCursor(0, 1);
  for(byte f3=0; f3<8; f3++)
  {
    lcd.print(adres_dat_temp_water[f3], HEX);
  }
  lcd.print("       ");
}


//////////////////////////////////////////////////////////
// подпрограмма формирования страницы 10-й страницы на lcd (1 строка -  надпись, что новых датчиков нет или их больше одного. 2 строка - выход)
void straniza_programmirovaniya_10()
{
  if(kolvo_new_datch==0)
  {
    lcd.setCursor(0, 0);
    lcd.print("No new datchik  ");
    lcd.setCursor(0, 1);
    if(status_programmirovaniya==91 && miganie_parametra_programmirovaniya==false)
    {
      lcd.print("                ");                     // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
    }
    else
    {
      lcd.print("Exit            ");
    }
  }
// вывод инфы на дисплей о подключении более 1 нового датчика и необходимости выключения и выключения устройства с 1 новым датчиком для его записи в EEPROM и присвоения ему статуса: комнатного, уличного и котловой воды
  if(kolvo_new_datch>1)
  {
    lcd.setCursor(0, 0);
    lcd.print("New datch > 1   ");
    lcd.setCursor(0,1);
    if(status_programmirovaniya==91 && miganie_parametra_programmirovaniya==false)
    {
      lcd.print("                ");                     // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
    }
    else
    {
      lcd.print("Exit            ");
    }
  }
  if(kolvo_new_datch==1)
  {
    status_programmirovaniya=101;
  }
} 


//////////////////////////////////////////////////////////
// подпрограмма формирования страницы 11-й страницы на lcd (1 строка -  надпись, что новых датчиков нет или их больше одного. 2 строка - выход)
void straniza_programmirovaniya_11()
{
// 1 строка  
  lcd.setCursor(0, 0);
  lcd.print("NewDat Vid:");
  lcd.setCursor(11, 0);
  if(status_programmirovaniya==101 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("     ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    switch(wybor_status_zapis_datch)
    {
      case 1:
      lcd.print("Room ");
      break;
      case 2:
      lcd.print("Stret");
      break;
      case 3:
      lcd.print("Water");
      break;
    }
  }
// 2 строка  
// с позиции 0 - "Save" сохранить
  lcd.setCursor(0, 1);
  lcd.print("Save ");
// с позиции 5 меняющиеся "Yes" или "No"
  lcd.setCursor(5, 1);
  if(status_programmirovaniya==102 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("   ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    if(status_wybora_save==true)
    {
      lcd.print("Yes");
    }
    else
    {
      lcd.print("No ");
    }
  }
  lcd.print("    ");
// с позиции 12 - выход 
  lcd.setCursor(12, 1);
  if(status_programmirovaniya==103 && miganie_parametra_programmirovaniya==false)
  {
    lcd.print("    ");                                                   // создает мигание выбранного параметра путем выключения его изображения на 0,1 сек. через 0,2 сек.
  }
  else
  {
    lcd.print("Exit");
  }
}  
  

/////////////////////////////////////////////////////////////////////////////
// подпрограмма проверки адресов подключенных датчиков температуры на их соответствие данным, содержащимся в EEPROM. 
void proverka_podkluch_datchikov_temp()
{
// считываем адреса датчиков, содержащиеся в EEPROM
  read_eeprom_adres_datch();
// считываем адреса подключенных датчиков температуры  
  for(byte b=1; b<4; b++)
  {
    ds.reset();
    ds.search(temp_adres);
    for(byte i=0; i<8; i++)
    {
      switch(b)
      {
        case 1:
        temp_adres_datch_1[i]=temp_adres[i];
        break;
        case 2:
        temp_adres_datch_2[i]=temp_adres[i];
        break;
        case 3:
        temp_adres_datch_3[i]=temp_adres[i];
        break;                                                
      }
    }
  }
  ds.reset();
  ds.search(sss);                            // нужна для исключения ошибок, так как командой search последний датчик считывывается два раза. Результат этой команды не используется
////////////////////////////////////
// Проверяем на отсутствие какого-либо датчика и исключения дальнейших ошибок от возможной записи в в несколько переменных одного и того же адреса
// Если в адресе 3 считанного датчика содержится адрес 2 считанного датчика, то записываем нули
  if(temp_adres_datch_3[0]==temp_adres_datch_2[0] && temp_adres_datch_3[1]==temp_adres_datch_2[1] && temp_adres_datch_3[2]==temp_adres_datch_2[2] && temp_adres_datch_3[3]==temp_adres_datch_2[3] &&
     temp_adres_datch_3[4]==temp_adres_datch_2[4] && temp_adres_datch_3[5]==temp_adres_datch_2[5] && temp_adres_datch_3[6]==temp_adres_datch_2[6] && temp_adres_datch_3[7]==temp_adres_datch_2[7])
  {
    for(byte qwerty=0; qwerty<8; qwerty++)
    {
      temp_adres_datch_3[qwerty]=0;
    }
  } 
// Если в адресе 3 считанного датчика содержится адрес 1 считанного датчика, то записываем нули
  if(temp_adres_datch_3[0]==temp_adres_datch_1[0] && temp_adres_datch_3[1]==temp_adres_datch_1[1] && temp_adres_datch_3[2]==temp_adres_datch_1[2] && temp_adres_datch_3[3]==temp_adres_datch_1[3] &&
     temp_adres_datch_3[4]==temp_adres_datch_1[4] && temp_adres_datch_3[5]==temp_adres_datch_1[5] && temp_adres_datch_3[6]==temp_adres_datch_1[6] && temp_adres_datch_3[7]==temp_adres_datch_1[7])
  {
    for(byte qwerty=0; qwerty<8; qwerty++)
    {
      temp_adres_datch_3[qwerty]=0;
    }
  } 
// Если в адресе 2 считанного датчика содержится адрес 1 считанного датчика, то записываем нули
  if(temp_adres_datch_2[0]==temp_adres_datch_1[0] && temp_adres_datch_2[1]==temp_adres_datch_1[1] && temp_adres_datch_2[2]==temp_adres_datch_1[2] && temp_adres_datch_2[3]==temp_adres_datch_1[3] &&
     temp_adres_datch_2[4]==temp_adres_datch_1[4] && temp_adres_datch_2[5]==temp_adres_datch_1[5] && temp_adres_datch_2[6]==temp_adres_datch_1[6] && temp_adres_datch_2[7]==temp_adres_datch_1[7])
  {
    for(byte qwerty=0; qwerty<8; qwerty++)
    {
      temp_adres_datch_2[qwerty]=0;
    }
  } 
  kolvo_new_datch=0;
// сравниваем считанные адреса подключенных датчиков и содержащиеся в памяти
// датчик с адресом temp_adres_datch_1
  if(temp_adres_datch_1[0]==0x28)
  {
    if(temp_adres_datch_1[0]==adres_dat_temp_room[0] && temp_adres_datch_1[1]==adres_dat_temp_room[1] && temp_adres_datch_1[2]==adres_dat_temp_room[2] && temp_adres_datch_1[3]==adres_dat_temp_room[3] &&
       temp_adres_datch_1[4]==adres_dat_temp_room[4] && temp_adres_datch_1[5]==adres_dat_temp_room[5] && temp_adres_datch_1[6]==adres_dat_temp_room[6] && temp_adres_datch_1[7]==adres_dat_temp_room[7])
    {
      status_schit_datch_new[0]=false;
    }
    else
    {
      if(temp_adres_datch_1[0]==adres_dat_temp_street[0] && temp_adres_datch_1[1]==adres_dat_temp_street[1] && temp_adres_datch_1[2]==adres_dat_temp_street[2] && temp_adres_datch_1[3]==adres_dat_temp_street[3] &&
         temp_adres_datch_1[4]==adres_dat_temp_street[4] && temp_adres_datch_1[5]==adres_dat_temp_street[5] && temp_adres_datch_1[6]==adres_dat_temp_street[6] && temp_adres_datch_1[7]==adres_dat_temp_street[7])
      {
        status_schit_datch_new[0]=false;
      }
      else
      {
        if(temp_adres_datch_1[0]==adres_dat_temp_water[0] && temp_adres_datch_1[1]==adres_dat_temp_water[1] && temp_adres_datch_1[2]==adres_dat_temp_water[2] && temp_adres_datch_1[3]==adres_dat_temp_water[3] &&
           temp_adres_datch_1[4]==adres_dat_temp_water[4] && temp_adres_datch_1[5]==adres_dat_temp_water[5] && temp_adres_datch_1[6]==adres_dat_temp_water[6] && temp_adres_datch_1[7]==adres_dat_temp_water[7])
        {
          status_schit_datch_new[0]=false;
        }
        else
        {
          status_schit_datch_new[0]=true;
          kolvo_new_datch++;
        } 
      }
    }
  }
  else
  {
    status_schit_datch_new[0]=false;
  }
// датчик с адресом temp_adres_datch_2
 if(temp_adres_datch_2[0]==0x28)
  {
    if(temp_adres_datch_2[0]==adres_dat_temp_room[0] && temp_adres_datch_2[1]==adres_dat_temp_room[1] && temp_adres_datch_2[2]==adres_dat_temp_room[2] && temp_adres_datch_2[3]==adres_dat_temp_room[3] &&
       temp_adres_datch_2[4]==adres_dat_temp_room[4] && temp_adres_datch_2[5]==adres_dat_temp_room[5] && temp_adres_datch_2[6]==adres_dat_temp_room[6] && temp_adres_datch_2[7]==adres_dat_temp_room[7])
    {
      status_schit_datch_new[1]=false;
    }
    else
    {
      if(temp_adres_datch_2[0]==adres_dat_temp_street[0] && temp_adres_datch_2[1]==adres_dat_temp_street[1] && temp_adres_datch_2[2]==adres_dat_temp_street[2] && temp_adres_datch_2[3]==adres_dat_temp_street[3] &&
         temp_adres_datch_2[4]==adres_dat_temp_street[4] && temp_adres_datch_2[5]==adres_dat_temp_street[5] && temp_adres_datch_2[6]==adres_dat_temp_street[6] && temp_adres_datch_2[7]==adres_dat_temp_street[7])
      {
        status_schit_datch_new[1]=false;
      }
      else
      {
        if(temp_adres_datch_2[0]==adres_dat_temp_water[0] && temp_adres_datch_2[1]==adres_dat_temp_water[1] && temp_adres_datch_2[2]==adres_dat_temp_water[2] && temp_adres_datch_2[3]==adres_dat_temp_water[3] &&
           temp_adres_datch_2[4]==adres_dat_temp_water[4] && temp_adres_datch_2[5]==adres_dat_temp_water[5] && temp_adres_datch_2[6]==adres_dat_temp_water[6] && temp_adres_datch_2[7]==adres_dat_temp_water[7])
        {
          status_schit_datch_new[1]=false;
        }
        else
        {
          status_schit_datch_new[1]=true;
          kolvo_new_datch++;
        }
      }
    }
  }
  else
  {
    status_schit_datch_new[1]=false;
  }
// датчик с адресом temp_adres_datch_3
  if(temp_adres_datch_3[0]==0x28)
  {
    if(temp_adres_datch_3[0]==adres_dat_temp_room[0] && temp_adres_datch_3[1]==adres_dat_temp_room[1] && temp_adres_datch_3[2]==adres_dat_temp_room[2] && temp_adres_datch_3[3]==adres_dat_temp_room[3] &&
       temp_adres_datch_3[4]==adres_dat_temp_room[4] && temp_adres_datch_3[5]==adres_dat_temp_room[5] && temp_adres_datch_3[6]==adres_dat_temp_room[6] && temp_adres_datch_3[7]==adres_dat_temp_room[7])
    {
      status_schit_datch_new[2]=false;
    }
    else
    {
      if(temp_adres_datch_3[0]==adres_dat_temp_street[0] && temp_adres_datch_3[1]==adres_dat_temp_street[1] && temp_adres_datch_3[2]==adres_dat_temp_street[2] && temp_adres_datch_3[3]==adres_dat_temp_street[3] &&
         temp_adres_datch_3[4]==adres_dat_temp_street[4] && temp_adres_datch_3[5]==adres_dat_temp_street[5] && temp_adres_datch_3[6]==adres_dat_temp_street[6] && temp_adres_datch_3[7]==adres_dat_temp_street[7])
      {
        status_schit_datch_new[2]=false;
      }
      else
      {
        if(temp_adres_datch_3[0]==adres_dat_temp_water[0] && temp_adres_datch_3[1]==adres_dat_temp_water[1] && temp_adres_datch_3[2]==adres_dat_temp_water[2] && temp_adres_datch_3[3]==adres_dat_temp_water[3] &&
           temp_adres_datch_3[4]==adres_dat_temp_water[4] && temp_adres_datch_3[5]==adres_dat_temp_water[5] && temp_adres_datch_3[6]==adres_dat_temp_water[6] && temp_adres_datch_3[7]==adres_dat_temp_water[7])
        {
          status_schit_datch_new[2]=false;
        }
        else
        {
          status_schit_datch_new[2]=true;
          kolvo_new_datch++;
        }
      }
    }
  }
  else
  {
    status_schit_datch_new[2]=false;
  }
}

 
/////////////////////////////////////////////////////////////////////////////
void setup()
{
  wdt_disable();                                            // останавливаем таймер перезагрузки
  Wire.begin();                                             // старт интерфейса I2C (выводы 4 и 5 для UNO). Необходим для часов.
 // инициализация выхода управления реле котла
  pinMode(relekotla, OUTPUT);                               // вывод, предназначенный для управления котлом, устанавливаем как выход
  digitalWrite(relekotla, LOW);                             // устанавливаем на выходе управления котлом 0
  lcd.begin(16, 2);                                         // включаем lcd
  lcd.createChar(1, znak_lcd_plamya);                       // региструем индивидуальный знак в виде пламени
  lcd.createChar(2, znak_lcd_gradus);                       // региструем индивидуальный знак в виде градуса
  lcd.createChar(3, znak_lcd_D_Rus); 
  lcd.createChar(4, znak_lcd_b_Rus); 
  lcd.createChar(5, znak_lcd_n_Rus);
  lcd.createChar(6, znak_lcd_ch_Rus);                        
  lcd.createChar(7, znak_lcd_u_Rus);
  lcd.createChar(8, znak_lcd_t_Rus);
  poluchenie_wremeni();                                     // считываем время с часов
  opredelenie_perioda_wremeni();                            // для моментального отражения на Lcd временного периода после включения и не ждать истечения задаваемого интервала
  nachal_ustanovki();                                       // переход к подпрограмме считывания данных из EEPROM и их проверке
  lcd.clear(); 
  temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3); 
  for(byte rrr=0; rrr<3; rrr++)
  {
    temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3);             // 3 раза считываем температуру и записываемх их в переменные temperatura_pamyat[] для исключения ошибок при сравнении. 
    temperatura_room_pamyat[rrr]=temperatura_room;
  }
  temperatura_street=schit_datchik_temperatury(adres_dat_temp_street, 1);
  lcd.clear();
  wdt_enable(WDTO_8S);                                      // запускае таймер перезагрузки с длительностью 8 сек.
}  

///////////////////////////////////////////////////////////////////
void loop()
{
  
  nashat_knopka=analogRead(0);                           // постоянно считываем данные с аналогового входа
// определяем факт нажатия кнопки Select (показатель 639) в течение 3 секунд для перехода к подпрограмме программирования
  if(nashat_knopka>550&&nashat_knopka<750)
  {
    nashat_knopka=1023;                                  // для исключения ошибок присваиваем переменной значение, равное состоянию, когда ни одна из кнопок не нажата
    delay(3000);                                         // необходиая длительность удержания кнопки Select для перехода в режим программирования
    nashat_knopka=analogRead(0);
    if(nashat_knopka>550&&nashat_knopka<750)
    {
      nashat_knopka=1023;                                // для исключения ошибок присваиваем переменной значение, равное состоянию, когда ни одна из кнопок не нажата
      programmirovanie();
    }                    
  }
  wywod_na_lcd_tekusch();                                // переход к подпрограмме вывода текущих данных на дисплей.       
//////
  poluchenie_wremeni();                                  // переход к подпрограмме считывания времени с ds3231
  opredelenie_perioda_wremeni();                         // переход к подпрограмме определения временного периода (ночного, утреннего или дневного) и присваивания переменной "temperatura_sravnenia" заданной пользователем температуры для последующего сравненния со считанной.
// проверяем достижение необходимого интервала для запуска подпрограммы считывания комнатной температуры
  if(formirovanie_intervala(time_snach_progi_dat_room)>interval_zapuska_dat_room)
  {
    time_snach_progi_dat_room=time_snachala_progi;
    temperatura_room=schit_datchik_temperatury(adres_dat_temp_room, 3);       // переход к подпрограмме считывания температуры с уличного датчика температуры. 3 - кол-во считываний
    wyhod_temp_room_predel();                            // переход к подпрограмме определения выхода температуры за установленный пользователем предел более чем на 1 градус и гистерезис и включения звукого уведомления
  }
  
// проверяем достижение необходимого интервала для запуска подпрограммы считывания уличной температуры
  if(formirovanie_intervala(time_snach_progi_dat_street)>interval_zapuska_dat_street)
  {
    time_snach_progi_dat_street=time_snachala_progi;
    temperatura_street=schit_datchik_temperatury(adres_dat_temp_street, 1);    // переход к подпрограмме считывания температуры с уличного датчика температуры. 1 - кол-во считываний
  }
  proverka_temperatury_room();                           // переход к подпрограмме проверки считанной температуры на наличие грубых ошибок
  sravnenie_temp_room_upravl_wychod();                   // переход к подпрограмме сравнения полученной с датчика температуры с установленными пользователем температурами с учетом времени и выполнение команд на включение или выключение котла
  problem_datch_room();                                  // переход к подпрограмме определения отсутствия ответа от комнатного датчика в течение длительного времени
  wdt_reset();                                           // обнуляем таймер перезагрузки
}

[/code]
c0013r
Offline
Зарегистрирован: 06.12.2015

trembo пишет:

Совет где повесить датчик.......
Мой совет не использовать температуру внутри для регулировки
Сам соседям лично выкидывал комнатные термостаты " втюханные" разными сантехниками.
А люди доверчивы, кнопочки жимкают, видиш, говорят: я тут температуру поставил, всё должно само работать
А у них то холодно то жарко.

Была такая же фигня, пока не настроил реакцию комнатного термостата на 0,5С, по умолчанию было 1,5С, во всем помещении температура с разницей 0,5С, что в общем то комфортно, суть в том, чтобы выбрать правильное место для датчика или брать средние/приоритные показания, если этих датчиков несколько.

Алгоритм с температрой улицы и носителя скорее для мини-котельни на несколько домов/квартир и явно не для обычных бытовых котлов, сам производитель начинает работу с термостатом от 55С носителя, повышая со временем, если термостат не реагирует. Расход газа и эл. с термостатом на малой температуре к сожалению не могу сравнить, но малая пост.температура носителя и высокая с термостатом имеют очень существенную разницу в пользу последнего.

Сам сейчас собираю термостат с интеграцией в УД, из наличия градусник DHT11, пробую подобрать к нему гистерезис, но чувствую надо брать другой с десятичными показаниями для этих дел.

rekrut007
Offline
Зарегистрирован: 19.10.2014

Изначально свою программу писал с учетом двух датчиков в одном помещении. Потом отказался от этой затеи, поскольку вероятность выхода из строя одного из двух датчиков выше, чем у одного, и пока не продумал алгоритм работы скетча при данной ситуации.

Думаю, что не стоит управлять термостатом из УД или центрального блока (ЦБ). Если такая возможность будет прописана в самой программе, то этим могут воспользоваться сторонние лица. Котел не тот прибор, чтобы в его работу кто-то иной вмешивался. Максимум термостат все необходимые параметры может отправлять в УД или ЦБ и то не на основании получаемых запросов.

vlad219i
Offline
Зарегистрирован: 05.03.2014

Сам сейчас собираю термостат с интеграцией в УД, из наличия градусник DHT11, пробую подобрать к нему гистерезис, но чувствую надо брать другой с десятичными показаниями для этих дел.

И это правильно. Насколько я понял, беда недорогих комнатных термостатов - как раз большой гистерезис, от этого и температура в помещении здорово плавает. У меня в доме в результате годового тест-драйва получилась комбинированная система - комнатный термостат (собственно, из топика) плюс уличный датчик, прикрученный к котлу. Подобрал подходящую кривую регулирования, ничего подкручивать не приходится. Котёл Baxi Mainfour 240F, подключение уличного датчика предусмотрено производителем, подходящий по параметрам я подобрал у китайцев.

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011

DHT11 - все его ругают.....

http://electronics-lab.ru/blog/mcu/46.html

 

Vladis_a
Offline
Зарегистрирован: 13.12.2015

vlad219i пишет:

Котёл Baxi Mainfour 240F, подключение уличного датчика предусмотрено производителем, подходящий по параметрам я подобрал у китайцев.

Здравствуйте! Я совсем новичок, но заинтересовался Ардуино и делаю самые первые шаги. У меня котел Baxi Ecofour 24, искал информацию по термостату и уличному датчику, а наткнулся на Ваш проект. К моему котлу все подключается, если верить инструкции. Если не сочтете за наглость, напишите, пожалуйста, какие компоненты мне необходимо купить, чтобы повторить Ваш проект.

vlad219i
Offline
Зарегистрирован: 05.03.2014

Vladis_a пишет:

какие компоненты мне необходимо купить, чтобы повторить Ваш проект.

 
Ну ещё пару конденсаторов 0.1мкФ для подавления дребезга энкодера, немного проводов, канифоль-припой-паяльник. :-)
 
Уличный термодатчик для моего котла я брал такой: http://www.ebay.com/itm/1m-NTC-Thermistor-accuracy-temperature-sensor-10K-1-3950-Waterproof-Probe-/400985262901
К Вашему котлу он тоже подойдёт, думаю. 
 
Удачи!
 
Vladis_a
Offline
Зарегистрирован: 13.12.2015

vlad219i пишет:

Удачи!
 

Премного благодарен! Пошел изучать все это дело. Если будут вопросы ( а они будут ), то отпишусь.

Ну вот и сразу первый вопрос - с помощью чего Вы заливали Вашу программу? Простите за ламерские вопросы, но я сегодня только первый день читаю про Ардуино.

Maverik
Offline
Зарегистрирован: 12.09.2012

JollyBiber пишет:

Человек в первую очередь ощущает температуру твердых тел вокруг себя, а только вторично - температуру воздуха.

В домах, где стены холодные (температурой до +20°C - то есть ниже темп.воздуха), а возух должен обогреть и самого человека и твердые тела вокруг, можно чувствовать холод даже при температуре воздуха в +25°C. Ведь холодные стены на расстоянии "высасывают" излучаемое телом человека тепло. И оно постоянно уходит "в никуда". А человек, в этом случае, выступает постоянным "нагревательным прибором", не айс..

 

извиняюсь за некропост.

уважаемый ДжолиБибер, Вы хоть сами понимаете, что процитировали явно имбецильный текст и график тоже из разряда альтернативно одаренных.

vlad219i
Offline
Зарегистрирован: 05.03.2014

Vladis_a пишет:

Ну вот и сразу первый вопрос - с помощью чего Вы заливали Вашу программу? Простите за ламерские вопросы, но я сегодня только первый день читаю про Ардуино.

На сайте разработчика www.arduino.cc в разделе 'download' скачайте 'Arduino software' - с помошью этого софта всё и делается.

Vladis_a
Offline
Зарегистрирован: 13.12.2015

Благодарю! С этим я уже разобрался. :) Сейчас активно изучаю Ваш скетч, чтобы понять, что куда подключается. После понимания этого набросаю схему подключений и выложу на Ваш суд. Возможно, пригодится таким же новичкам, как и я, для повторения Вашего проекта.

Клапауций 321
Offline
Зарегистрирован: 17.12.2015

Maverik пишет:

уважаемый ДжолиБибер, Вы хоть сами понимаете, что процитировали явно имбецильный текст и график тоже из разряда альтернативно одаренных.

таки, "да"... мне, тоже, про тёплые твёрдые тела не понравилось - чувствую себя комфортно исключительно рядом с тёплым и мягким телом противоположного пола.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Maverik пишет:

извиняюсь за некропост.

уважаемый ДжолиБибер, Вы хоть сами понимаете, что процитировали явно имбецильный текст и график тоже из разряда альтернативно одаренных.

Аргументы будут? Собственные утверждения, доводы, факты, расчеты? Или ограничимся утверждением кг/ам?

Ради эксперимента можете попробовать прислониться в жару к бетонной стене которая назодится в тени.

Клапауций 321
Offline
Зарегистрирован: 17.12.2015

JollyBiber пишет:

Аргументы будут?

у меня вопрос: почему тела твёрдые?

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Клапауций 321 пишет:

JollyBiber пишет:

Аргументы будут?

у меня вопрос: почему тела твёрдые?

По утрам?

Клапауций 321
Offline
Зарегистрирован: 17.12.2015

JollyBiber пишет:

По утрам?

...вокруг нас [С] твёрдые тела - это уже некомфортно.

bwn
Offline
Зарегистрирован: 25.08.2014

JollyBiber пишет:

Maverik пишет:

извиняюсь за некропост.

уважаемый ДжолиБибер, Вы хоть сами понимаете, что процитировали явно имбецильный текст и график тоже из разряда альтернативно одаренных.

Аргументы будут? Собственные утверждения, доводы, факты, расчеты? Или ограничимся утверждением кг/ам?

Ради эксперимента можете попробовать прислониться в жару к бетонной стене которая назодится в тени.

Даже не надо прислоняться, при хорошем морозе на улице просто подойти к окну и почувствовать холод, это вашу тепловую энергию  вытягивает через излучение.

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Клапауций 321 пишет:

...вокруг нас [С] твёрдые тела - это уже некомфортно.

Процесс превращения энергии излучения во внутреннюю энергию поглощающего тела называется поглощением. Большинство твердых и жидких тел излучают энергию всех длин волн в интервале от 0 до ∞, то есть имеют сплошной спектр излучения. Газы испускают энергию только в определенных интервалах длин волн (селективный спектр излучения). Твердые тела излучают и поглощают энергию поверхностью, а газы — объемом.

Клапауций 321
Offline
Зарегистрирован: 17.12.2015

JollyBiber пишет:

Клапауций 321 пишет:

...вокруг нас [С] твёрдые тела - это уже некомфортно.

Процесс превращения энергии излучения во внутреннюю энергию поглощающего тела называется поглощением. Большинство твердых и жидких тел излучают энергию всех длин волн в интервале от 0 до ∞, то есть имеют сплошной спектр излучения. Газы испускают энергию только в определенных интервалах длин волн (селективный спектр излучения). Твердые тела излучают и поглощают энергию поверхностью, а газы — объемом.

ты график читал или смотрел? - написано "твёрдых тел вокруг нас[С]"

не википедию мне цитируй, а объясни, с какого будуна вокруг нас тела твёрдые?

 

JollyBiber
JollyBiber аватар
Offline
Зарегистрирован: 08.05.2012

Объясняю - стены, пол и крыша в доме сторятся из твердых материалов во избежании обрушения. Мебель производится в основном из дерева и пластика, поэтому коэффициент теплообмена у них ввиду более низкой плотности гораздо ниже.

Клапауций 321
Offline
Зарегистрирован: 17.12.2015

JollyBiber пишет:

Объясняю - стены, пол и крыша в доме сторятся из твердых материалов во избежании обрушения. Мебель производится в основном из дерева и пластика, поэтому коэффициент теплообмена у них ввиду более низкой плотности гораздо ниже.

в твоём доме мягкая мебедь из дерева и пластика потому, что нет опасности обрушения стола на табурет, а потолка нет вообще?

yul-i-an
yul-i-an аватар
Offline
Зарегистрирован: 10.12.2012

ТС а Вы не думали об использования в термостате Эффективной температуры (ощущаемой)?

vlad219i
Offline
Зарегистрирован: 05.03.2014

yul-i-an пишет:

ТС а Вы не думали об использования в термостате Эффективной температуры (ощущаемой)?

Нет, не думал. И не собираюсь.

 

Vladis_a
Offline
Зарегистрирован: 13.12.2015

Как и обещал. Если я все правильно понял, то схема подключения выглядит так. Надеюсь, если что, vlad219i меня поправит.

umpelev69
Offline
Зарегистрирован: 01.04.2015

Помогите пж с библиотекой wdt.h (сколько не искал так и не нашел извените) использую arduino 1.06 zip архив

trembo
trembo аватар
Онлайн
Зарегистрирован: 08.04.2011

Я нашёл тут :

arduino-1.6.7\hardware\tools\avr\avr\include\avr

И здесь :

arduino-1.7.8\hardware\tools\avr\avr\include\avr

umpelev69
Offline
Зарегистрирован: 01.04.2015

а как её добавить стандартным вариантом не получается :(

Jeka_M
Jeka_M аватар
Offline
Зарегистрирован: 06.07.2014
#include <avr/wdt.h>

void setup() {
  // put your setup code here, to run once:
}

void loop() {
  // put your main code here, to run repeatedly: 
}

 

Vladis_a
Offline
Зарегистрирован: 13.12.2015

В скетче вот что заметил - #define ONE_WIRE_BUS A1.

А разве этот датчик (DS18B20) может работать по аналоговым пинам?

 
vlad219i
Offline
Зарегистрирован: 05.03.2014

Неверная постановка вопроса.

Аналоговый пин может быть настроен как цифровой (точнее, он и есть цифровой, но внутри чипа к нему подключен АЦП и он используется при необходимости после соответствующей инициализации). Подробности - в даташите на чип.

В общем - в данном случае A1 используется как цифровой пин.

Vladis_a
Offline
Зарегистрирован: 13.12.2015

vlad219i пишет:

В общем - в данном случае A1 используется как цифровой пин.

Премного благодарен за разъяснения! Просто столкнулся с тем, что у меня DS18B20 показывает только какие-то буквы nan, хотя отдельно работает как положено.

И еще вопрос - выходы реле (их в общей сложности 3, средний, понятно, общий) Вы как подключали к котлу?

vlad219i
Offline
Зарегистрирован: 05.03.2014

Vladis_a пишет:

И еще вопрос - выходы реле (их в общей сложности 3, средний, понятно, общий) Вы как подключали к котлу?

Замыкающий контакт реле - штатно, ко входу комнатного термостата котла (когда контакт замкнут - котлу разрешено зажигать горелку, когда разомкнут - запрещено).

SU-27-16
SU-27-16 аватар
Offline
Зарегистрирован: 13.08.2012

vlad219i   , до окончания зимы создана дешёвая схема управления газовым котлом с НЕ электронным управлением
а как ты сказал "Когда контакт замкнут - котлу разрешено зажигать горелку, когда разомкнут - запрещено)."
Надо ? поделюсь...
....если у тибя схема котла и отоплен
ия такая же

vlad219i
Offline
Зарегистрирован: 05.03.2014

SU-27-16 пишет:

vlad219i   , до окончания зимы создана дешёвая схема управления газовым котлом с НЕ электронным управлением
а как ты сказал "Когда контакт замкнут - котлу разрешено зажигать горелку, когда разомкнут - запрещено)."
Надо ? поделюсь...
....если у тибя схема котла и отоплен
ия такая же

Прочёл все слова, но не понял смысла. Если это предложение - то мне ни к чему, у меня всё работает как задумано...

 

Vladis_a
Offline
Зарегистрирован: 13.12.2015

Vlad219i, а из-за чего может показывать температуру в виде букв "nan"? Схему проверил, все в порядке. Датчик отдельно тоже работает нормально. Как только подключаешь по схеме, вместо температуры показывает вот это "nan".

vlad219i
Offline
Зарегистрирован: 05.03.2014

Vladis_a пишет:

Vlad219i, а из-за чего может показывать температуру в виде букв "nan"? Схему проверил, все в порядке. Датчик отдельно тоже работает нормально. Как только подключаешь по схеме, вместо температуры показывает вот это "nan".

Мне такая ошибка не встречалась.

Подтяжка есть (резистор 4,7к на +5в с A1)?

"Датчик отдельно работает нормально" - как проверяли?

 

Vladis_a
Offline
Зарегистрирован: 13.12.2015

Да, резистор стоит.

Проверял просто. Взял этот же датчик, подключил тремя проводами. Залил скетч из примеров. Все в норме, температуру показывает.

vlad219i
Offline
Зарегистрирован: 05.03.2014

Vladis_a пишет:

Да, резистор стоит.

Проверял просто. Взял этот же датчик, подключил тремя проводами. Залил скетч из примеров. Все в норме, температуру показывает.

Стало быть, остаётся только проверить, одинаковые ли библиотеки используются в примере и в этом скетче. Ну и в случае если нет - копать в этом направлении.

Vladis_a
Offline
Зарегистрирован: 13.12.2015

Добрый вечер! Перепробовал кучу библиотек, пайку проверил, датчик рабочий. Все равно температуру показывает вот так:

Подскажите, куда копнуть?

klbsss
Offline
Зарегистрирован: 16.07.2015

Сделайте холодный старт, зажмите энкодер при включении ардуино

Vladis_a
Offline
Зарегистрирован: 13.12.2015

Вы меня спасли!!!! Премного благодарен!!! Все запустилось и показывает. 

vlad219i
Offline
Зарегистрирован: 05.03.2014

klbsss пишет:
Сделайте холодный старт, зажмите энкодер при включении ардуино

Спасибо за спасённый мозг - у меня вариантов не осталось, что ещё это может быть. :-)

Как всё просто, а...

klbsss
Offline
Зарегистрирован: 16.07.2015

vlad219i, это вам спасибо большое за отличный скетч, отличная реализация использования энкодера, памяти, меню...

На базе вашего примера сделал управление тт котлом и бойлером коственого нагрева.

Управление турбиной, насосами, заслонкой+ с помощью esp8266 рулю всем этим по вайфаю) 

Это было первое мое знакомство с ардуино, спасибо еще раз)

Vladis_a
Offline
Зарегистрирован: 13.12.2015

vlad219i - ​Вам огромаднейшее спасибо за отличную идею и, не менее отличную реализацию!

klbsss -​ Вам за решение проблемы с запуском! 

В итоге все работает, температуру показывает, сейчас буду подключать к котлу.