Мой термостат для котла BAXI

Stas046
Offline
Зарегистрирован: 10.12.2014

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

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

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

Первое собранное устройство выглядит так:

Это головное устройство, оно находится возле котла и дает команду на вкл./выкл. )

С ним впаре работает:

Дистанционный датчик температуры, он переодически отправляет "голове" температуру в некой комнате.

Stas046
Offline
Зарегистрирован: 10.12.2014

Отработала эта связка пару месяцев и такую же захотел установить родственник. Собрал и ему. Его вариант выглядит так:

Датчик

Далее уже конкретно к железу :)

Умеет следующее:

поддерживает в доме дневную и ночную температуру;

два датчика температуры (дистанционный и местный, расположенный недалеко от котла);

основной датчик дистанционный, при его отключении или поломке автоматически переходит на работу с местным датчиком;

настройка температур, время срабатывания, гистерезиса, коррекция часов и еще некоторые сервисные настройки;

сохранение и вывод некоторых ошибок работы устройства и их сброс; 

дистанционный датчик отправляет температуру на основное устройство с некоторыми интервалами и выводит ее на 7сегментник, меняет яркость дисплея в зависимости от освещения;

 

Stas046
Offline
Зарегистрирован: 10.12.2014

Для сборки этой системы потребовались:

2 arduino pro mini, часовой модуль ds3231, релейный модуль, 2 датчика 18b20, модули приемника и передатчика 433мГц, lcd 16x2 i2c, 7сегментный индикатор, блоки питания 12в и 5в, ну и еще мелочевка: max7219, кнопки, светодиоды... всего сразу не вспомню, прошло 2 года, а все схемы в голове ;) Если кого заинтересует вспомню подробней.

Устройство отработало 2 года, я уже начал забывать какая кнопка за что отвечает :) а если устройство включил и забыл, мне кажется, оно работает неплохо. Есть конечно же и мелкие косяки, недочеты. Их легко исправить при сборке нового устройства, свое править мне пока лень.... но вдруг )

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

sirik
Offline
Зарегистрирован: 10.11.2012

Добрый день

Так как пишу что-то подобное, есть пару вопросов:

1. Как Вы организовали резервное питание устройств (если оно есть вообще);

2. Как реализовали временные интервалы? Например день, ночь, лето, зима и т.д.

3. Почему не использовали  Nrf24l01+? Вроде оно лучше, чем 433МГц.

 

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

 

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

1. Выкиньте ваш датчик на улицу, желательно на северную сторону.

2. Регулируйте температуру подачи в зависимости от наружной  как на этом графике
Используя map() , понятно что в меню надо делать регулировку точек
http://www.heizungsforum.de/forum/index.php/Attachment/2502-Unbenannt1-PNG/
Полная документация http://www.gazeskatli.lv/documents/Junkers_TA211E_Rus.pdf

3. А все остальные таймеры-день-ночь это только дополнения к правильному регулированию

А называется всё это погодозависимый регулятор

 

sirik
Offline
Зарегистрирован: 10.11.2012

Спасибо.

Но я немного про другое спрашивал) Зависимости от темп дома и улицы, сделаю в последнюю очередь, сейчас вопрос про интервалы.

Потому что у меня их будет порядка 4 в день.

Stas046
Offline
Зарегистрирован: 10.12.2014

И Вам доброго дня.

1. Резервного питания нет. Если вы имеете ввиду только сам термостат, какой смысл ? котел-то обесточен... А резервное питание котла - это уже другая история...

2. Интервалы день - ночь. Например: днем желаемая т.25-поддерживаем, бумс 23:00, ночь желаемая т.23 -держим, 6:00 день - т.25 греем-держим ну и тд. Приятно встать в 7 утра, а дома тепло )

3. Во-первых: для меня это был 2й на что-то похожий проект и про Nrf24l01+ я слышал только краем уха, да и сейчас еще толком с ними не разобрался :) Во-вторых: дом у меня небольшой, дальности и этих хватает.Да и передавать-то там особо нечего, раз в минуту температуру отправить. Ну и в-третьих: у меня на крыше дома стоят несколько wifi антенн+дома роутер+соседские роутеры, какофония в диапазоне wifi жесть. Не хотелось туда особо лезть.

Про ПИД много читал-думал, много заморочек там... ну его, не стоит ) 

По разнице температур.... оно наверное правильней, но там тоже есть подводные камни

Сегодня приеду домой, выложу скетчи

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

sirik пишет:

.....Зависимости от темп дома и улицы, сделаю в последнюю очередь, сейчас вопрос про интервалы.

Потому что у меня их будет порядка 4 в день.

Повторюсь- температура в доме не измеряется. Она делается вами от наружной.

Тогда и интервалы не очень нужны.

Stas046 пишет:

Про ПИД много читал-думал, много заморочек там... ну его, не стоит ) 

По разнице температур.... оно наверное правильней, но там тоже есть подводные камни

ПИД, конечно, нет смысла делать, не та точность регулирования .
И средней температуры подачи вполне хватает.

И никакой разницы температур! Только уличная и график зависимости.

sirik
Offline
Зарегистрирован: 10.11.2012

Я бы не сказал, что надо плясать только от улицы. Вот сейчас у нас температура скачет, причем так как я живу один, то днем вообще не топлю.

Про интервалы понял. Тогда надо иметь процедуру, которая будет возвращать текущую температуру текущего интервала.

 

Stas046
Offline
Зарегистрирован: 10.12.2014

Вот код головного устройства:



/ версия 1.23 30.12.2013

#include <OneWire.h> //подключаем шину 1-ware
#include <Wire.h>
#include <DS3231.h> //подключаем библиотеку RTC3231
#include <LiquidCrystal_I2C.h> //экран
#include <avr/wdt.h> //watchdog
#include <Bounce.h> //библиотека дребезга кнопок
#include <EEPROM.h> //включаем EEPROM
#include <RCSwitch.h>//библиотека для передатчика/приемника




#define led1 11 //доп.светодиод
#define led2 9 //зел. остывание
#define led3 10 //красн. нагрев
#define relay 12 //релюшка
#

#define zummer 4 //зуммер

#define swich1 6 //кнопки вниз
#define swich2 5 //вверх

#define swich4 7 //enter

int TSensorPin = 8; // ds18b20 местный на ноге 8
OneWire ds(TSensorPin);// создаем объект температурного датчика
RCSwitch mySwitch = RCSwitch(); // объект приемник/передатчик

// настройка часов RTC
DS3231 Clock;
bool h12 = false; //True is 12-h, false is 24-hour.;
bool PM;
bool Century = false;

LiquidCrystal_I2C lcd(0x27, 16, 2); //Задаем размерность дисплея.

byte ledlight = 1; //яркость светодиодов EEPROM 55
byte ledlightset = 0;
byte controlE4 = 1; //контроль перезагрузок EEPROM 54
int flagmenu = 0; //флаг выбора меню
int setwait = 300; //время возврата в главное меню
int wait = setwait;
int ledwite = 0;//время для мигания светодиодов работы котла
byte light = 1; //подсветка экрана
boolean warningOn = false; // задержка проверки аварии т сенсора
boolean termoblock = true; // блокировка кипятильника при аварии
float termo1 = 99.9; //температура местная
float termo2 = 99.9; //температура дистанционная
float termoS = 88; //температура внутри устройства

byte flagtermo = 0; //флаг датчика температуры: 0 - местный, 1 - дистанционный
float termoset = 25; // желаемая температура днем, байты 23 и 24
float ntermoset = 23; // желаемая ночная температура, байты 21 и 22
boolean flagnight = false; // флаг ночи
byte nightstart = 21; //начало ночи
byte nightend = 5; //конец ночи
int timer = 0; // timer2 = 0, timer3 = 0; // переменная для проверки отсутствия дист. датчика, мигалки светодиодов
int timer433 = 0;
int settimer = 3000;

boolean flagkotel = false; //флаг котел включен или нет
boolean flagrelay = false; //флаг релюшки
float termokey = termo1; //температура для проверки релюшкой

float tGist = 0.7;//гистерезис EEPROM 26
float gistset = 0.0;//переменная для настройки гистерезис
int gst = 0;//установка гистерезиса в EEPROM байт 26

boolean sw1 = false;
boolean sw2 = false;

boolean sw4 = false;

int x = 0;

void setup()
{
  Wire.begin();
  //Serial.begin(9600);
  lcd.init();                       // Инициализация lcd
  lcd.backlight();   // Включаем подсветку
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("BAXI'k TERMO");       // Выводим текст
  lcd.setCursor(0, 1);              // Устанавливаем курсор в начало 2 строки
  lcd.print("V 1.23 Loading...");     // Выводим текст
  controlE4 = EEPROM.read(54); //контроль перезагрузок EEPROM 54
  mySwitch.enableReceive(0);  //  приемник на пине 2
  //пишем в память при первой компиляции ??
  //EEPROM.write(51, 0); //пишем в EEPROM
  //EEPROM.write(52, 0); //пишем в EEPROM
  //EEPROM.write(53, 0); //пишем в EEPROM
  //EEPROM.write(54, 0); //пишем в EEPROM
  //EEPROM.write(55, 0); //пишем в EEPROM
  //EEPROM.write(56, 0); //пишем в EEPROM
  //EEPROM.write(57, 0); //пишем в EEPROM
  //EEPROM.write(58, 0); //пишем в EEPROM
  //EEPROM.write(59, 0); //пишем в EEPROM
  //EEPROM.write(60, 0); //пишем в EEPROM
  // EEPROM.write(41, 0); //пишем в EEPROM
  // EEPROM.write(42, 0); //пишем в EEPROM
  //EEPROM.write(43, 0); //пишем в EEPROM
  // контроль перезагрузки
  if (controlE4 == 1)
  {
    EEPROM.write(44, 1); //пишем в EEPROM сработала WD
  }
  //EEPROM.write(45, 0); //пишем в EEPROM
  //EEPROM.write(46, 0); //пишем в EEPROM
  //EEPROM.write(47, 0); //пишем в EEPROM
  //EEPROM.write(48, 0); //пишем в EEPROM
  //EEPROM.write(49, 0); //пишем в EEPROM
  //EEPROM.write(50, 0); //пишем в EEPROM

  // начальные настройки часов
  //  Clock.setSecond(50);//Set the second
  // Clock.setMinute(59);//Set the minute
  // Clock.setHour(11); //Set the hour
  // Clock.setDoW(5); //Set the day of the week
  // Clock.setDate(31); //Set the date of the month
  // Clock.setMonth(5); //Set the month of the year
  // Clock.setYear(13); //Set the year (Last two digits of the year)

  // читаем EEPROM
  flagtermo = EEPROM.read(25); // выбор датчика
  // яркость светодиодов и контроль наприжения
  ledlightset = EEPROM.read(55); //яркость светодиодов EEPROM 55



  // желаемая температура днем
  //читаем EEPROM и собираем
  byte hi = EEPROM.read(23);
  byte low = EEPROM.read(24);
  float set = word(hi, low); //собираем число
  termoset = (set / 10); //получаем запятую )

  // желаемая температура ночью
  //читаем EEPROM и собираем
  byte hin = EEPROM.read(21);
  byte lown = EEPROM.read(22);
  float setn = word(hin, lown); //собираем число
  ntermoset = (setn / 10); //получаем запятую )

  // ночной режим
  nightstart = EEPROM.read(19); //читаем в EEPROM
  nightend = EEPROM.read(20); //читаем в EEPROM


  gst = EEPROM.read(26); // гистерезис из памяти
  gistset = float (gst);
  tGist = gistset / 10; // гистерезис

  // яркость светодиодов
  if (ledlightset == 0)
  {
    ledlight = 2;
  }
  if (ledlightset == 1)
  {
    ledlight = 100;
  }
  if (ledlightset == 2)
  {
    ledlight = 254;
  }
  //  Первоначальные установки выходов

  pinMode (swich1, INPUT);
  pinMode (swich2, INPUT);
  // pinMode (swich3, INPUT);
  pinMode (swich4, INPUT);
  // pinMode (A0, INPUT);
  pinMode (led1, OUTPUT);
  pinMode (led2, OUTPUT);
  pinMode (led3, OUTPUT);
  pinMode (relay, OUTPUT);


  pinMode(zummer, OUTPUT); //зуммер

  analogWrite (led1, 0);
  analogWrite (led2, 0);
  analogWrite (led3, 0);
  digitalWrite (relay, LOW);



  delay(2000);
  timer = settimer;
  wdt_enable (WDTO_8S); //запуск watchdog
  lcd.clear();




}

void loop() //основной цикл
{

  //мигаем светодиодами
  if (ledwite > 100) //мигалка работы котла
  {

    if (flagkotel == false)
    {
      analogWrite (led2, ledlight);
      delay(200);
      analogWrite (led2, 0);
    }
    else
    {
      analogWrite (led3, ledlight);
      delay(200);
      analogWrite (led3, 0);
    }
  }





  //Serial.println(termokey);
  keycont1(); //проверяем кнопки в главном меню

  errors(); //смотрим нет ли ошибок
  if (wait == (setwait / 2))// иногда измеряем внутреннюю температуру
  {
    termoS = Clock.getTemperature(); // температура внутри устройства
    termo1 = getTemp(); // температура внутренний
    termoread();
  }




  if (flagmenu == 0)
  {
    menu0();
    termoread(); // температуру
    relaycontroL(); //смотрим, не пора ли включить котел )
  }
  if (flagmenu == 1)
  {
    menu1();
  }
  if (flagmenu == 2)
  {
    menu2();
  }
  if (flagmenu == 3)
  {
    menu3();
  }
  if (flagmenu == 4)
  {
    menu4();
  }
  if (flagmenu == 5)
  {
    menu5();
  }
  if (flagmenu == 6)
  {
    menu6();
  }
  if (flagmenu == 7)
  {
    menu7();
  }
  if (flagmenu == 8)
  {
    menu8();
  }
  timeout();//если ничего не нажато- то возврат в главное меню


}

//вырубаем подсветку если включена в главном меню
void LightBack()
{
  if (light == 0)
  {
    lcd.noBacklight(); // выключаем подсветку
    //lcd.clear();
  }
  else
  {
    lcd.backlight();   // Включаем подсветку
  }
}

void menu0() //выводим меню0 - часы и температура Главное меню  *****************
{
  int second, minute, hour;



  hour = Clock.getHour(h12, PM);
  minute = Clock.getMinute();
  second = Clock.getSecond();



  lcd.setCursor(0, 0); //часы
  if (hour < 10) lcd.print('0');
  lcd.print(hour, DEC);
  lcd.print(':');
  if (minute < 10) lcd.print('0');
  lcd.print(minute, DEC);
  lcd.print(':');
  if (second < 10) lcd.print('0');
  lcd.print(second, DEC);
  lcd.print(' ');

  if (termo2 == 99.9) //ошибка датчика внешнего
  {
    lcd.print("E:----");
  }
  else
  {
    lcd.print("E:");
    lcd.print(termo2, 1);
  }

  lcd.setCursor(9, 1);
  //lcd.print("I:");
  if (termo1 == 99.9)
  {
    lcd.print("I:----");//ошибка датчика внутреннего
  }
  else
  {
    lcd.print("I:");
    lcd.print(termo1, 1);
  }


  lcd.setCursor(0, 1);
  lcd.print("R:");

  if (flagtermo == 0 && EEPROM.read(53) == 2)
  {
    lcd.setCursor(15, 1);
    lcd.print("*");
    lcd.setCursor(15, 0);
    lcd.print(" ");
  }
  if (flagtermo == 1 && EEPROM.read(53) == 2)
  {
    lcd.setCursor(15, 0);
    lcd.print("*");
    lcd.setCursor(15, 1);
    lcd.print(" ");
  }

  if (flagnight == false)
  {
    lcd.setCursor(2, 1); //включен режим день
    lcd.print("D");
    lcd.print(" ");
    lcd.print(termoset, 1);
    //lcd.print(demo, 1);
  }
  else
  {
    lcd.setCursor(2, 1); //включен режим ночь
    lcd.print("N");
    lcd.print(" ");
    lcd.print(ntermoset, 1);

  }


}

void menu1() //выводим меню1 установка желаемой температуры днем ***************
{

  lcd.setCursor(2, 0);
  lcd.print("Day termo Set");
  lcd.setCursor(6, 1);
  lcd.print(termoset, 1);

}

void menu4() //выводим меню2 выбор датчика ********************
{
  flagtermo = EEPROM.read(25); // выбор датчика
  lcd.setCursor(0, 0);
  lcd.print("Sensor:");
  lcd.setCursor(7, 0);

  if (flagtermo == 0)
  {
    lcd.print("Internal"); //внутренний
    lcd.setCursor(9, 1);
    lcd.print(termo1, 1);


  }
  if (flagtermo == 1)
  {
    lcd.print("External"); //внешний
    lcd.setCursor(9, 1);
    lcd.print(termo2, 1);

  }
}

void menu3() //выводим меню3 гистерезис  **********************
{
  lcd.setCursor(0, 0);
  lcd.print("Hysteresis:");
  lcd.setCursor(12, 0);
  lcd.print(tGist, 1);
  lcd.setCursor(6, 1);
  lcd.print("Set");
  gistset = tGist;

}

void menu2() //выводим меню4 установка температура режима ночь  **********************
{
  lcd.setCursor(1, 0);
  lcd.print("Night termo Set");
  lcd.setCursor(6, 1);
  lcd.print(ntermoset, 1);


}
void menu5() //начало и завершение режима ночь  **********************
{
  lcd.setCursor(3, 0);
  lcd.print("Night Time");
  lcd.setCursor(12, 0);

  lcd.setCursor(7, 1);
  lcd.print("Set");


}

void menu6() //выводим меню6 настройка часов  **********************
{
  int second, minute, hour;

  hour = Clock.getHour(h12, PM);
  minute = Clock.getMinute();
  second = Clock.getSecond();

  lcd.setCursor(4, 0);
  lcd.print("Time set");
  lcd.setCursor(4, 1); //часы
  if (hour < 10) lcd.print('0');
  lcd.print(hour, DEC);
  lcd.print(':');
  if (minute < 10) lcd.print('0');
  lcd.print(minute, DEC);
  lcd.print(':');
  if (second < 10) lcd.print('0');
  lcd.print(second, DEC);
  lcd.print(' ');
}
void menu7() // ***************************INFO******************************* ошибки
{
  byte ea, eb, ec, ed, ee;
  byte x;

  ea = EEPROM.read(41);
  eb = EEPROM.read(42);
  ec = EEPROM.read(43);
  ed = EEPROM.read(44);
  ee = EEPROM.read(45);

  lcd.setCursor(0, 0);
  lcd.print("Errors:"); // выводим коды ошибок

  if (ea != 0) // пропал дистанционный датчик
  {
    lcd.setCursor(0, 1);
    lcd.print("E01");


  }
  if (eb != 0) // авария датчика температуры
  {
    lcd.setCursor(3, 1);
    lcd.print("E02");


  }
  if (ec != 0) //
  {
    lcd.setCursor(6, 1);
    lcd.print("E03");


  }
  if (ed != 0) //срабатывала перезагрузка
  {
    lcd.setCursor(9, 1);
    lcd.print("E04");


  }
  if (ee != 0) //
  {
    lcd.setCursor(12, 1);
    lcd.print("E05");


  }


}

void menu8() //******************************SERVIS MENU **********************
{

  lcd.setCursor(02, 0);
  lcd.print("Service Menu");

}

void termoread() //обрабатываем температуру  *************************
{

  receiver(); // ждем температуру с дистанционника


  if (flagtermo == 0)
  {
    termokey = termo1;
  }
  if (flagtermo == 1)
  {
    termokey = termo2;
  }
  if (termo2 == 99.9) //отсутствует дистанционный датчик переходим на внутренний
  {

    termokey = termo1;
  }


  if (termokey < 10 && termokey != 99.9) //при глюках включаем тревогу
  {
    if (termoblock == false)
    {
      warning ();

    }
  }
  if (termokey > 40 && termokey != 99.9) //при глюках включаем тревогу
  {
    if (termoblock == false)
    {
      warning ();

    }
  }
  if (termo1 == 99.9 && termo2 == 99.9) //отсутствуют оба датчика
  {
    if (termoblock == false)
    {
      warning ();
    }
  }



}

//Функции чтения с внутреннего датчика температуры****************
float getTemp()
{
  byte data[12];
  byte addr[8];
  if ( !ds.search(addr))
  {

    ds.reset_search();
    return 99.9;
  }

  if ( OneWire::crc8( addr, 7) != addr[7])
  {

    return 99.9;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28)
  {


    return 99.9;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44, 1);
  // delay(800);
  byte present = ds.reset();
  ds.select(addr);
  ds.write(0xBE);


  for (int i = 0; i < 9; i++)
  {
    data[i] = ds.read();
  }

  ds.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float TRead = ((MSB << 8) | LSB);
  float Temperature = TRead / 16;

  return Temperature;
}

// подпрограмма зуммера*********************************************************************
void beep( int delt ) // подпрограмма зуммера
{
  tone(zummer, 2093);
  delay(delt);
  noTone(zummer);
  delay(delt);
}

// не пора ли включать котел *********************************************************
void relaycontroL()
{
  int x = 1;
  float term;
  byte z;
  z = EEPROM.read(53);

  nightcontrol(); // смотрим день у нас или ночь

  if (flagnight == false)
  {
    term = termoset;
  }
  if (flagnight == true)
  {
    term = ntermoset;
  }

  float minus = term - tGist;
  float plus = term + tGist;




  if (termokey < minus)
  {
    flagrelay = true;
  }

  if (termokey > plus)
  {
    flagrelay = false;
  }

  if (z == 0)
  {
    flagrelay = false;
  }

  if (z == 1)
  {
    flagrelay = true;
    termoblock = false;
  }


  if (flagrelay == true && termoblock == false) //если котел включен и блокировка снята, то включаем
  {
    digitalWrite (relay, LOW); // включаем котел

    flagkotel = true;
  }
  else
  {
    digitalWrite (relay, HIGH); //выключаем котел

    flagkotel = false;
  }


}

void timeout() //если ничего не нажато******************************************
{
  if (wait < 0 && flagmenu != 0)
  {
    flagmenu = 0;
    lcd.clear();
    beep(50);
    wait = setwait;

  }
  if (wait < 0 && flagmenu == 0)
  {
    wait = setwait;
    termoblock = false; // отключение тревоги
  }
  wait = wait - 1;

  if (ledwite > 100) //таймер для светодиодов
  {
    ledwite = 0;
  }
  ledwite = ledwite + 1;

  if (timer < 0 && light == 1)
  {
    light = 0;
    LightBack();
  }

  if (timer < 0)
  {
    timer433 = timer433 + 1;
    timer = settimer;
  }
  timer = timer - 1;

}

void warning () // авария датчика температуры ******************************************
{
  byte z;
  z = EEPROM.read(42);


  lcd.clear();
  lcd.setCursor(3, 0);
  lcd.print("WARNING !!!");
  lcd.setCursor(0, 1);
  lcd.print("t Sensor Failed!");
  if (z == 0) //если ошибки не было то пишем её
  {
    EEPROM.write(42, 1);
  }

  beep(50);
  beep(50);
  beep(50);
  delay(100);
  beep(150);
  beep(150);
  beep(150);
  beep(50);
  beep(50);
  beep(50);
  delay(500);
  lcd.clear();


  termoblock = true;

}


void keycont1() //проверяем кнопки в главном меню *****************************************
{
  debounce(); //читаем кнопки

  if (sw2 == true) //нажатие кнопки1
  {
    if (light == 1)
    {
      wait = setwait;
      flagmenu = flagmenu + 1; //листаем менюшки вверх
      timer = settimer;
      if (flagmenu > 8)
      {
        flagmenu = 0;
      }
      lcd.clear();
    }
    if (light == 0) //если подсветка была выключен то....
    {

      light = 1;
      LightBack();
      timer = settimer;
    }
    delay (100);
  }

  if (sw1 == true) //нажатие кнопки3
  {
    if (light == 1)
    {
      wait = setwait;
      timer = settimer;
      flagmenu = flagmenu - 1; //листаем менюшки вниз

      if (flagmenu < 0)
      {
        flagmenu = 8;
      }
      lcd.clear();
    }

    if (light == 0)
      //если подсветка была выключен то....
    {

      light = 1;
      LightBack();
      timer = settimer;
    }
    delay (100);
  }



  if (sw4 == true && flagmenu == 0) //нажатие кнопки2 вкл\выкл подсветка
  {
    if (light == 1)
    {

      light = 0;
      LightBack();

    }
    else
    {

      light = 1;
      LightBack();
      timer = settimer;
    }
    delay(100);
  }



  // смотрим на кнопку enter sw4
  if (sw4 == true && flagmenu == 4) //выбор сенсора
  {
    wait = setwait;
    if (flagtermo == 0)
    {
      flagtermo = 1;
      EEPROM.write(25, flagtermo); //пишем в EEPROM
    }
    else
    {
      flagtermo = 0;
      EEPROM.write(25, flagtermo); //пишем в EEPROM
    }
    delay (200);
  }
  if (sw4 == true && flagmenu == 3) // гистерезис
  {
    wait = setwait;
    hysteresis();
  }
  if (sw4 == true && flagmenu == 1) // дневная температура установка
  {
    wait = setwait;
    settermoon();
  }
  if (sw4 == true && flagmenu == 5) // ночное время
  {
    wait = setwait;
    nighttime();
  }
  if (sw4 == true && flagmenu == 2) // установка ночной температуры
  {
    wait = setwait;
    nighttermoset();
  }
  if (sw4 == true && flagmenu == 6) // установка часов
  {
    wait = setwait;
    settime();
  }
  if (sw4 == true && flagmenu == 8) // сервисное меню
  {
    wait = setwait;
    servismenu();
  }
  if (sw4 == true && flagmenu == 7) // сброс ошибок
  {
    wait = setwait;
    errorClear();
  }

}
//**********************************СБРОС ОШИБОК*****************************************
void errorClear()
{
  EEPROM.write(41, 0); //пишем в EEPROM
  EEPROM.write(42, 0); //пишем в EEPROM
  EEPROM.write(43, 0); //пишем в EEPROM
  EEPROM.write(44, 0); //пишем в EEPROM
  EEPROM.write(45, 0); //пишем в EEPROM
  EEPROM.write(46, 0); //пишем в EEPROM
  EEPROM.write(47, 0); //пишем в EEPROM
  EEPROM.write(48, 0); //пишем в EEPROM
  EEPROM.write(49, 0); //пишем в EEPROM
  EEPROM.write(50, 0); //пишем в EEPROM

  lcd.clear();

  lcd.setCursor(4, 0);
  lcd.print("Cleared");
  delay (500);
  beep(50);
  beep(50);
  delay (500);
  lcd.clear();

}
//меню установка гистерезиса ****************************************************
void hysteresis()
{
  lcd.clear();
  delay(200);
  lcd.setCursor(0, 0);
  lcd.print("Hysteresis:");
  lcd.setCursor(0, 1);
  lcd.print("On:");
  lcd.print((termoset - tGist), 1);
  lcd.setCursor(8, 1);
  lcd.print("Off:");
  lcd.print((termoset + tGist), 1);
  lcd.setCursor(12, 0);
  lcd.print(tGist, 1);
  lcd.blink();
  gistset = tGist;
  delay(500);
  while (1)
  {
    debounce(); //читаем кнопки
    if (sw2 == true)//кнопка вверх
    {
      gistset = gistset + 0.1;
      if (gistset > 3)
      {
        gistset = 0;
      }
      delay (200);
      lcd.setCursor(3, 1);
      lcd.print((termoset - gistset), 1);
      lcd.setCursor(12, 1);
      lcd.print((termoset + gistset), 1);
      lcd.setCursor(12, 0);
      lcd.print(gistset, 1);

    }
    if (sw1 == true)//кнопка вниз
    {
      gistset = gistset - 0.1;
      if (gistset < 0)
      {
        gistset = 3;
      }
      delay (200);
      lcd.setCursor(3, 1);
      lcd.print((termoset - gistset), 1);
      lcd.setCursor(12, 1);
      lcd.print((termoset + gistset), 1);
      lcd.setCursor(12, 0);
      lcd.print(gistset, 1);

    }
    if (sw4 == true)//кнопка ENTER :)
    {
      delay(200);
      lcd.noBlink();
      break;
    }
  }
  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("SETTING");
  lcd.setCursor(6, 1);
  lcd.print(gistset, 1);
  tGist = gistset;
  gistset = gistset * 10;
  gst = int(gistset);
  EEPROM.write(26, gst); //пишем в EEPROM
  delay (500);
  beep(50);
  beep(50);
  delay (500);
  lcd.clear();
}

// Устанавливаем желаемую температуру днем ***************************************
void settermoon()
{
  float set = termoset;
  lcd.clear();
  delay(200);
  lcd.setCursor(0, 0);
  lcd.print("Day termo:");
  lcd.setCursor(0, 1);
  lcd.print("On:");
  lcd.print((set - tGist), 1);
  lcd.setCursor(8, 1);
  lcd.print("Off:");
  lcd.print((set + tGist), 1);
  lcd.setCursor(10, 0);
  lcd.print(set, 1);
  // lcd.setCursor(9, 1);
  lcd.blink();

  delay(500);

  while (1)
  {
    debounce(); //читаем кнопки

    if (sw2 == true)//кнопка вверх
    {
      set = set + 0.1;
      if (set > 35)
      {
        set = 15;
      }
      lcd.setCursor(3, 1);
      lcd.print((set - tGist), 1);
      lcd.setCursor(12, 1);
      lcd.print((set + tGist), 1);
      lcd.setCursor(10, 0);
      lcd.print(set, 1);
      delay(200);
    }
    if (sw1 == true)//кнопка вниз
    {
      set = set - 0.1;
      if (set < 15)
      {
        set = 35;
      }
      lcd.setCursor(3, 1);
      lcd.print((set - tGist), 1);
      lcd.setCursor(12, 1);
      lcd.print((set + tGist), 1);
      lcd.setCursor(10, 0);
      lcd.print(set, 1);
      delay(200);
    }
    if (sw4 == true)//кнопка ENTER :)
    {
      delay(200);
      lcd.noBlink();
      break;
    }
  }
  termoset = set;
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("SETTING");
  lcd.setCursor(7, 1);
  lcd.print(termoset, 1);

  //разбираем и пишем в EEPROM
  int eepromset = int(set * 10);//избавляемся от запятых

  byte hi = highByte(eepromset); //разбивка числа на 2 байта
  byte low = lowByte(eepromset);
  EEPROM.write(23, hi);
  EEPROM.write(24, low);
  delay (500);
  beep(50);
  beep(50);
  delay (500);
  lcd.clear();
}
//установка часов *************************************
void settime()
{
  int second, minute, hour;
  int sethour, setminute;


  hour = Clock.getHour(h12, PM);
  minute = Clock.getMinute();
  second = Clock.getSecond();

  sethour = hour;
  setminute = minute;
  second = 0;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Hour:");
  lcd.print(sethour);
  lcd.print(" ");
  lcd.setCursor(0, 1);
  lcd.print("Minute:");
  lcd.print(setminute);
  lcd.print(" ");
  delay(300);
  lcd.setCursor(7, 0);
  lcd.blink();

  while (1) //устанавливаем часы
  {
    debounce(); //читаем кнопки

    if (sw2 == true)//кнопка вверх
    {
      sethour = sethour + 1;
      if (sethour > 23)
      {
        sethour = 0;
      }
      delay (200);
      lcd.setCursor(5, 0);
      lcd.print(sethour);
      lcd.print(" ");
    }
    if (sw1 == true)//кнопка вниз
    {
      sethour = sethour - 1;
      if (sethour < 0)
      {
        sethour = 23;
      }
      delay (200);
      lcd.setCursor(5, 0);
      lcd.print(sethour);
      lcd.print(" ");
    }
    if (sw4 == true)
    {
      lcd.setCursor(9, 1);
      hour = sethour;
      delay(200);
      break;
    }
  }
  while (2) //устанавливаем минуты
  {
    debounce(); //читаем кнопки

    if (sw2 == true)//кнопка вверх
    {
      setminute = setminute + 1;
      if (setminute > 59)
      {
        setminute = 0;
      }
      delay (200);
      lcd.setCursor(7, 1);
      lcd.print(setminute);
      lcd.print(" ");
    }
    if (sw1 == true)//кнопка вниз
    {
      setminute = setminute - 1;
      if (setminute < 0)
      {
        setminute = 59;
      }
      delay (200);
      lcd.setCursor(7, 1);
      lcd.print(setminute);
      lcd.print(" ");
    }
    if (sw4 == true)
    {
      minute = setminute;
      delay(200);
      break;
    }
  }

  // сохраняем установки времени
  Clock.setSecond(second);  //Set the second
  Clock.setMinute(minute);  //Set the minute
  Clock.setHour(hour); //Set the hour

  lcd.clear();
  lcd.noBlink();
  lcd.setCursor(7, 0);
  lcd.print("Time");

  lcd.setCursor(5, 1);
  lcd.print("SETTING");
  delay (500);
  beep(50);
  beep(50);
  delay (500);
  lcd.clear();

}
// устанавливаем ночную температуру ********************************************
void nighttermoset()
{
  float set = ntermoset;
  lcd.clear();
  delay(200);
  lcd.setCursor(0, 0);
  lcd.print("N. termo:");
  lcd.setCursor(0, 1);
  lcd.print("On:");
  lcd.print((set - tGist), 1);
  lcd.setCursor(8, 1);
  lcd.print("Off:");
  lcd.print((set + tGist), 1);
  lcd.setCursor(9, 0);
  lcd.print(set, 1);
  // lcd.setCursor(9, 1);
  lcd.blink();

  delay(500);

  while (1)
  {
    debounce(); //читаем кнопки

    if (sw2 == true)//кнопка вверх
    {
      set = set + 0.1;
      if (set > 35)
      {
        set = 15;
      }
      lcd.setCursor(3, 1);
      lcd.print((set - tGist), 1);
      lcd.setCursor(12, 1);
      lcd.print((set + tGist), 1);
      lcd.setCursor(9, 0);
      lcd.print(set, 1);
      delay(200);
    }
    if (sw1 == true)//кнопка вниз
    {
      set = set - 0.1;
      if (set < 15)
      {
        set = 35;
      }
      lcd.setCursor(3, 1);
      lcd.print((set - tGist), 1);
      lcd.setCursor(12, 1);
      lcd.print((set + tGist), 1);
      lcd.setCursor(9, 0);
      lcd.print(set, 1);
      delay(200);
    }
    if (sw4 == true)//кнопка ENTER :)
    {
      delay(200);
      lcd.noBlink();
      break;
    }
  }
  ntermoset = set;
  lcd.clear();
  lcd.setCursor(5, 0);
  lcd.print("SETTING");
  lcd.setCursor(7, 1);
  lcd.print(ntermoset, 1);

  //разбираем и пишем в EEPROM
  int eepromset = int(set * 10);//избавляемся от запятых

  byte hi = highByte(eepromset); //разбивка числа на 2 байта
  byte low = lowByte(eepromset);
  EEPROM.write(21, hi);
  EEPROM.write(22, low);
  delay (500);
  beep(50);
  beep(50);
  delay (500);
  lcd.clear();
}

// устанавливаем продолжительность ночи
void nighttime()
{
  int startset = nightstart;
  int endset = nightend;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Start:");
  lcd.print(startset);
  //lcd.print(" ");
  lcd.setCursor(9, 0);
  lcd.print("End:");
  lcd.print(endset);

  delay(300);
  lcd.setCursor(8, 0);
  lcd.blink();

  while (1) //устанавливаем начало ночи
  {
    debounce(); //читаем кнопки

    if (sw2 == true)//кнопка вверх
    {
      startset = startset + 1;
      if (startset > 23)
      {
        startset = 0;
      }
      lcd.setCursor(6, 0);
      lcd.print(startset);
      lcd.print(" ");

      lcd.setCursor(8, 0);
      delay(200);
    }
    if (sw1 == true)//кнопка вниз
    {
      startset = startset - 1;
      if (startset < 0)
      {
        startset = 23;
      }
      lcd.setCursor(6, 0);
      lcd.print(startset);
      lcd.print(" ");

      delay(200);
    }
    if (sw4 == true)
    {
      lcd.setCursor(15, 0);

      delay(200);
      break;
    }
  }
  while (2) //устанавливаем завершение ночи
  {
    debounce(); //читаем кнопки

    if (sw2 == true)//кнопка вверх
    {
      endset = endset + 1;
      if (endset > 23)
      {
        endset = 0;
      }
      lcd.setCursor(13, 0);
      lcd.print(endset);
      lcd.print(" ");

      lcd.setCursor(15, 0);
      delay(200);
    }
    if (sw1 == true)//кнопка вниз
    {
      endset = endset - 1;
      if (endset < 0)
      {
        endset = 23;
      }
      lcd.setCursor(13, 0);
      lcd.print(endset);
      lcd.print(" ");

      lcd.setCursor(15, 0);
      delay(200);
    }
    if (sw4 == true)
    {
      lcd.noBlink();
      delay(200);
      break;
    }
  }
  nightstart = startset;
  nightend = endset;
  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("SETTING");
  lcd.setCursor(0, 1);
  lcd.print("Start:");
  lcd.print(nightstart);
  //lcd.print(" ");
  lcd.setCursor(9, 1);
  lcd.print("to:");
  lcd.setCursor(13, 1);
  lcd.print(nightend);

  EEPROM.write(19, nightstart); //пишем в EEPROM
  EEPROM.write(20, nightend); //пишем в EEPROM
  delay (500);
  beep(50);
  beep(50);
  delay (500);
  lcd.clear();
}

// Сервисное меню *************************************************************************************
void servismenu()
{
  int fa, fb, fc, fd, fe;

  fa = EEPROM.read(51); // время ожидания с дистанционника до ошибки
  fb = EEPROM.read(52); //звук приемника
  fc = EEPROM.read(53); //режим работы котла 0-вык, 1-вкл, 2-авт
  fd = EEPROM.read(54); //controlE4 контроль перезагрузок
  fe = EEPROM.read(55); // яркость светодиодов ledlight
  //byte setF;

  lcd.clear();
  lcd.setCursor(0, 0); //температура внутри устройства
  lcd.print("S:");

  lcd.setCursor(0, 1);
  lcd.print("1F");
  lcd.print(fa);

  lcd.setCursor(5, 1);
  lcd.print("2F");
  lcd.print(fb);

  lcd.setCursor(10, 1);
  lcd.print("3F");
  lcd.print(fc);

  lcd.setCursor(2, 0);
  lcd.print("4F");
  lcd.print(fd);

  lcd.setCursor(6, 0);
  lcd.print("5F");
  lcd.print(fe);

  lcd.setCursor(12, 0);
  lcd.print(termoS, 1);


  lcd.blink();
  lcd.setCursor(4, 1);


  while (1) //установки f1
  {
    debounce(); //читаем кнопки


    if (sw2 == true)//кнопка вверх
    {
      fa = fa + 1;

      if (fa > 60)
      {
        fa = 1;
      }

      lcd.setCursor(2, 1);
      lcd.print(fa);
      lcd.print(" ");
      lcd.setCursor(4, 1);
      delay(200);
    }

    if (sw1 == true)//кнопка вниз
    {
      fa = fa - 1;

      if (fa < 1)
      {
        fa = 60;
      }
      lcd.setCursor(2, 1);
      lcd.print(fa);
      lcd.print(" ");
      lcd.setCursor(4, 1);
      delay(200);
    }

    if (sw4 == true)
    {
      lcd.setCursor(8, 1);

      delay(200);
      break;
    }
  }
  while (2) //установки f2
  {
    debounce(); //читаем кнопки


    if (sw2 == true)//кнопка вверх
    {
      fb = fb + 1;
      if (fb > 1)
      {
        fb = 0;
      }
      lcd.setCursor(7, 1);
      lcd.print(fb);
      lcd.setCursor(8, 1);
      delay(200);
    }

    if (sw1 == true)//кнопка вниз
    {
      fb = fb - 1;
      if (fb < 0)
      {
        fb = 1;
      }
      lcd.setCursor(7, 1);
      lcd.print(fb);
      lcd.setCursor(8, 1);
      delay(200);
    }

    if (sw4 == true)
    {
      lcd.setCursor(13, 1);

      delay(200);
      break;
    }
  }
  while (3) //установки f3
  {
    debounce(); //читаем кнопки


    if (sw2 == true)//кнопка вверх
    {
      fc = fc + 1;

      if (fc > 2)
      {
        fc = 0;
      }
      lcd.setCursor(12, 1);
      lcd.print(fc);
      lcd.setCursor(13, 1);
      delay(200);
    }

    if (sw1 == true)//кнопка вниз
    {
      fc = fc - 1;
      if (fc < 0)
      {
        fc = 2;
      }
      lcd.setCursor(12, 1);
      lcd.print(fc);
      lcd.setCursor(13, 1);
      delay(200);
    }

    if (sw4 == true)
    {
      lcd.setCursor(5, 0);
      //lcd.noBlink();
      delay(200);
      break;
    }
  }

  while (4) //установки f4
  {
    debounce(); //читаем кнопки


    if (sw2 == true)//кнопка вверх
    {
      fd = fd + 1;

      if (fd > 1)
      {
        fd = 0;
      }
      lcd.setCursor(4, 0);
      lcd.print(fd);
      lcd.setCursor(5, 0);
      delay(200);
    }

    if (sw1 == true)//кнопка вниз
    {
      fd = fd - 1;
      if (fd < 0)
      {
        fd = 1;
      }
      lcd.setCursor(4, 0);
      lcd.print(fd);
      lcd.setCursor(5, 0);
      delay(200);
    }

    if (sw4 == true)
    {
      lcd.setCursor(9, 0);
      //lcd.noBlink();
      delay(200);
      break;
    }
  }
  while (5) //установки f5
  {
    debounce(); //читаем кнопки


    if (sw2 == true)//кнопка вверх
    {
      fe = fe + 1;

      if (fe > 2)
      {
        fe = 0;
      }
      lcd.setCursor(8, 0);
      lcd.print(fe);
      lcd.setCursor(9, 0);
      delay(200);
    }

    if (sw1 == true)//кнопка вниз
    {
      fe = fe - 1;
      if (fe < 0)
      {
        fe = 2;
      }
      lcd.setCursor(8, 0);
      lcd.print(fe);
      lcd.setCursor(9, 0);
      delay(200);
    }

    if (sw4 == true)
    {

      lcd.noBlink();
      delay(200);
      break;
    }
  }


  lcd.clear();
  lcd.setCursor(4, 0);
  lcd.print("SETTING");

  EEPROM.write(51, fa); //пишем в EEPROM
  EEPROM.write(52, fb); //пишем в EEPROM
  EEPROM.write(53, fc); //пишем в EEPROM
  EEPROM.write(54, fd); //пишем в EEPROM
  EEPROM.write(55, fe); //пишем в EEPROM яркость светодиодов

  if (fe == 0)
  {
    ledlight = 2;
  }
  if (fe == 1)
  {
    ledlight = 100;
  }
  if (fe == 2)
  {
    ledlight = 254;
  }

  delay (500);
  beep(50);
  beep(50);
  delay (500);
  lcd.clear();



}

void receiver() // слушаем эфир 433 Мгц *******************************************************************
{
  int temp;
  byte recivewait;
  int x = 1; // индикация считывания температуры

  unsigned long value;


  float temp2;
  byte p1;
  p1 = EEPROM.read(52); //читаем в EEPROM  звук приема есть\нет
  recivewait = EEPROM.read(51);

  byte e1, e2;

  if (mySwitch.available()) // если что-то принято, начинаем разбор передачи
  {
    value = mySwitch.getReceivedValue();


    if (value > 100 && value < 400) // принята температура
    {
      temp = value;

      temp2 = float (temp);
      termo2 = temp2 / 10;
      timer433 = 0; // сбрасываем таймер


      for (x = 1; x < 4; x++)
      {
        analogWrite (led1, (ledlight / 2));
        delay(100);
        analogWrite (led1, 0);
        delay(100);
      }

      if (p1 == 1)
      {
        beep(50);
      }

      if (EEPROM.read(25) == 1) //если были на дистанцинном то на него и возврат
      {

        flagtermo = 1;
      }
    }

    mySwitch.resetAvailable();
  }

  if ( timer433 > recivewait) //отсутствие приема
  {

    termo2 = 99.9;
    timer433 = 0; // сбрасываем таймер

    flagtermo = 0; //переходим на внутренний датчик
    termokey = termo1;

    if (EEPROM.read(41) == 0) //если ошибка еще не записана, то пишем
    {
      EEPROM.write(41, 1);
    }
  }


}

void debounce() //убираем дребезг кнопок и опрашиваем кнопки ********************************
{

  Bounce bouncer1 = Bounce(swich1, 5);
  Bounce bouncer2 = Bounce(swich2, 5);

  Bounce bouncer4 = Bounce(swich4, 5);

  wdt_reset(); //сбрасываем watchdog

  if ( bouncer1.read() == HIGH) //нажатие кнопки1 вниз
  {
    sw1 = true;
    beep(50);
  }
  else
  {
    sw1 = false;
  }
  if ( bouncer2.read() == HIGH) //нажатие кнопки2 вверх
  {
    sw2 = true;
    beep(50);
  }
  else
  {
    sw2 = false;
  }

  if ( bouncer4.read() == HIGH) //нажатие кнопки4 enter
  {
    sw4 = true;
    beep(50);
  }
  else
  {
    sw4 = false;
  }
}
// проверяем день у нас или ночь*****************************************************
void nightcontrol()
{
  int hour;
  hour = Clock.getHour(h12, PM); //

  if (hour == nightstart)
  {
    flagnight = true;
  }


  if (hour == nightend)
  {
    flagnight = false;
  }

}
// *************************** обработка ошибoк ***************************************
void errors()
{
  byte ea, eb, ec, ed, ee;
  byte x;

  ea = EEPROM.read(41);
  eb = EEPROM.read(42);
  ec = EEPROM.read(43);
  ed = EEPROM.read(44);
  ee = EEPROM.read(45);

  x = (ea + eb + ec + ed + ee);

  if (x != 0)
  {
    analogWrite (led1, (ledlight / 2)); // если есть ошибки то горит светодиод led1
  }
  else
  {
    analogWrite (led1, 0);
  }
}

Посмотрел на него, спустя 2 года ...... это кошмар 0_0

 

Stas046
Offline
Зарегистрирован: 10.12.2014

Вот код дистанционного датчика





#include <OneWire.h> //подключаем шину 1-ware
#include <Wire.h>
#include <RCSwitch.h>
#include "LedControl.h"
//#include <avr/wdt.h>
//#include <EEPROM.h> //включаем EEPROM


LedControl lc=LedControl(12,11,10,1);
float f = 0; //число для вывода на дисплей
int f2; //вывод на диплей целого числа
int LedLight = 1; //яркость дисплея
int TSensorPin = 5;//датчик температуры на 5 выводе
int termo; //температура для передачи в эфир

OneWire ds(TSensorPin);// создаем объект температурного датчика
RCSwitch mySwitch = RCSwitch(); //передатчик

int transtime=30; //переменная времени отправки
unsigned long timer=0, prevtimer=0,prevtimer2=0, t1, t2; //таймеры прерываний

void setup() 
{
  mySwitch.enableTransmit(7); // пин,на который подключен передатчик
 // Serial.begin(9600);
 lc.shutdown(0,false);
 
  lc.setIntensity(0,1);
 
  lc.clearDisplay(0);
 //wdt_enable (WDTO_8S); //запуск watchdog

}

void loop() 
{
  float termoset;
timer=millis();

  if (timer-prevtimer > 5000) // иногда измеряем температуру
  {
   termoset = getTemp(); //получаем и преобразуем температуру для отправки
   f = termoset;
  
   prevtimer=timer;
   
   SetBright(); //определяем яркость дисплея
  }
  
  if (timer-prevtimer2 > transtime*1000) // иногда отправляем в эфир температуру 
  {
  
      sendRC(); 
      
    prevtimer2=timer;
  }
  
  
  output(); //вывод на дисплей температуры
 //wdt_reset(); //сбрасываем watchdog
}

// ***********************************MAX7219 ИНДИКАЦИЯ*****************
void output()
{
  float hundreds; //десятки
  float tens; //единицы
  float ones; //дусятые
  boolean floatPoint = false;
 int data1, data2, data3;
  
  //смотрим дробное у нас число или нет
  
  
  if (int(f * 10) != int(f) * 10)
  {
    floatPoint = true; // число дробное
  }
  else
  {
    floatPoint = false; // число не дробное
  }
  
  //потрошим число на сотни, десятки и единицы
  //выделяем десятки   
  hundreds=(int(f) / 10);
  data1 = int(hundreds);
  
//выделяем единицы                   
  tens=(int(f) % 10);
  data2=int(tens); 
//выделяем десятые           
  ones=((f-int(f))*10);
  data3 = int(ones);
 
 if (data1 == 0) data1=17; //если число < 10 то рисуем пустышку

 lc.setDigit(0,3,data1,false); 



  
  
  lc.setDigit(0,2,data2,true); //точка включена всегда
  lc.setDigit(0,1,data3,false);
  
 
  
  if (floatPoint == false)
  {
   lc.setDigit(0,1,0,false); //число не дробное рисуем 0
  }

  lc.setRow(0,0,B01100011); //знак градуса
}

///***********************Яркость дисплея*****************************
void SetBright()
{
  long int j;

  // Прикладываем обратное напржение - это зарядит собственную емкость вывода 2
  pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  digitalWrite(2, HIGH);
  digitalWrite(3, LOW);
  
  pinMode(2, INPUT);     // Переключаем 2й вывод на вход
  digitalWrite(2, LOW);  // и отключаем на нем подтягивающий резистор

  // Считаем сколько времени потребуется, чтобы емкость разрядилась до логич. 0
  for ( j = 0; j < 128000; j++) {
    if (digitalRead(2)==0) break;
  }
 
  
  if (j > 7000) //очень яркий свет
  {
    LedLight=1;
  }
  else
  {
    LedLight=7;
  }
  
  lc.setIntensity(0,LedLight);
}
//*****************************************************
//Функции чтения с датчика температуры
float getTemp()
{                                       
  byte data[12];
  byte addr[8];
  if ( !ds.search(addr)) {
    //no more sensors on chain, reset search
    ds.reset_search();
    return 99;  
  }

  if ( OneWire::crc8( addr, 7) != addr[7]) {

    return 99;
  }

  if ( addr[0] != 0x10 && addr[0] != 0x28) {
    
    
    return 99;
  }

  ds.reset();
  ds.select(addr);
  ds.write(0x44,1); 
  
  byte present = ds.reset();
  ds.select(addr); 
  ds.write(0xBE); 

  output();
  
  for (int i = 0; i < 9; i++) { 
    data[i] = ds.read();
    output();
  }

  ds.reset_search();

  byte MSB = data[1];
  byte LSB = data[0];

  float TRead = ((MSB<<8) | LSB); 
  float Temperature = TRead / 16;

  return Temperature;
}
// подпрограмма отправки данных 433mHz
void sendRC () // 433 
{
 float t, t2;
 int code;
  
  if (f > 1 && f < 40)
  {
    t2 = f;
    t = t2 * 10;
    code = int(t);
   
    mySwitch.send(code, 20);
    //и моргаем светодиодом
    pinMode(2, OUTPUT);
  pinMode(3, OUTPUT);
  digitalWrite(2, LOW);
  analogWrite(3, 1);
  delay(300);
  
  digitalWrite(2, LOW);
  digitalWrite(3, LOW);
    
    
  }
}

Не менее кошмарно. + Почемуто забыл активировать watchdog в "передатчике"...) Однако все работает нормально )

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

Stas046 добавь пожалуйста схемы подключений головного устройсва и выносного датка

Stas046
Offline
Зарегистрирован: 10.12.2014

Так как по "молодости" лепил все "из головы" целиком все не нарисовал, а зря :( . Хорошо хоть листочки набросков сохранил. Чтобы все восстановить займет 1-2 вечера. Перересую все на листок, а если терпения хватит то в sPlan`е.  Это сейчас дорос до sPlan, Sprint Layout, ЛУТа, тиньки всякие... а тогда еще учился )))) Опять на код смотрю....это пипец, сейчас-бы все переделал, но все работает без проблем.

lex2k
Offline
Зарегистрирован: 17.12.2015

не совсем понял как этот термостат на работу котла влияет....чем регулирует работу котла?

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

В навесных котлах а впрочем и в напольном варианте есть подключение комнатного датчика (это я говорю про новые модели котлов :)  а не про те где уголь или дрова закидуюся лопатой, руками, ведрами на выбор ) и через эти контакты и упровляет прибор температурой отопительного контура

Stas046
Offline
Зарегистрирован: 10.12.2014

В зависимости от температуры в помещении включает или выключает котел. В котле есть спецом для этого контакты: замкнуты-вкл., разомкнуты-выкл. У меня BAXI Main four 24.

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

Да стас а чтобы ты хотел переделать в своем проэкте ?

lex2k
Offline
Зарегистрирован: 17.12.2015

Stas046 пишет:

В зависимости от температуры в помещении включает или выключает котел. В котле есть спецом для этого контакты: замкнуты-вкл., разомкнуты-выкл. У меня BAXI Main four 24.

все ясно спасибо за пояснения 

у меня была идея по тому же принципу регулирования ручку на регуляторе серврприводом таскать...но выключить смогу а вот  главное включить уже не получиться...тока больше меньше и все(

Stas046
Offline
Зарегистрирован: 10.12.2014

umpelev69 пишет:

Да стас а чтобы ты хотел переделать в своем проэкте ?

Логика работы остается та-же, она меня полностью устраивает. Но вот сам код....  Он-то рабочий, но если мягко, не красивый )))) Нубства там много )))) Это по сути, вторая вещь на МК которую я сделал (после простенького контроллера для аквариума). 

Например:

pinMode (swich1, INPUT);

можно вообще не объявлять, ноги и так по умолчанию настроены на вход, delay много, подтягивающие резисторы у меня внешние-нафиг, внутренних за-глаза ну и тд. Это все от переизбытка памяти в 328 меге )))) По-нормальному там и 8ки должно хватить. Сейчас "заболел" тиньками-13, а там всего 1Кб памяти! Борьба идет за каждый байт, вот где начинаешь оптимально прогу писать.

 

 

Stas046
Offline
Зарегистрирован: 10.12.2014

Stas046 пишет:

umpelev69 пишет:

Да стас а чтобы ты хотел переделать в своем проэкте ?

Логика работы остается та-же, она меня полностью устраивает. Но вот сам код....  Он-то рабочий, но если мягко, не красивый )))) Нубства там много )))) Это по сути, вторая вещь на МК которую я сделал (после простенького контроллера для аквариума). 

Например:

pinMode (swich1, INPUT);

можно вообще не объявлять, ноги и так по умолчанию настроены на вход, delay много, подтягивающие резисторы у меня внешние-нафиг, внутренних за-глаза ну и тд. Это все от переизбытка памяти в 328 меге ))))  Сейчас "заболел" тиньками-13, а там всего 1Кб памяти! Борьба идет за каждый байт, вот где начинаешь оптимально прогу писать.

 

 

uragan
Offline
Зарегистрирован: 23.02.2015

umpelev69 пишет:

В навесных котлах а впрочем и в напольном варианте есть подключение комнатного датчика (это я говорю про новые модели котлов :)  а не про те где уголь или дрова закидуюся лопатой, руками, ведрами на выбор ) и через эти контакты и упровляет прибор температурой отопительного контура

Отстали от жизни. Сейчас это возможно и на котлах с дровами.

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

uragan пишет:

Отстали от жизни. Сейчас это возможно и на котлах с дровами.

:) :) :)

кода я еще работал по сервису котлов (лет 10 назад) то и горелки были на лузге от подсолничника

и автоматическая подача топлива в топку котла (уголь, угольная пыль) но это было в промышленных

масштабах

Stas046
Offline
Зарегистрирован: 10.12.2014

Головное устройство. На самом деле в одном устройстве трудится ProMini прошитая в uno, а в другом ужу голая atmega328 с объвязкой. Но сути это не меняет.

 

Stas046
Offline
Зарегистрирован: 10.12.2014

Дистанционный датчик. Также, ProMini ставшая UNO или 328я с объвязкой. Индикация на МАХ7219 (хотелось мне попробывать эту штучку), можно переделать на регистрах, можно и напрямую к меге, но это уже будет динамическая индикация. Там свои камни. Обратите внимание на конденсатор С5, его нужно припаять как можно ближе к ножкам микросхемы или прямо к ним. Несколько 7219 работали без него, а некоторые нет. Вообще, считается хорошим тоном на каждый корпус микросхемы ставить по одному конденсатору.

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

Stas046 спасибо огромное за схемы подключений вашых устройств да помоему и в первом можно было поставить просто ATmeua328 попробую переделать ваши исходники в баском авр порезультатам отпишусь :-))

Дмитрий

MaKo
Offline
Зарегистрирован: 25.10.2017

Спасибо за проект, собрал, работает. Но вот с радиомодулями как-то не задалось, постоянные глюки. Кто-нибудь может переделать скетчи на nRF24L01?