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

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

Собственно, готовый проект - плод моих ночных бдений в свободное от работы и семьи время.

Ничего особенного, но проекта с нужным функционалом мне не встретилось, посему сотворил свой.

Что может: включать-выключать горелку газового котла (электрообогреватель тоже можно), поддерживая температуру воздуха в помещении (разрешение - 0.1 градус); три таймера в течение суток (по срабатыванию каждого температура термостатирования меняется на заданную); предупреждающе попискивать при снижении температуры воздуха ниже заданной; показывать всё это безобразие на LCD.

В меню настроек: температура термостатирования, гистерезис, коррекция показаний датчика температуры, таймеры1-2-3 с установкой температуры, установка часов (RTC), установка температуры для предупреждения о снижении. После 10 секунд бездействия в любом пункте меню - выход без сохранения. ВСЕ настройки записываются в EEPROM и считываются оттуда после выключения-включения питания.

Состав: мини про 328, LCD16*2,  энкодер с кнопкой, часы на модуле с DS1307, градусник DS18B20, пьезо-пищалка, управление нагрузкой - с помощью такого релейного модуля:

,

питание - от адаптера питания с USB выходом. Код особенно не причёсывал, занимает в ардуине около 20 килобайт, откомментирован он изрядно. Работа проверена в реальных боевых условиях (котёл Baxi Mainfour 240F), работой я удовлетворён.

Конструктивная критика принимается. Код можете использовать на свой стах и риск, для медицинских применений прибор не подходит. :-)

/*
 
 */

#include <Wire.h> // i2c (для RTC)
#include <RealTimeClockDS1307.h> // RTC
#include <EEPROM.h> // EE
#include <LiquidCrystal.h> // LCD 16*2
#include <TimerOne.h> // прерывания по таймеру1

#include <OneWire.h> // 1wire для DS18B20
#include <DallasTemperature.h> // DS18B20

#define ONE_WIRE_BUS A1
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
DeviceAddress DS18B20Address;

#define encoderA    2 // энкодер - поворот вправо (об землю)
#define encoderB    3 // энкодер - поворот влево (об землю)
#define encoderK    4 // энкодер - кнопка (об землю)
#define BeepPin     11 // пищалка
#define BeepToneNo  2000 // тон звука "No", герц
#define BeepToneYes 4000 // тон звука "Yes", герц
#define BeepToneNoDuration 200 // длительность звука "No", мс
#define BeepToneYesDuration 200 // длительность звука "Yes", мс
#define  Relay  12 // нога, к которой подключено реле
#define RelayOn LOW // полярность сигнала включения реде (HIGH/LOW)

// LCD connection RS, E, D4, D5, D6, D7
// R/W - to ground
LiquidCrystal lcd(7, 6, 5, 10, 9, 8);

byte block1[8] = { 
  0x06,0x09,0x09,0x06,0x00,0x04,0x0E,0x1F }; // значок градуса с пламенем снизу
byte block2[8] = { 
  0x06,0x09,0x09,0x06,0x00,0x00,0x00,0x00 }; // значок градуса

//#define serialenabled // раскомментировать для выдачи в порт отладочной инфы

#define TstatTimerMax 120 //минимальная пауза между включениями горелки, сек
unsigned int TstatTimer = 20; //таймер паузы между включениями/выключениями, начальная установка 20 сек для устаканивания системы после сброса

float DS18B20Temperature = 0; //сырая температура от датчика
float Temperature = 0; //вычисленная температура с коррекцией
float DS18B20TempTmp; //времянка
byte DS18B20iteration = 0; //счётчик измерений температуры для усреднения

float TstatTemp = 23; //температура термостатирования, может изменяться настройками
float TemperatureCorr = 0; //коррекция температуры, может изменяться настройками
float Hysteresis = 0.1; // гистерезис термостата, может изменяться настройками
float HysteresisOld;

int Hours = 0; // времянка часов RTC для отображения и установки
int Minutes = 0; // времянка минут RTC для отображения и установки
int Seconds;
boolean PrintYesNo = false; // показывать ли после времени Yes/No (косвенно - указание на режим установка/отображение)
boolean SetH = false; // выделение часов при отображении
boolean SetM = false; // выделение минут при отображении
boolean SetYesNo = false; // выделение Yes/No при установке часов

boolean blink500ms = false; // мигающий бит, инвертируется каждые 500мс
boolean plus1sec = false; // ежесекундно взводится

boolean BeepEnabled = true;

byte MenuTimeoutTimer;

byte Timer1Hours = 0;
byte Timer1Minutes = 0;
boolean Timer1Enabled = false;
boolean Timer1Activated = false;
float Timer1Temp = 23; //температура термостатирования по таймеру1, может изменяться настройками
byte Timer2Hours = 0;
byte Timer2Minutes = 0;
boolean Timer2Enabled = false;
boolean Timer2Activated = false;
float Timer2Temp = 23; //температура термостатирования по таймеру2, может изменяться настройками
byte Timer3Hours = 0;
byte Timer3Minutes = 0;
boolean Timer3Enabled = false;
boolean Timer3Activated = false;
float Timer3Temp = 23; //температура термостатирования по таймеру3, может изменяться настройками
float AlarmTemp = 20; // температура для замерзательного орала

// encoder vars
static boolean rotating=false;      // debounce management
boolean A_set = false;              
boolean B_set = false;
boolean encoderR = false;
boolean encoderL = false;

// EEPROM addresses
#define TstatTempEEaddr 0 // EE - адрес для сохранения температуры термостатирования, 4 байта(float)!
#define TemperatureCorrEEaddr 4 // EE - адрес для сохранения коррекции температуры, 4 байта(float)!
#define HysteresisEEaddr 8 // EE - адрес для сохранения гистерезиса, 4 байта(float)!
#define Timer1HoursEEaddr 12 // EE - адрес для сохранения часов таймера 1 (byte)
#define Timer1MinutesEEaddr 13 // EE - адрес для сохранения минут таймера 1 (byte)
#define Timer1EnabledEEaddr 14 // EE - адрес для сохранения статуса таймера 1 (boolean)
#define Timer1TempEEaddr 15 // EE - адрес для сохранения температуры таймера 1, 4 байта(float)!
#define Timer2HoursEEaddr 19 // EE - адрес для сохранения часов таймера 2 (byte)
#define Timer2MinutesEEaddr 20 // EE - адрес для сохранения минут таймера 2 (byte)
#define Timer2EnabledEEaddr 21 // EE - адрес для сохранения статуса таймера 2 (boolean)
#define Timer2TempEEaddr 22 // EE - адрес для сохранения температуры таймера 2, 4 байта(float)!
#define Timer3HoursEEaddr 26 // EE - адрес для сохранения часов таймера 3 (byte)
#define Timer3MinutesEEaddr 27 // EE - адрес для сохранения минут таймера 3 (byte)
#define Timer3EnabledEEaddr 28 // EE - адрес для сохранения статуса таймера 3 (boolean)
#define Timer3TempEEaddr 29 // EE - адрес для сохранения температуры таймера 3, 4 байта(float)!
#define BeepEnabledEEaddr 33 // EE - адрес для сохранения признака разрешения звука (boolean)
#define AlarmTempEEaddr 34 // EE - адрес для сохранения значения недопустимого снижения температуры, 4 байта(float)!

// ===== SETUP ========================================================================
void setup() {
#ifdef serialenabled
  Serial.begin(9600);
#endif
  pinMode(Relay, OUTPUT);
  digitalWrite(Relay, HIGH);
  lcd.begin(16, 2);
  lcd.createChar(1, block1);
  lcd.createChar(2, block2);
  pinMode(encoderA, INPUT);
  digitalWrite(encoderA, HIGH);
  pinMode(encoderB, INPUT);
  digitalWrite(encoderB, HIGH);
  pinMode(encoderK, INPUT);
  digitalWrite(encoderK, HIGH);
  attachInterrupt(0, doEncoderA, CHANGE);   // encoder pin on interrupt 0 (pin 2)
  attachInterrupt(1, doEncoderB, CHANGE);  // encoder pin on interrupt 1 (pin 3)
  Timer1.initialize(500000); // Timer0 interrupt - set a timer of length 500000 microseconds
  Timer1.attachInterrupt( timerIsr ); // attach the service routine here
  if (EEPROM.read(Timer1HoursEEaddr) > 23) { // если первая запись однокристалки - записать начальные значения в EE
    EEPROM.write(BeepEnabledEEaddr, BeepEnabled);
    EEPROM_float_write(TstatTempEEaddr, TstatTemp);
    EEPROM_float_write(TemperatureCorrEEaddr, TemperatureCorr);
    EEPROM_float_write(HysteresisEEaddr, Hysteresis);
    EEPROM.write(Timer1HoursEEaddr, Timer1Hours);
    EEPROM.write(Timer1MinutesEEaddr, Timer1Minutes);
    EEPROM.write(Timer1EnabledEEaddr, Timer1Enabled);
    EEPROM_float_write(Timer1TempEEaddr, Timer1Temp);
    EEPROM.write(Timer2HoursEEaddr, Timer2Hours);
    EEPROM.write(Timer2MinutesEEaddr, Timer2Minutes);
    EEPROM.write(Timer2EnabledEEaddr, Timer2Enabled);
    EEPROM_float_write(Timer2TempEEaddr, Timer2Temp);
    EEPROM.write(Timer3HoursEEaddr, Timer3Hours);
    EEPROM.write(Timer3MinutesEEaddr, Timer3Minutes);
    EEPROM.write(Timer3EnabledEEaddr, Timer3Enabled);
    EEPROM_float_write(Timer3TempEEaddr, Timer3Temp);
    EEPROM_float_write(AlarmTempEEaddr, AlarmTemp);
  }
  BeepEnabled = EEPROM.read(BeepEnabledEEaddr);
  TstatTemp = EEPROM_float_read(TstatTempEEaddr);
  TemperatureCorr = EEPROM_float_read(TemperatureCorrEEaddr);
  Hysteresis = EEPROM_float_read(HysteresisEEaddr);
  Timer1Hours = EEPROM.read(Timer1HoursEEaddr);
  Timer1Minutes = EEPROM.read(Timer1MinutesEEaddr);
  Timer1Enabled = EEPROM.read(Timer1EnabledEEaddr);
  Timer1Temp = EEPROM_float_read(Timer1TempEEaddr);
  Timer2Hours = EEPROM.read(Timer2HoursEEaddr);
  Timer2Minutes = EEPROM.read(Timer2MinutesEEaddr);
  Timer2Enabled = EEPROM.read(Timer2EnabledEEaddr);
  Timer2Temp = EEPROM_float_read(Timer2TempEEaddr);
  Timer3Hours = EEPROM.read(Timer3HoursEEaddr);
  Timer3Minutes = EEPROM.read(Timer3MinutesEEaddr);
  Timer3Enabled = EEPROM.read(Timer3EnabledEEaddr);
  Timer3Temp = EEPROM_float_read(Timer3TempEEaddr);
  AlarmTemp = EEPROM_float_read(AlarmTempEEaddr);

  DS18B20.begin();
  DS18B20.getAddress(DS18B20Address, 0);
  DS18B20.setResolution(DS18B20Address, 12);
  DS18B20.setWaitForConversion(false);
  DS18B20.requestTemperatures();

  tone(BeepPin,2000,50);
  delay(50);
  tone(BeepPin,3000,50);
  delay(50);
  tone(BeepPin,4000,50);
  delay(50);
}

// ===== MAIN CYCLE ===================================================================
void loop() {

  lcd.setCursor(8, 0); //инфо на LCD
  if ((Temperature < AlarmTemp)&(blink500ms)) {
  lcd.print(F("*"));
  } else {
  lcd.print(F(" "));
  }
  lcd.print(F("t="));
  if (Temperature < 10) {
    lcd.print(F(" "));
  }
  lcd.print(Temperature,1);
  lcd.write(0x02); // значок градуса

  // если таймер 1 включен - надпись светится, если сработал - мигает
  lcd.setCursor(0, 1); //инфо на LCD
  if ((Timer1Enabled)&!((Timer1Activated)&(blink500ms))) {
    lcd.print(F("T1"));
  } 
  else { 
    lcd.print(F("  "));
  }

  // если таймер 2 включен - надпись светится, если сработал - мигает
  lcd.setCursor(3, 1); //инфо на LCD
  if ((Timer2Enabled)&!((Timer2Activated)&(blink500ms))) {
    lcd.print(F("T2"));
  } 
  else { 
    lcd.print(F("  "));
  }

  // если таймер 3 включен - надпись светится, если сработал - мигает
  lcd.setCursor(6, 1); //инфо на LCD
  if ((Timer3Enabled)&!((Timer3Activated)&(blink500ms))) {
    lcd.print(F("T3"));
  } 
  else { 
    lcd.print(F("  "));
  }

  lcd.setCursor(9, 1); //инфо на LCD
  lcd.print(F("s="));
  lcd.print(TstatTemp,1);
  if ( digitalRead(Relay) == RelayOn ) { 
    lcd.write(0x01); // значок градуса с пламенем
  } 
  else { 
    lcd.write(0x02); // значок градуса
  }

  // печатаем текущее время
  PrintYesNo = false;
  PrintRTC(0,0);

  // термостатирование
  if ( TstatTimer == 0 )
  {
    if ( Temperature > ( TstatTemp + Hysteresis ) ) // гистерезис
    {
      if ( digitalRead(Relay) == RelayOn ) // если горелка включена - 
      {
        digitalWrite(Relay, !RelayOn); // выключить горелку
        TstatTimer = TstatTimerMax; // горелку держать выключённой не менее заданного в TstatTimerMax времени
      }
    }
    if (Temperature < TstatTemp)
    {
      if ( digitalRead(Relay) == !RelayOn ) // если горелка выключена - 
      {
        digitalWrite(Relay, RelayOn); // включить горелку
        TstatTimer = TstatTimerMax; // горелку держать включённой не менее заданного в TstatTimerMax времени
      }
    }
  }
  
  // если прошла 1 секунда - делаем ежесекундные дела
  if (plus1sec) {
    plus1sec = false; // сбрасываем до следующей секунды
    // обновляем часы
    RTC.readClock();
    Hours=RTC.getHours();
    Minutes=RTC.getMinutes();
    Seconds=RTC.getSeconds();

    // измеряем температуру воздуха
    DS18B20TempTmp = DS18B20.getTempCByIndex(0); // получить температуру от датчика
    DS18B20.requestTemperatures();  // запустить новое измерение
    if (DS18B20TempTmp != -127)
    {
    DS18B20Temperature += DS18B20TempTmp; // суммируем для усреднения
    DS18B20iteration ++;
    if (DS18B20iteration == 10)
      {
      DS18B20iteration = 0;
      Temperature = (DS18B20Temperature / 10) + TemperatureCorr; //усреднённая + коррекция
      DS18B20Temperature = 0;
      }
    }
    
    // если уставку термостата поменяли вручную - запись её в EE, не чаще 1 раза в минуту
    //(экономия ресурса EE)
    if ((EEPROM_float_read(TstatTempEEaddr) != TstatTemp)&(Seconds == 0)) {
      EEPROM_float_write(TstatTempEEaddr, TstatTemp);
    }

    // проверка Timer1 и изменение уставки термостата при совпадении	
    if ((Hours == Timer1Hours)&(Minutes == Timer1Minutes)&(Timer1Enabled)&(Seconds == 0)) { // время T1 совпадает с RTC
      Timer1Activated = true;
      Timer2Activated = false;
      Timer3Activated = false;
      TstatTemp = Timer1Temp;
      EEPROM_float_write(TstatTempEEaddr, TstatTemp);
      if (BeepEnabled) {
        tone(BeepPin,4000,5);
      }
    }

    // проверка Timer2 и изменение уставки термостата при совпадении	
    if ((Hours == Timer2Hours)&(Minutes == Timer2Minutes)&(Timer2Enabled)&(Seconds == 0)) { // время T2 совпадает с RTC
      Timer1Activated = false;
      Timer2Activated = true;
      Timer3Activated = false;
      TstatTemp = Timer2Temp;
      EEPROM_float_write(TstatTempEEaddr, TstatTemp);
      if (BeepEnabled) {
        tone(BeepPin,4000,5);
      }
    }

    // проверка Timer3 и изменение уставки термостата при совпадении	
    if ((Hours == Timer3Hours)&(Minutes == Timer3Minutes)&(Timer3Enabled)&(Seconds == 0)) { // время T3 совпадает с RTC
      Timer1Activated = false;
      Timer2Activated = false;
      Timer3Activated = true;
      TstatTemp = Timer3Temp;
      EEPROM_float_write(TstatTempEEaddr, TstatTemp);
      if (BeepEnabled) {
        tone(BeepPin,4000,5);
      }
    }

    // дебаг-инфо - в терминал
#ifdef serialenabled
    Serial.print(F("Temp="));
    Serial.print(Temperature, 1);
    Serial.print(F("("));
    Serial.print(DS18B20Temperature, 4);
    Serial.print(F(",corr "));
    Serial.print(TemperatureCorr, 1);
    Serial.print(F("),TstatTimer="));
    Serial.println(TstatTimer);
#endif
    
    if (Temperature < AlarmTemp) {
    tone(BeepPin,4000,5);
    }
  }

  // обработка поворота энкодера на лету (ручное изменение уставки температуры))
  rotating = true;  // reset the debouncer
  if ((encoderR)^(encoderL)) {
    if (encoderR) {
      TstatTemp += 0.1;
    } 
    else 
    {
      TstatTemp -= 0.1;
    }
    TstatTemp = constrain(TstatTemp, 10, 35);
    encoderR = false;
    encoderL = false;
    Timer1Activated = false;
    Timer2Activated = false;
    Timer3Activated = false;
    }

  // ================ по нажатию кнопки энкодера - меню настроек ====================
  if(digitalRead(encoderK) == 0) {
    MenuTimeoutTimer = 10; //таймер таймаута, секунд
    lcd.clear();
    lcd.setCursor(0, 0); //инфо на LCD
    lcd.print(F("< SETUP >"));  
    if (BeepEnabled) { 
      tone(BeepPin,4000,50); 
    }
    delay(200);
    int menuitem = 0;

    do {
      rotating = true;  // reset the debouncer
      if ((encoderR)^(encoderL)) {
        MenuTimeoutTimer = 10; //таймер таймаута, секунд
        if (encoderR) { menuitem += 1; } 
        else  { menuitem -= 1; }
        if ( menuitem > 8 ) { menuitem = 0; } // границы пунктов меню
        if ( menuitem < 0 ) { menuitem = 8; }
        encoderR = false;
        encoderL = false;
      }
      
      // индикация пункта меню (номер пункта - в menuitem)
      lcd.setCursor(0, 1); //инфо на LCD
      switch(menuitem)
      {
      case 0:
        lcd.print(F("0.BACK          "));  
        break;
      case 1:
        lcd.print(F("1.TIMER1 SET    "));  
        break;
      case 2:
        lcd.print(F("2.TIMER2 SET    "));  
        break;
      case 3:
        lcd.print(F("3.TIMER3 SET    "));  
        break;      
      case 4:
        lcd.print(F("4.CLOCK SET     "));  
        break;
      case 5:
        lcd.print(F("5.HYSTERESIS SET"));  
        break;
      case 6:
        lcd.print(F("6.T-CORRECT SET "));  
        break;
      case 7:
        lcd.print(F("7.SOUND SET     "));  
        break;
      case 8:
        lcd.print(F("8.T-ALARM SET   "));  
        break;      }
      if (MenuTimeoutTimer == 0) {
        menuitem = 0;
      }

    }
    while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));
    // если нажата кнопка энкодера или таймаут - обработка пункта меню (номер пункта - в menuitem)
    if (BeepEnabled) {
      tone(BeepPin,4000,50);
    } 
    switch(menuitem)
    {
    // ====== пункт 0 - выход
    case 0: 
      if (BeepEnabled) { 
        tone(BeepPin,BeepToneNo,BeepToneNoDuration); 
      } //звук "NO"
      break; // case 0 out

    // ====== пункт 1 - установка Timer1
    case 1:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("SETUP TIMER1"));  
      delay(200);
      Hours=Timer1Hours;
      Minutes=Timer1Minutes;
      SetYesNo = false;
      PrintYesNo = true;
      SetTime(0,1); // в позиции 0,1 - запрос ввода времени
      if (MenuTimeoutTimer != 0) {
        if (SetYesNo) // если при установке времени выбрано "Yes"
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
          }
          Timer1Hours = Hours;
          Timer1Minutes = Minutes;
          Timer1Enabled = true;
          EEPROM.write(Timer1HoursEEaddr, Timer1Hours);
          EEPROM.write(Timer1MinutesEEaddr, Timer1Minutes);
          EEPROM.write(Timer1EnabledEEaddr, Timer1Enabled);

          MenuTimeoutTimer = 10; //таймер таймаута, секунд
          lcd.clear();
          lcd.setCursor(0, 0); //инфо на LCD
          lcd.print(F("Timer1 Temp. Set"));  
          delay(200);
          do {
            lcd.setCursor(0,1);
            if (blink500ms) {
              lcd.print(F("     "));  
            } 
            else {
              lcd.print(Timer1Temp, 1);  
              lcd.write(0x02); // значок градуса
            }
            rotating = true;  // reset the debouncer
            if (encoderR) {
              Timer1Temp += 0.1;
              encoderR = false;
            }
            if (encoderL) {
              Timer1Temp -= 0.1;
              encoderL = false;
            }
            Timer1Temp = constrain(Timer1Temp, 10, 35); // крайние значения
          }
          while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));

          if (MenuTimeoutTimer != 0) { // если после выбора температуры нажата кнопка энкодера
            EEPROM_float_write(Timer1TempEEaddr, Timer1Temp);
            if (BeepEnabled) {
              tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
            }
          }
          else { // если не нажата - используем старую температуру
            Timer1Temp = EEPROM_float_read(Timer1TempEEaddr);
            if (BeepEnabled) {
              tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
            }
          }		  

        }
        else // если при установке времени выбрано "No"
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
          }
          Timer1Enabled = false;
          EEPROM.write(Timer1EnabledEEaddr, Timer1Enabled);
          Timer1Hours = EEPROM.read(Timer1HoursEEaddr);
          Timer1Minutes = EEPROM.read(Timer1MinutesEEaddr);
        }
      }
      else {
        if (BeepEnabled) {
          tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
        }
      }
      break; // case 1 out

    // ====== пункт 2 - установка Timer2
    case 2:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("SETUP TIMER2"));  
      delay(200);
      Hours=Timer2Hours;
      Minutes=Timer2Minutes;
      SetYesNo = false;
      PrintYesNo = true;
      SetTime(0,1); // в позиции 0,1 - запрос ввода времени
      if (MenuTimeoutTimer != 0) {
        if (SetYesNo) // если при установке времени выбрано "Yes"
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
          }
          Timer2Hours = Hours;
          Timer2Minutes = Minutes;
          Timer2Enabled = true;
          EEPROM.write(Timer2HoursEEaddr, Timer2Hours);
          EEPROM.write(Timer2MinutesEEaddr, Timer2Minutes);
          EEPROM.write(Timer2EnabledEEaddr, Timer2Enabled);

          MenuTimeoutTimer = 10; //таймер таймаута, секунд
          lcd.clear();
          lcd.setCursor(0, 0); //инфо на LCD
          lcd.print(F("Timer2 Temp. Set"));  
          delay(200);
          do {
            lcd.setCursor(0,1);
            if (blink500ms) {
              lcd.print(F("     "));  
            } 
            else {
              lcd.print(Timer2Temp, 1);  
              lcd.write(0x02); // значок градуса
            }
            rotating = true;  // reset the debouncer
            if (encoderR) {
              Timer2Temp += 0.1;
              encoderR = false;
            }
            if (encoderL) {
              Timer2Temp -= 0.1;
              encoderL = false;
            }
            Timer2Temp = constrain(Timer2Temp, 10, 35); // крайние значения
          }
          while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));

          if (MenuTimeoutTimer != 0) { // если после выбора температуры нажата кнопка энкодера
            EEPROM_float_write(Timer2TempEEaddr, Timer2Temp);
            if (BeepEnabled) {
              tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
            }
          }
          else { // если не нажата - используем старую температуру
            Timer2Temp = EEPROM_float_read(Timer2TempEEaddr);
            if (BeepEnabled) {
              tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
            }
          }		  

        }
        else // если при установке времени выбрано "No"
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
          }
          Timer2Enabled = false;
          EEPROM.write(Timer2EnabledEEaddr, Timer2Enabled);
          Timer2Hours = EEPROM.read(Timer2HoursEEaddr);
          Timer2Minutes = EEPROM.read(Timer2MinutesEEaddr);
        }
      }
      else {
        if (BeepEnabled) {
          tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
        }
      }
      break; // case 2 out

    // ====== пункт 3 - установка Timer3
    case 3:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("SETUP TIMER3"));  
      delay(200);
      Hours=Timer3Hours;
      Minutes=Timer3Minutes;
      SetYesNo = false;
      PrintYesNo = true;
      SetTime(0,1); // в позиции 0,1 - запрос ввода времени
      if (MenuTimeoutTimer != 0) {
        if (SetYesNo) // если при установке времени выбрано "Yes"
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
          }
          Timer3Hours = Hours;
          Timer3Minutes = Minutes;
          Timer3Enabled = true;
          EEPROM.write(Timer3HoursEEaddr, Timer3Hours);
          EEPROM.write(Timer3MinutesEEaddr, Timer3Minutes);
          EEPROM.write(Timer3EnabledEEaddr, Timer3Enabled);

          MenuTimeoutTimer = 10; //таймер таймаута, секунд
          lcd.clear();
          lcd.setCursor(0, 0); //инфо на LCD
          lcd.print(F("Timer3 Temp. Set"));  
          delay(200);
          do {
            lcd.setCursor(0,1);
            if (blink500ms) {
              lcd.print(F("     "));  
            } 
            else {
              lcd.print(Timer3Temp, 1);  
              lcd.write(0x02); // значок градуса
            }
            rotating = true;  // reset the debouncer
            if (encoderR) {
              Timer3Temp += 0.1;
              encoderR = false;
            }
            if (encoderL) {
              Timer3Temp -= 0.1;
              encoderL = false;
            }
            Timer3Temp = constrain(Timer3Temp, 10, 35); // крайние значения
          }
          while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));

          if (MenuTimeoutTimer != 0) { // если после выбора температуры нажата кнопка энкодера
            EEPROM_float_write(Timer3TempEEaddr, Timer3Temp);
            if (BeepEnabled) {
              tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
            }
          }
          else { // если не нажата - используем старую температуру
            Timer3Temp = EEPROM_float_read(Timer3TempEEaddr);
            if (BeepEnabled) {
              tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
            }
          }		  

        }
        else // если при установке времени выбрано "No"
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
          }
          Timer3Enabled = false;
          EEPROM.write(Timer3EnabledEEaddr, Timer3Enabled);
          Timer3Hours = EEPROM.read(Timer3HoursEEaddr);
          Timer3Minutes = EEPROM.read(Timer3MinutesEEaddr);
        }
      }
      else {
        if (BeepEnabled) {
          tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
        }
      }
      break; // case 3 out

    // ====== пункт 4 - установка RTC
    case 4:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("SETUP CLOCK"));  
      delay(200);
      RTC.readClock();
      Hours=RTC.getHours();
      Minutes=RTC.getMinutes();
      SetYesNo = false;
      PrintYesNo = true;
      SetTime(0,1); // в позиции 0,1 - запрос ввода времени
      if (MenuTimeoutTimer != 0) {
        if (SetYesNo)
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
          }
          RTC.setHours(Hours);
          RTC.setMinutes(Minutes);
          RTC.setSeconds(0);
          RTC.setClock();
        }
        else
        {
          if (BeepEnabled) {
            tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
          }
        }
      }
      else {
        if (BeepEnabled) {
          tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
        }
      }
      break; // case 4 out

    // ====== пункт 5 - установка гистерезиса
    case 5:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      HysteresisOld = Hysteresis;
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("SETUP HYSTERESIS"));  
      delay(200);
      do {
        lcd.setCursor(0,1);
        if (blink500ms) {
          lcd.print("   ");  
        } 
        else {
          lcd.print(Hysteresis, 1);  
          lcd.write(0x02); // значок градуса
        }
        rotating = true;  // reset the debouncer
        if (encoderR) {
          Hysteresis += 0.1;
          encoderR = false;
        }
        if (encoderL) {
          Hysteresis -= 0.1;
          encoderL = false;
        }
        Hysteresis = constrain(Hysteresis, 0.1, 1); // крайние значения
      }
      while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));
      if (MenuTimeoutTimer != 0) {
        EEPROM_float_write(HysteresisEEaddr, Hysteresis); // запись в ЕЕПРОМ
        if (BeepEnabled) {
          tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
        }
      }
      else {
        Hysteresis = HysteresisOld;
        if (BeepEnabled) {
          tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
        }
      }
      break; // case 5 out

    // ====== пункт 6 - установка коррекции температуры 
    case 6:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("SETUP T-CORRECT "));  
      delay(200);
      do {
        lcd.setCursor(0,1);
        if (blink500ms) {
          lcd.print(F("    "));  
        } 
        else {
          if (TemperatureCorr >= 0) {
            lcd.print(F("+")); 
          }

          lcd.print(TemperatureCorr, 1);  
          lcd.write(0x02); // значок градуса
        }
        rotating = true;  // reset the debouncer
        if (encoderR) {
          TemperatureCorr += 0.1;
          encoderR = false;
        }
        if (encoderL) {
          TemperatureCorr -= 0.1;
          encoderL = false;
        }
        TemperatureCorr = constrain(TemperatureCorr, -8, 8); // крайние значения
      }
      while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));

      if (MenuTimeoutTimer != 0) {
        EEPROM_float_write(TemperatureCorrEEaddr, TemperatureCorr); // запись в ЕЕПРОМ
        if (BeepEnabled) {
          tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
        }
      }
      else {
        TemperatureCorr = EEPROM_float_read(TemperatureCorrEEaddr);
        if (BeepEnabled) {
          tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
        }
      }
      break; // case 6 out      

    // ====== пункт 7 - вкл/выкл звука
    case 7:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("SOUND SET       "));  
      delay(200);
      do {
        lcd.setCursor(0,1);
        if (BeepEnabled) {
          lcd.print(F("BEEP ON         "));  
        }      
        else {
          lcd.print(F("BEEP OFF        "));  
        }

        rotating = true;  // reset the debouncer
        if ((encoderR)^(encoderL)) {
          BeepEnabled = !BeepEnabled;
          encoderR = false;
          encoderL = false;
        }
      }
      while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));

      if (MenuTimeoutTimer != 0) {
        if (BeepEnabled) {
          tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
        }
        EEPROM.write(BeepEnabledEEaddr, BeepEnabled);
      }
      if (MenuTimeoutTimer == 0) {
        BeepEnabled = EEPROM.read(BeepEnabledEEaddr);
      }
      break; // case 7 out

      // ====== пункт 8 - установка коррекции температуры  
    case 8:
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      lcd.clear();
      lcd.setCursor(0, 0); //инфо на LCD
      lcd.print(F("ALARM-TEMP SET  "));  
      delay(200);
      do {
        lcd.setCursor(0,1);
        if (blink500ms) {
          lcd.print(F("    "));  
        } 
        else {
          if (AlarmTemp >= 0) {
            lcd.print(F("+")); 
          }

          lcd.print(AlarmTemp, 0);  
          lcd.write(0x02); // значок градуса
        }
        rotating = true;  // reset the debouncer
        if (encoderR) {
          AlarmTemp += 1;
          encoderR = false;
        }
        if (encoderL) {
          AlarmTemp -= 1;
          encoderL = false;
        }
        AlarmTemp = constrain(AlarmTemp, 15, 30); // крайние значения
      }
      while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));

      if (MenuTimeoutTimer != 0) {
        EEPROM_float_write(AlarmTempEEaddr, AlarmTemp); // запись в ЕЕПРОМ
        if (BeepEnabled) {
          tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES"
        }
      }
      else {
        AlarmTemp = EEPROM_float_read(AlarmTempEEaddr);
        if (BeepEnabled) {
          tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO"
        }
      }
      break; // case 8 out
      
    }

    delay(200);
    lcd.clear();
  }
}

// ===== SUBROUTINES ==================================================================

// ========================================
void SetTime(char x, char y)
{
  // ========= set hours
  SetH = true;
  do {
    PrintRTC(x,y);
    rotating = true;  // reset the debouncer
    if (encoderR) {
      Hours += 1;
      if(Hours > 23) {
        Hours = 0;
      };
      encoderR = false;
    }
    if (encoderL) {
      Hours -= 1;
      if(Hours < 0) {
        Hours = 23;
      };
      encoderL = false;
    }
  }
  while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));
  if (BeepEnabled) {
    tone(BeepPin,4000,50); //звук "YES"
  }
  SetH = false;
  delay(200);
  // ========= set minutes
  SetM = true;
  do {
    PrintRTC(0,1);
    rotating = true;  // reset the debouncer
    if (encoderR) {
      Minutes += 1;
      if(Minutes > 59) {
        Minutes = 0;
      };
      encoderR = false;
    }
    if (encoderL) {
      Minutes -= 1;
      if(Minutes < 0) {
        Minutes = 59;
      };
      encoderL = false;
    }
  }
  while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));
  if (BeepEnabled) {
    tone(BeepPin,4000,50); //звук "YES"
  }
  if (PrintYesNo) {
    SetM = false;
    delay(200);
    // ========= set yes-no
    SetYesNo = false;
    do {
      PrintRTC(0,1);
      rotating = true;  // reset the debouncer
      if ((encoderR)||(encoderL)) {
        SetYesNo = !SetYesNo;
        encoderR = false;
        encoderL = false;
      }
    }
    while ((digitalRead(encoderK)==1)^(MenuTimeoutTimer==0));
    delay(200);
  }

}

// ========================================
void PrintRTC(char x, char y)
{
  lcd.setCursor(x,y);
  if (SetH&&blink500ms) {
    lcd.print(F("  ")); 
  } 
  else {
    if (Hours < 10) { 
      lcd.print(F("0")); 
    }    
    lcd.print(Hours);
  }

  // мигающее двоеточие, если не в режиме установки времени
  if (!(SetH||SetM||PrintYesNo||blink500ms))
  {
    lcd.print(F(" "));
  } 
  else {
    lcd.print(F(":"));
  }

  if (SetM&&blink500ms) {
    lcd.print(F("  ")); 
  } 
  else {
    if (Minutes < 10) { 
      lcd.print(F("0")); 
    }    
    lcd.print(Minutes);
  }
  lcd.print(F(" "));

  if (PrintYesNo) {
    lcd.print(F("["));
    if (!(SetH||SetM||blink500ms))
    {
      lcd.print(F("   "));
    }
    else {
      if (SetYesNo)
      {
        lcd.print(F("YES"));
      } 
      else {
        lcd.print(F("NO "));
      }
    }
    lcd.print(F("]"));
  }

}

// ========= чтение/запись float в EE =====
void EEPROM_float_write(int addr, float val) // запись в ЕЕПРОМ
{ 
  byte *x = (byte *)&val;
  for(byte i = 0; i < 4; i++) EEPROM.write(i+addr, x[i]);
}

float EEPROM_float_read(int addr) // чтение из ЕЕПРОМ
{   
  byte x[4];
  for(byte i = 0; i < 4; i++) x[i] = EEPROM.read(i+addr);
  float *y = (float *)&x;
  return y[0];
}
// ========================================

// ============================ Encoder interrupts =============================
// Interrupt on A changing state
void doEncoderA(){
  if ( rotating ) {
    delay (1) ;  // wait a little until the bouncing is done
  }
  // Test transition, did things really change? 
  if( digitalRead(encoderA) != A_set ) {  // debounce once more
    A_set = !A_set;
    // adjust counter + if A leads B
    if ( A_set && !B_set )
    {
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      if (BeepEnabled) {
        tone(BeepPin,4000,5);
      }
      encoderR = true;
      rotating = false;  // no more debouncing until loop() hits again
    }
  }
}
// Interrupt on B changing state, same as A above
void doEncoderB(){
  if ( rotating ) {
    delay (1);
  }
  if( digitalRead(encoderB) != B_set ) {
    B_set = !B_set;
    //  adjust counter - 1 if B leads A
    if( B_set && !A_set ) {
      MenuTimeoutTimer = 10; //таймер таймаута, секунд
      if (BeepEnabled) {
        tone(BeepPin,4000,5);
      }
      encoderL = true;
      rotating = false;
    }
  }
}
// ============================ Timer0 interrupt =============================
// run every 500ms
void timerIsr()
{
  blink500ms = !blink500ms; // инверсия мерцающего бита
  if(blink500ms) {
    plus1sec = true; // ежесекундно взводится
    if (TstatTimer != 0) {
      TstatTimer --; // ежесекундный декремент этого таймера
    }
    if (MenuTimeoutTimer != 0) {
      MenuTimeoutTimer --; // ежесекундный декремент этого таймера
    }
  }
}






























 

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

vlad219i пишет:

Конструктивная критика принимается. Код можете использовать на свой стах и риск, для медицинских применений прибор не подходит. :-)

Проводились ли тесты на животных и сколько их от этого пострадало?

А как Вы проверяете что пьезо сработала?

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

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

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

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

Хм. То-есть пьзо щелкнула, газ пошел но не загорелся, и ждемс бумс?

leshak
Offline
Зарегистрирован: 29.09.2011

JollyBiber пишет:

Хм. То-есть пьзо щелкнула, газ пошел но не загорелся, и ждемс бумс?

Микрофон поставить? Типа "если бумс, значит не загорелся".

А вообще, лично бы я пострелся ставить что-то что может самостоятельно "зажигать гас". Я бы ставил только больше/меньше. Причем, как правильно заметил JollyBiber нужен еще контроль что "горении идет".

Если погасло (не важно по каким причинам), все перекрывать, слать SMS хозяину, и... по хорошему, еще бы и себя обесточить.

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

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

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

Я на прямые вопросы даю прямые ответы.

Во избежание дальнейшего флейма - гугль в помощь, по запросу "комнатный термостат для котла" будет масса подробных объяснений, что это такое и как оно подключается к штатной(!) колодке подключения термостата котла. Откуда взялись глубокомысленные выводы, что я изобрёл мозг для котла и насколько мне стало опаснее жить, я не знаю. Другими словами - друзья мои, вы просто перепутали круглое с мягким. :-)

И я повторю на всякий случай: пьезодинамик - это то, что издаёт звук. Для этого здесь и используется. Проще говоря - он говорит "бип" при нажатии кнопки. Как объяснить ещё проще - я не знаю.

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

вся газовая защита - в котле ! у него свои мозги есть... 

хороший проект - пойду под дачу брата его подпиливать :)

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

vlad219i пишет:

Я на прямые вопросы даю прямые ответы.

Во избежание дальнейшего флейма - гугль в помощь...

Что Вы! Простите нас глупцов необразованных! Мы просто от офигивания Вашим проектом впали в ступор! Я сейчас-же пойду читать про все виды горелок, обогревателей, отопителей и на всякий случай про рыбные консервы, а то мало ли что, и особенно про Ваш "комнатный термостат для котла".

Вы бы просто сразу в первом посте написали "можно восхищаться и офигивать. За всеми вопросами - в гуглю"

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

кроме котла о "БУУУУУУУУУУМ" ещё беспокоится датчик газа в помещении ( сразу перекрывает газ на весь объект - ОБЯЗАТЕЛЕН при подключении к газовым магистралям )..... на Украине, кажися, его не используют :)

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

error

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

чё напали-то на человека ? это же ветка ПРОЕКТЫ..... кому надо - пользуйтесь, кому не нать - не орите.... 

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

Дружище JollyBiber, в таком случае предлагаю продолжить разговор после того, как вы закончите "читать про все виды горелок, обогревателей, отопителей и на всякий случай про рыбные консервы". Иначе получается, что вы берётесь рассуждать о том, в чём не смыслите, что выглядит довольно забавно.

Удачи!

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

2SU-27-16: спасибо на добром слове. Собственно, допилить проект будет несложно - я скетч обвешал дефайнами как раз с целью лёгкой повторяемости и гибкой настройки под разное железо и разные потребности, ибо повторять оную железку мне для знакомых наверняка придётся... :-)

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

Эмм.. Перечитал свои посты, места где я "рассуждал" так и не нашел (* вычеркнул из плана на завтра провериться на старческий маразм). Задал вопрос - был отправлен в гугль. Про то что гугль знает больше Вас я никогда не сомневался. Вы похвастаться выкладывали проект? Тогда смотрите мой пост выше. Обычно здесь выкладывают свои проекты и отвечают на вопросы по существу и от тех кто не в теме.

И Вам не хворать.

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

vlad219i пишет:

2SU-27-16: спасибо на добром слове. Собственно, допилить проект будет несложно - я скетч обвешал дефайнами как раз с целью лёгкой повторяемости и гибкой настройки под разное железо и разные потребности, ибо повторять оную железку мне для знакомых наверняка придётся... :-)

моя всё понял, спасибо !

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

JollyBiber пишет:

Эмм.. Перечитал свои посты, места где я "рассуждал" так и не нашел (* вычеркнул из плана на завтра провериться на старческий маразм). Задал вопрос - был отправлен в гугль. Про то что гугль знает больше Вас я никогда не сомневался. Вы похвастаться выкладывали проект? Тогда смотрите мой пост выше. Обычно здесь выкладывают свои проекты и отвечают на вопросы по существу и от тех кто не в теме.

И Вам не хворать.

нуууууу, по ходу перепутали ( кто - не помню и не хочЮ искать ) пъезоПищалку с пъезоПоджигом - нано всем успокоиться....

гугл - не умнее, он просто быстрее ищет инфу...

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

JollyBiber пишет:

Хм. То-есть пьзо щелкнула, газ пошел но не загорелся, и ждемс бумс?

ой, так это Вы и начали......

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

SU-27-16 пишет:

JollyBiber пишет:

Хм. То-есть пьзо щелкнула, газ пошел но не загорелся, и ждемс бумс?

ой, так это Вы и начали......

Ой, там можно дальше наверх скроллить! ;)

vlad219i пишет:

Что может: включать-выключать горелку газового котла (электрообогреватель тоже можно)

nikolaki
nikolaki аватар
Offline
Зарегистрирован: 14.02.2013

Чет Пухлявый молчит.. Не приболел часом?Странно ....

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

Дружеский совет: дом- это не инкубатор.

Регулировать котёл по температуре ВНУТРИ помещения- бессмысленно. Я подошёл и "дыхнул" на датчик, включил телевизор, плиту на кухне - и вот ваш термостат отключил отопление. У вас получился комнатный термостат (room termostat). Для инкубатора.

Погодозависимый регулятор измеряет температуру на улице (потери тепла домом зависят от уличной температуры) и по графику изменяет температуру подачи котла.

 

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

nikolaki пишет:

Чет Пухлявый молчит.. Не приболел часом?Странно ....

 

Гы :) Работает он, деньги на ардуину зарабатывает.

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

JollyBiber пишет:

SU-27-16 пишет:

JollyBiber пишет:

Хм. То-есть пьзо щелкнула, газ пошел но не загорелся, и ждемс бумс?

ой, так это Вы и начали......

Ой, там можно дальше наверх скроллить! ;)

vlad219i пишет:

Что может: включать-выключать горелку газового котла (электрообогреватель тоже можно)

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

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Я все слышу!
А че тут обсуждать то? Ну прилепил мужик датчик температуры и реле.. в чем прикол то?

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

trembo пишет:

Дружеский совет: дом- это не инкубатор.

Регулировать котёл по температуре ВНУТРИ помещения- бессмысленно. Я подошёл и "дыхнул" на датчик, включил телевизор, плиту на кухне - и вот ваш термостат отключил отопление. У вас получился комнатный термостат (room termostat). Для инкубатора.

Погодозависимый регулятор измеряет температуру на улице (потери тепла домом зависят от уличной температуры) и по графику изменяет температуру подачи котла.

 

бессмысленно управление котлом по t обратки !!!!!!!!!!! именно и надо регулировать по t в помещении...

и рядом с датчиком t в помещении надо поставить датчик алкоголя !!!!!!!!! чобы неадекватные не дышали на датчик t !!!!!!

ВСЁ правильно !!!!!!!!!!!!! включили телевизор - он подогреет помещение.... котлу меньше работы....

 

помогите лучьше НОВИЧКАМ ! чем тут рассуждать....

Проект уже работает !!!!!!!!!!

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Обычно для таких целей ставят пружинку которая от температуры воздуха замыкает и размыкает контакт..

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

trembo пишет:

Погодозависимый регулятор измеряет температуру на улице (потери тепла домом зависят от уличной температуры) и по графику изменяет температуру подачи котла.

 

Вы обрисовали логику работы ТЭЦ... а дом - это и есть ИНКУБАТОР с постоянной температурой внутри помещения независимо от температуры на улице !

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

Puhlyaviy пишет:
Обычно для таких целей ставят пружинку которая от температуры воздуха замыкает и размыкает контакт..

как в холодильнике, как в жаровом шкафу ? ....тогда Ардуину - НАХ ?

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

2trembo: да, я в курсе про разные типы термостатирования. Однако, для реализации погодозависимого регулятора нужно либо иметь уличный термодатчик, заточенный под конкретный котёл (датчик стОит зачастую несуразных денег, да и вход для подключения этого датчика предусмотрен не в каждом котле), либо знать протокол, используемый при подключении оригинального терморегулятора с возможностью управления модулятором (такая возможность есть тоже не везде). В общем - покопав инет на эту тему, я остановился на комнатном термостате. Вопрос дыхания/телевизора/плиты решён установкой термодатчика в определённом месте помещения (в тени, вдали от шальных потоков воздуха, батарей и прочих катаклизмов).

Вкратце - я ж говорю, меня устраивает. Вариант с уличным датчиком наверняка во сто крат правильнее и экономичнее, но в моём случае room thermostat'а мне хватает за глаза. Елозить установкой температуры теплоносителя больше не приходится, ну и, к примеру, котёл реже включается, если солнце через окна подогревает дом, - дык этого я и добивался. :-)

 

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

SU-27-16 пишет:

Puhlyaviy пишет:
Обычно для таких целей ставят пружинку которая от температуры воздуха замыкает и размыкает контакт..

как в холодильнике, как в жаровом шкафу ? ....тогда Ардуину - НАХ ?

Именно. Такие пружинчатые термостаты уже 100 используют. Его достаточно что бы делать описаное в топике... и именно на него расчитан вывод на котле. Заикнулось включилось, разомкнулось выключилось. 5 баксов. Точность даже в 1-2 градуса не критична для дома.

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

vlad219i пишет:

2trembo: да, я в курсе про разные типы термостатирования. Однако, для реализации погодозависимого регулятора нужно либо иметь уличный термодатчик, заточенный под конкретный котёл (датчик стОит зачастую несуразных денег, да и вход для подключения этого датчика предусмотрен не в каждом котле), либо знать протокол, используемый при подключении оригинального терморегулятора с возможностью управления модулятором (такая возможность есть тоже не везде). В общем - покопав инет на эту тему, я остановился на комнатном термостате. Вопрос дыхания/телевизора/плиты решён установкой термодатчика в определённом месте помещения (в тени, вдали от шальных потоков воздуха, батарей и прочих катаклизмов).

Вкратце - я ж говорю, меня устраивает. Вариант с уличным датчиком наверняка во сто крат правильнее и экономичнее, но в моём случае room thermostat'а мне хватает за глаза. Елозить установкой температуры теплоносителя больше не приходится, ну и, к примеру, котёл реже включается, если солнце через окна подогревает дом, - дык этого я и добивался. :-)

 

Вопрос дыхания/телевизора/плиты решён установкой термодатчика в определённом месте помещения (в тени, вдали от шальных ВОЗДЫХАТЕЛЕЙ на термодатчик ).    :)

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

2Puhlyaviy: пружинка (пассивный room thermostat) имеет лютый гистерезис, порядка 1 градуса - сие есть неприемлемо. Кроме того, пружинка не умеет по времени суток менять уставку температуры. Про прикрученные реле и датчик - прикола нет, разумеется. Термостата с нужным мне функционалом за адекватные деньги я не нашёл, готового проекта тоже, что и побудило меня к.

PS: лютобешено завидую тому, что для Вас разница температуры в помещении 1-2 градуса не важна. По своему опыту скажу - разница в полградуса - это смена футболки на рубашку. Я предпочитаючастым переодеваниям более продуктивные занятия.

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

Puhlyaviy пишет:
SU-27-16 пишет:

Puhlyaviy пишет:
Обычно для таких целей ставят пружинку которая от температуры воздуха замыкает и размыкает контакт..

как в холодильнике, как в жаровом шкафу ? ....тогда Ардуину - НАХ ?

Именно. Такие пружинчатые термостаты уже 100 используют. Его достаточно что бы делать описаное в топике... и именно на него расчитан вывод на котле. Заикнулось включилось, разомкнулось выключилось. 5 баксов. Точность даже в 1-2 градуса не критична для дома.

согласен... приупрощениии...

а как быть, если : подвал ( котельная ), 2 этажа по три комнаты + санузел на каждом, гараж и оранжерея над гаражом ?

тока радиодатчики t от каждого помещения и управление потоком теплоносителя на каждое помещение....

ЭТИ датчики - громоздские для таких целей...

 

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

vlad219i пишет:

пружинка не умеет по времени суток менять уставку температуры

дааааааа, Ардуинка позволит установить режимы - все спят, все ушли на работу, все на Мальдивах ( не разморозить систему бы ), и т.д.

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

vlad219i пишет:

2Puhlyaviy: пружинка (пассивный room thermostat) имеет лютый гистерезис, порядка 1 градуса - сие есть неприемлемо. Кроме того, пружинка не умеет по времени суток менять уставку температуры. Про прикрученные реле и датчик - прикола нет, разумеется. Термостата с нужным мне функционалом за адекватные деньги я не нашёл, готового проекта тоже, что и побудило меня к.

PS: лютобешено завидую тому, что для Вас разница температуры в помещении 1-2 градуса не важна. По своему опыту скажу - разница в полградуса - это смена футболки на рубашку. Я предпочитаючастым переодеваниям более продуктивные занятия.

совершенно не согласен !

точность датчика t в +/- 0,1 гр не даст Вам точность t в помещении такую же....

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

ТОЛЬКО при всех факторах внешних = const можно будет достичь t в помещении +/- 1...3 гр

...чобы точнее выдерживать - нужно задейсвовать кондиционер :(

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Вы делаете мне смешно.
Вы врятли почуствуете разницу в 2-3 градуса.
А темы о изменении температуры в течении суток вообще меня убивают. Для того что поднять температуру на 10 градусов в нормальном доме в течении получаса, нужно подорвать ядерну бомбу. Иначе трудно добыть столько энергии сразу.

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

Puhlyaviy пишет:
Вы делаете мне смешно. Вы врятли почуствуете разницу в 2-3 градуса. А темы о изменении температуры в течении суток вообще меня убивают. Для того что поднять температуру на 10 градусов в нормальном доме в течении получаса, нужно подорвать ядерну бомбу. Иначе трудно добыть столько энергии сразу.

термопроцессы очень медленны.... моя с Пухликом - согласен !!!!!!!!!!!!! :)

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

Puhlyaviy пишет:
Вы делаете мне смешно. Вы врятли почуствуете разницу в 2-3 градуса. А темы о изменении температуры в течении суток вообще меня убивают. Для того что поднять температуру на 10 градусов в нормальном доме в течении получаса, нужно подорвать ядерну бомбу. Иначе трудно добыть столько энергии сразу.

 ардуине хватит возможностей своих управлять термоядом ? 

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

Пухлявый, Вам хорошо - вам только сейчас смешно стало. Я вот уже с первого коммента ржу.

Про "вряд ли почуствуете разницу в 2-3 градуса" - не надо за меня, ага? Вы думаете - я знаю, я там выше про полградуса уже говорил.

Про изменение на 10 градусов за полчаса - это опять Ваша фантазия. Недельные/суточные таймеры придуманы с определённой целью и успешно используются вне зависимости от Вашего видения мира. :-)

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

Puhlyaviy пишет:
Вы делаете мне смешно. Вы врятли почуствуете разницу в 2-3 градуса. А темы о изменении температуры в течении суток вообще меня убивают. Для того что поднять температуру на 10 градусов в нормальном доме в течении получаса, нужно подорвать ядерну бомбу. Иначе трудно добыть столько энергии сразу.

моя думал чота, что коллаИдером управляет Ардуинка..... блиииииииииииииин :(

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

SU-27-16 пишет:

Puhlyaviy пишет:
Вы делаете мне смешно. Вы врятли почуствуете разницу в 2-3 градуса. А темы о изменении температуры в течении суток вообще меня убивают. Для того что поднять температуру на 10 градусов в нормальном доме в течении получаса, нужно подорвать ядерну бомбу. Иначе трудно добыть столько энергии сразу.

 ардуине хватит возможностей своих управлять термоядом ? 


Лехко. Нужно еще несколько dht22 и сервоприводы ингоидиенты в кастрюльку подкидывать и помешивать

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Таймеры придуманы как маркетинг. На практике они не работают. Личный опыт и физика не согласна м вашими фантазиями.

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

vlad219i пишет:

Про изменение на 10 градусов за полчаса - это опять Ваша фантазия. Недельные/суточные таймеры придуманы с определённой целью и успешно используются вне зависимости от Вашего видения мира. :-)

чо вы спорите-то ? Пухлик в душе очень добрый... Проект работает ! Спасибо !

Пухлик - переключись уже на мирные цели.... Или ты из "Правого....... " ?

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

SU-27-16 пишет:

 ардуине хватит возможностей своих управлять термоядом ? 

Замкнуть реле на детонаторе? Легко!

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

Ладно, предлагаю всем остаться при своих фантазиях. Я флейм не по теме ещё с фидошных времён не понимаю. Про всем вопросам - да, да, да-да-да, вы во всём совершенно правы, я абсолютно с Вами согласен.

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

Dixi.

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

JollyBiber пишет:

SU-27-16 пишет:

 ардуине хватит возможностей своих управлять термоядом ? 

Замкнуть реле на детонаторе? Легко!

 там ток управление реле этим - 200 А !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :)

Puhlyaviy
Puhlyaviy аватар
Offline
Зарегистрирован: 22.05.2013

Я не спорю. Я делюсь опытом. Мой опыт базируется на нескольких сотнях клиентов которых интересовал вопрос какого хрена такой дорогой термостат не делает как в проспекте написано. Ака по расписанию температуру меняет... а оно тупо не успевало... :)

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

vlad219i пишет:

Пользуйтесь, кому интересно.

спасибо :)

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

Puhlyaviy пишет:
Я не спорю. Я делюсь опытом. Мой опыт базируется на нескольких сотнях клиентов которых интересовал вопрос какого хрена такой дорогой термостат не делает как в проспекте написано. Ака по расписанию температуру меняет... а оно тупо не успевало... :)

исполнительное обогревающее устройство не успевало.... :(

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

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

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

Если же стены теплее воздуха в помещении и имеют температуру +26°C и выше, то не возникает необходимости перегревать и пересушивать воздух, догревая его до той же температуры, что и ограждающие поверхности. Ведь ему уже не нужно обогревать собой (веществом с наименьшей теплоемкостью) стены и людей - стены теплые сами по себе, а люди - получают от них тепло излучением. Таким образом, при теплых стенах, достаточной для ощущения комфорта в помещении является температура воздуха уже +18°C (она же и самая здоровая для легких человека!).

 

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

не понял - чемпионат никто не смотрит чоли ? :)

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

SU-27-16 пишет:

 там ток управление реле этим - 200 А !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :)

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