там ток управление реле этим - 200 А !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :)
В данном случае повторное замыкание реле вопрос несущественный )) Контакты расплавиться вряд-ли успеют, к этому моменту они уже будут в газообразном состоянии
аха ! и автомат надо при ядрёном взрыве держать на вытянутых руках.... чобы расплавленный металл не капал на казённое обмундирование !
...для реализации погодозависимого регулятора нужно либо иметь уличный термодатчик, заточенный под конкретный котёл (датчик стОит зачастую несуразных денег, да и вход для подключения этого датчика предусмотрен не в каждом котле), либо знать протокол, используемый при подключении оригинального терморегулятора с возможностью управления модулятором (такая возможность есть тоже не везде). В общем - покопав инет на эту тему, я остановился на комнатном термостате. Вопрос дыхания/телевизора/плиты решён установкой термодатчика в определённом месте помещения (в тени, вдали от шальных потоков воздуха, батарей и прочих катаклизмов).
Вкратце - я ж говорю, меня устраивает. Вариант с уличным датчиком наверняка во сто крат правильнее и экономичнее, но в моём случае room thermostat'а мне хватает за глаза. Елозить установкой температуры теплоносителя больше не приходится, ну и, к примеру, котёл реже включается, если солнце через окна подогревает дом, - дык этого я и добивался. :-)
Или вы меня не понимаете или заблуждаетесь.
1. Уличный датчик- тот же самый DS18B20, он не стОит несуразных денег.
2. Протокол нас не интересует- лезть в газовый котёл так глубоко даже опасно. Единственное ЛЕГАЛЬНОЕ место куда можно подключаться как раз и есть те самые контакты комнатного термостата.
А дальше всё просто - второй датчик на подачу котла, как температура достигла необходимого нам значения- выключяем, как упала ниже порога - включаем.
У меня два года у соседа работала Ардуина с блоком реле и ЖКИ шилдом на котле Junkrs Eurostar который по своей природе на минимуме регулятора не мог выдавать меньше 45-50 градусов, а его тёплый пол при этом становился горячим пока не сработают клапана на рейке, потом они отключались и когда снова включались - пол уже был ледяной. И так всё время колебания: холодный-горячий
Ардуина выключала котёл при 32 и снова включала при 28 (условно) Все клапана пола были НАВСЕГДА открыты! Регулировка вручную температура-гистерезис, стабильная температура в доме, сосед был доволен.
У меня у самого дома котёл с погодником- Junkers Cerapur, как лет 8 назад отрегулировал наклон графика так и работает. Клапана тёплого пола тоже сняты навсегда за ненадобностью
...для реализации погодозависимого регулятора нужно либо иметь уличный термодатчик, заточенный под конкретный котёл (датчик стОит зачастую несуразных денег, да и вход для подключения этого датчика предусмотрен не в каждом котле), либо знать протокол, используемый при подключении оригинального терморегулятора с возможностью управления модулятором (такая возможность есть тоже не везде). В общем - покопав инет на эту тему, я остановился на комнатном термостате. Вопрос дыхания/телевизора/плиты решён установкой термодатчика в определённом месте помещения (в тени, вдали от шальных потоков воздуха, батарей и прочих катаклизмов).
Вкратце - я ж говорю, меня устраивает. Вариант с уличным датчиком наверняка во сто крат правильнее и экономичнее, но в моём случае room thermostat'а мне хватает за глаза. Елозить установкой температуры теплоносителя больше не приходится, ну и, к примеру, котёл реже включается, если солнце через окна подогревает дом, - дык этого я и добивался. :-)
Или вы меня не понимаете или заблуждаетесь.
1. Уличный датчик- тот же самый DS18B20, он не стОит несуразных денег.
2. Протокол нас не интересует- лезть в газовый котёл так глубоко даже опасно. Единственное ЛЕГАЛЬНОЕ место куда можно подключаться как раз и есть те самые контакты комнатного термостата.
А дальше всё просто - второй датчик на подачу котла, как температура достигла необходимого нам значения- выключяем, как упала ниже порога - включаем.
У меня два года у соседа работала Ардуина с блоком реле и ЖКИ шилдом на котле Junkrs Eurostar который по своей природе на минимуме регулятора не мог выдавать меньше 45-50 градусов, а его тёплый пол при этом становился горячим пока не сработают клапана на рейке, потом они отключались и когда снова включались - пол уже был ледяной. И так всё время колебания: холодный-горячий
Ардуина выключала котёл при 32 и снова включала при 28 (условно) Все клапана пола были НАВСЕГДА открыты! Регулировка вручную температура-гистерезис, стабильная температура в доме, сосед был доволен.
У меня у самого дома котёл с погодником- Junkers Cerapur, как лет 8 назад отрегулировал наклон графика так и работает. Клапана тёплого пола тоже сняты навсегда за ненадобностью
ВСЁ ПРАВИЛЬНО ! но зачем плясать от t на улице ? через графики наклона ? проще от t в помещении.... НЕТ ?
Да можно делать все что угодно. Доктору вон для управления его отоплением нужно 11 датчиков и 12 реле и это еще не считая датчиков в каждой комнате, на улице. Главное что бы нравилось самому
Да можно делать все что угодно. Доктору вон для управления его отоплением нужно 11 датчиков и 12 реле и это еще не считая датчиков в каждой комнате, на улице. Главное что бы нравилось самому
Я переподсчитал - там уже за 20 датчиков зашкаливает. Китайцы уже сами скидку оптовую предлагают.
Уважаемый vlad219i отличный проект. Не обращайте внимание на скучающих теоретиков. Кто-то умничает без конструктива, а содеянное работает и приносит пользу. Если не возражаете, как автор, хочу повторить Вашу конструкцию, возможно внесу какие-то изменения применимо к своим задачам. Буду весьма благодарен, если пришлете на s-chuprin@mail.ru схему, скетч, описание, фото конструкции.
Собственно, в этой ветке есть всё, что Вы хотите. Свежий скетч - под спойлером в предыдущем сообщении, схему как таковую я не рисовал, но подключение периферии расписано в комментариях прямо в скетче. Повторяйте на здоровье, какие могут быть возражения...
ProMini прошитая как Uno, часики на ds3231, приемник 433мгц, релюшка, кнопки.
Дистанционный датчик:
ProMini ставшая Uno ), ds18b20, передатчик 433 мгц, индикатор от мертвого ксерокса, кнопка.
Когда делал тоже начитался теоретиков (пид, температура внутри-снаружи, теплопроводность стен и т.д.), забил на все это и сделал.
Функционал: дневная-ночная температура, дистанционный датчик (в случае поломки, работа от местного датчика), индикация режимов работы/ошибки, регулировка частоты отправки температуры с дист. датчика и кое-что по-мелочам.
Работает 2 года в паре с баксиком, полет нормальный - я доволен как слон. Вам посоветовал бы: часы 1307 заменить на 3231 (за 2 года убежали на ~2 минуты !), добавить watchdog.
P.S. Gigabyte к моему термостату никакого отношения не имеет, логотип был приклеен как альтернатива выбрасыванию в мусорную корзину :)
Уважаемый Stas046, Ваш проект мог бы заинтересовать многих практиков. К примеру на форуме termoportal, многие ищут варианты решений для автоматизации систем отопления. Многие самоделкины, изготовившие самостоятельно горелки Бабингтона для котлов отопления в поисках решений автоматизации. Если не жалко времени, опубликуйте код и схему. Так же буду благодарен, если пришлете мне на s-chuprin@mail.ru.
Давайте так. Здесь выкладывать не буду, ибо топик не о моем термостате, не этично как-то ). А раз хоть кому-то интересна моя "поделка", соберусь с силами и запилю на выходных свой топик.
Доброго времени суток. Не могу подвязать библиотеки. Можно архив со всеми использующимися библиотеками. Очень хочу повторить данный термостат. Заранее спасибо. мой адрес: sidorenkoz@mail.ru
In file included from sketch_oct26a.ino:12:0:
C:\Users\universe\Documents\Arduino\libraries\EEPROMex-master/EEPROMex.h:23:20: fatal error: EEPROM.h: No such file or directory
#include <EEPROM.h>
^
compilation terminated.
Ошибка компиляции.
Добрый день, коллеги по увлечению. В развитие темы предлагаю совместными усилиями доработать следующий проект. В наличии есть скетч термостата, который с определенной периодичностью замеряет комнатную, уличную и температуру воды котла. На управление котлом пока влияет 1-ый параметр. Есть три режима (ночной, утренний и дневной), время начала которых и температуры устанавливаются из меню с кнопок. Необходимая информация выводится на lcd1602. Что хотелось бы совместными силами доработать. Создать центральный блок управления с tft на 7 дюймов, который посредством nrf24l01 будет с определенной периодичностью получать информацию от термостата и выводить на экран.
Попытаюсь снова заинтересовать проблематикой. Составленная программа выполняет следующее. С определенной периодичностью считывает температуры с датчиков (в комнате раз в 30 сек., на улице раз в 3 мин., по воде пока еще не сделал). Программа проверяет на наличие грубых ошибок при считывании и учитывает фактор дунавения ветра и т.п. с целью исключения тактирования котла. На экран выводится текущая инфа - время, временной режим, комнатная и уличная температуры, а также факт включения котла. Устанавливаемые в меню программирования сведения о начале временных режимов и температур сохраняются в EEPROM. Программа может определять подключение новых датчиков температур, записывать их в EEPROM и присваивать им статус комнатного, уличного или водяного. Предлагаю рассмотреть возможные алгоритмы: 1) управления температурой нагрева котлом воды только через контакты для термостата; 2) обмена информацией между термостатом и центральным блоком посредством nrf24l01.
На самом деле я не ищу исполнителя. Потихоньку осваиваю все сам. Немного сделал. Без подключения к котлу программа работает уже 3 недели. Пока ни одного сбоя. Все функции работают нормально. Планирую на новогодних праздниках подключить термостат к котлу и проверить его в боевых условиях. Хотел бы услышать мнения и пожелания уважаемых форумчан, кто в данном вопросе понимает больше меня. Поэтому и написал в данной ветке.
Уважаемые форумчане. Предлагаю следующий подход к управлению температурой нагрева котлом воды для системы отопления без влезания внутрь котла, а использовать только стандартный разъем для подключения термостата. Штатной ручкой управления температурой нагрева воды устанавливаем мощность 3/4. При снижении температуры в комнате ниже установленного уровня, включается котел на нагрев. Однако при достижении воды на выходе из котла температуры в зависимости от уличной, котел выключается. При достижении температуры воды из котла ниже нижнего предела в зависимости от уличной котел включается. И так до тех пор, пока комнатная температура не достигнет установленной. Например уличная 0, вода котла 35-50; улица -10, вода 40-55; улица -20, вода 45-60.
1 ....... использовать только стандартный разъем для подключения термостата.
2. ....... Штатной ручкой управления температурой нагрева воды устанавливаем мощность 3/4.
3 ....... При снижении температуры в комнате ниже установленного уровня, включается котел на нагрев.
4. .....Однако при достижении воды на выходе из котла температуры в зависимости от уличной, котел выключается. При достижении температуры воды из котла ниже нижнего предела в зависимости от уличной котел включается. И так до тех пор, пока комнатная температура не достигнет установленной. Например уличная 0, вода котла 35-50; улица -10, вода 40-55; улица -20, вода 45-60.
1. И это очень правильно!
2. Вы не мощьность устанавливаете. Вы устанавливаете температуру подачи.
Мощьность котёл с модулируещей горелкой устанавливает и регулирует сам.
3. Если у вас температура в комнате упала ниже или поднялась выше необходимой
значит вы неправильно настроили погодозависимый регулятор ( из пункта 4 ), его график .
Надо просто откорректировать.
И что значит температура в комнате?
В какой комнате? С северной? В южной? А люди там есть? А вентиляция работает?
Под потолком? У пола? У окна? Радиаторы? Тёплый пол? А солнце в окна светит?
Везде разная температура
4. И это очень правильно!
Я считал скользящее среднее по 10-ти измерениям раз в 10 секунд ( 100 секунд- цикл).
Это чтобы котёл часто не стартовалю
Ну и проблемма отключения насоса при управлении по клеммам комнатного термостата
через 3 минуты ( у Юнкерса) тоже присутствует: дёргал выход раз в две минуты
на время меньшее чем котёл успевал включить подачу газа .
Исправляюсь. Ручкой регулирую не мощность, а температуру теплоносителя. Не планирую управлять котлом с учетом температуры в каждом помещении дома. С учетом проведенных наблюдений температура во всех помещениях дома практически одинакова. Минимум от максимума отличается не более 1 градуса. Основная цель - поддержание температуры в помещениях с учетом времени суток. Утром потеплее, днем средняя, ночью попрохладнее. Комнатный датчик будет располагаться в помещении 40 кв.м., а именно в центре на расстоянии 1,5 м. от пола (имеется возможность), большая стена которой на северной стороне.
По поводу температуры теплоносителя это я примерно указал. А так полагаю, надо этой зимой котел поставить в ручной режим (ручку температуры теплоносителя крутить в зависимости от уличной температуры) и записывать все параметры на sd-карту.
У меня у соседа такой. Действительно простейший агрегат... Всё просит сделать подобное.
Но проще котёл на конденсатный поменять. Сразу с погодником
Другому соседу на Юнкерсе регулировал именно тепературу подачи измеряя её Далласом на трубе и включая-выключая котёл.
Помню 25-35 градусов были пределы температуры.
У него была проблемма в том что Евролайн не может выдавать меньше 50-ти , а для тёплого пола это полный перебор.
Делал быстро и просто так как не сделал никакого мощьного меню настроек.
А погодник именно "крутит" ручку температуры, сам, по уличной температуре и графику.
У самого ночью и днём в будни снижаю на 1-2 градуса по часам.
Больше не надо, разгон полов пару часов длится.
Тоже планирую на новогодних праздниках даллас на трубу из котла ставить и записывать показания до середины весны. Летом датчик поставлю в гребенку и с учетом снятых показаний сделаю зависимость нагрева воды от уличной температуры. Хотя посещает мысль о целесообразности погодозависимости. Поставил температуры теплоносителя на 3/4 от максимума. А термостат сам включит.
Спасибо. Но мне кажется, что температура теплоносителя также зависит от качества утепления стен дома. Соответственно при -15° на улице для стены из пенобетона 40 см температуры теплоносителя достаточно будет 60°, а для той же стены с утеплителем к примеру 10 см. будет достаточно и 50° теплоносителя. Цифры конечно условные. Основным является,чтобы температура теплоносителя был достаточной для прогрева помещения при самой низкой температуре на улице. А если на улице вдруг потеплеет, то в помещении температура начнет подниматься и термостат выключит котел. Вопрос - какой будет выгода с использованием термостата поддерживать заданную температуру в помещении при нагреве теплоносителя до более высокой температуры.
Если на улице потеплеет то котёл не выключится, а станет давать меньшую температуру согласно графика.
И как раз настройкой точек графика вы получите стабильную температуру внутри.
Отключение- это точка А на графике.
У меня дома 12 выставлено.
В комнатах практически стабильно 20-21
Из реальных многолетних данных при "0" подача = 30-35, при "-20" = 40-45
В тёплый пол подача идёт 27 при 0 и 33-35 при -20
Там где радиаторы- они заменены на " гигантский" размер. Сколько влазило- двухметровые.
Поэтому они и эффективны при низкой температуре теплоносителя.
Что очень хорошо для работы конденсатного котла.
Trembo, посоветуйте, пжл. Есть помещение размерами 8×5 м, состоящее из зоны кухни 3,5×3 м и зала. В зоне кухни висит котел. Грубо говоря, посередине этого помещения располагается несущий металлический столб, от которого до радиаторов, плиты и котла не мене 3-х метров. Думаю, на этом столбе повесить датчик комнатной температуры. Сама температура столба будет влиять на показания от датчика? А то когда рукой дотрагиваешься до него, кажется прохладным. Сам столб стоит на теплой основе.
не понял - чемпионат никто не смотрит чоли ? :)
Да кому он нужен. У них там даже ни одной ардуино нет.
там ток управление реле этим - 200 А !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! :)
В данном случае повторное замыкание реле вопрос несущественный )) Контакты расплавиться вряд-ли успеют, к этому моменту они уже будут в газообразном состоянии
аха ! и автомат надо при ядрёном взрыве держать на вытянутых руках.... чобы расплавленный металл не капал на казённое обмундирование !
...для реализации погодозависимого регулятора нужно либо иметь уличный термодатчик, заточенный под конкретный котёл (датчик стОит зачастую несуразных денег, да и вход для подключения этого датчика предусмотрен не в каждом котле), либо знать протокол, используемый при подключении оригинального терморегулятора с возможностью управления модулятором (такая возможность есть тоже не везде). В общем - покопав инет на эту тему, я остановился на комнатном термостате. Вопрос дыхания/телевизора/плиты решён установкой термодатчика в определённом месте помещения (в тени, вдали от шальных потоков воздуха, батарей и прочих катаклизмов).
Вкратце - я ж говорю, меня устраивает. Вариант с уличным датчиком наверняка во сто крат правильнее и экономичнее, но в моём случае room thermostat'а мне хватает за глаза. Елозить установкой температуры теплоносителя больше не приходится, ну и, к примеру, котёл реже включается, если солнце через окна подогревает дом, - дык этого я и добивался. :-)
Или вы меня не понимаете или заблуждаетесь.
1. Уличный датчик- тот же самый DS18B20, он не стОит несуразных денег.
2. Протокол нас не интересует- лезть в газовый котёл так глубоко даже опасно. Единственное ЛЕГАЛЬНОЕ место куда можно подключаться как раз и есть те самые контакты комнатного термостата.
А дальше всё просто - второй датчик на подачу котла, как температура достигла необходимого нам значения- выключяем, как упала ниже порога - включаем.
У меня два года у соседа работала Ардуина с блоком реле и ЖКИ шилдом на котле Junkrs Eurostar который по своей природе на минимуме регулятора не мог выдавать меньше 45-50 градусов, а его тёплый пол при этом становился горячим пока не сработают клапана на рейке, потом они отключались и когда снова включались - пол уже был ледяной. И так всё время колебания: холодный-горячий
Ардуина выключала котёл при 32 и снова включала при 28 (условно) Все клапана пола были НАВСЕГДА открыты! Регулировка вручную температура-гистерезис, стабильная температура в доме, сосед был доволен.
У меня у самого дома котёл с погодником- Junkers Cerapur, как лет 8 назад отрегулировал наклон графика так и работает. Клапана тёплого пола тоже сняты навсегда за ненадобностью
не понял - чемпионат никто не смотрит чоли ? :)
ЕСТЬ ! в каждом мячике ! ....для системы ТЕЛЕГОЛ ! :)
...для реализации погодозависимого регулятора нужно либо иметь уличный термодатчик, заточенный под конкретный котёл (датчик стОит зачастую несуразных денег, да и вход для подключения этого датчика предусмотрен не в каждом котле), либо знать протокол, используемый при подключении оригинального терморегулятора с возможностью управления модулятором (такая возможность есть тоже не везде). В общем - покопав инет на эту тему, я остановился на комнатном термостате. Вопрос дыхания/телевизора/плиты решён установкой термодатчика в определённом месте помещения (в тени, вдали от шальных потоков воздуха, батарей и прочих катаклизмов).
Вкратце - я ж говорю, меня устраивает. Вариант с уличным датчиком наверняка во сто крат правильнее и экономичнее, но в моём случае room thermostat'а мне хватает за глаза. Елозить установкой температуры теплоносителя больше не приходится, ну и, к примеру, котёл реже включается, если солнце через окна подогревает дом, - дык этого я и добивался. :-)
Или вы меня не понимаете или заблуждаетесь.
1. Уличный датчик- тот же самый DS18B20, он не стОит несуразных денег.
2. Протокол нас не интересует- лезть в газовый котёл так глубоко даже опасно. Единственное ЛЕГАЛЬНОЕ место куда можно подключаться как раз и есть те самые контакты комнатного термостата.
А дальше всё просто - второй датчик на подачу котла, как температура достигла необходимого нам значения- выключяем, как упала ниже порога - включаем.
У меня два года у соседа работала Ардуина с блоком реле и ЖКИ шилдом на котле Junkrs Eurostar который по своей природе на минимуме регулятора не мог выдавать меньше 45-50 градусов, а его тёплый пол при этом становился горячим пока не сработают клапана на рейке, потом они отключались и когда снова включались - пол уже был ледяной. И так всё время колебания: холодный-горячий
Ардуина выключала котёл при 32 и снова включала при 28 (условно) Все клапана пола были НАВСЕГДА открыты! Регулировка вручную температура-гистерезис, стабильная температура в доме, сосед был доволен.
У меня у самого дома котёл с погодником- Junkers Cerapur, как лет 8 назад отрегулировал наклон графика так и работает. Клапана тёплого пола тоже сняты навсегда за ненадобностью
ВСЁ ПРАВИЛЬНО ! но зачем плясать от t на улице ? через графики наклона ? проще от t в помещении.... НЕТ ?
котёл + батареи + тёплПол = система ( типа конденсатор )
но котёл мона включить на 5 сек, или на 45 сек - тот же самый ШИМ
Мощность, передавемая из дома на улицу, зависит от разности температуры внутри и снаружи.
Коэффицент теплопроводности материалов измеряется в Ваттах на квадратный метр на ГРАДУС!!!!!
t на улице очень полезно водяных систем отопления, в виду их большой инерционости.
это Вы, наверное, про теплопотери ?
Пробовал даже ПИД, но сделал проще: уставка-гистерезис, цикл 3 минуты, ограничение минимального времени включения(секунд 20 вроде)
это Вы, наверное, про теплопотери ?
Да, именно они, мы как раз их и компенсируем сжигая газ......
сама по себе - НЕТ !
а вот связка t-улица и t-помещение - ДА
если делать ПИД-регулятор t-помещения.....
нет смысла, проще среднее считать с интервалом секунд 10 и так раз 20-30
Да можно делать все что угодно. Доктору вон для управления его отоплением нужно 11 датчиков и 12 реле и это еще не считая датчиков в каждой комнате, на улице. Главное что бы нравилось самому
Если хочется понастраивать ПИД- забавненькие ссылки:
"Apply" надо нажимать при смене , я думаю вы теперь до утра будете коэффициенты подбирать ;)
http://kopterovod.ru/o-pid-regulyatorax-zamolvite-slovo/
http://kopterovod.ru/i-eshhe-o-pid-regulyatorax/
Для второго линка - коптера, ответы
P=0.2
I=0.005
D=0.1
http://habrahabr.ru/post/227425/
Ну тогда подбирайте, удачи
Ну тогда подбирайте, удачи
Дык это, у нас ничего не падало. У кого упало, тот пусть и подбирает.
Я переподсчитал - там уже за 20 датчиков зашкаливает. Китайцы уже сами скидку оптовую предлагают.
Добрый день!
подскажите пожалуйста, работает ли данный термостат на охлаждение?
если нет, прошу, подскажите какую часть кода и как поменять! спасибо!
Спасибо!
есть проблемка, иногда перестает крутить энкодер пока не пезагрузишь ардуину. Были у кого такие траблы?
Про энкодер - да, был косяк в коде, в части обработки энкодера. Обновленный, допиленный и исправленный скетч - под спойлером.
/* Суточный термостат для котла Baxi Mainfour 240F >Encoder control >DS18B20 thermal sensor >LCD1602 parallel >DS1307 RTC */ //#include <avr\eeprom.h> #include <Wire.h> // i2c (для RTC) #include <RealTimeClockDS1307.h> // RTC #include <EEPROMex.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 180 //минимальная пауза между включениями горелки, сек 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; // структура для суточных таймеров (8 байт) struct buffer_template { byte Hours; byte Minutes; float Temperature; boolean Enabled; boolean Activated; }; buffer_template Timer[4] = { 0, 0, 23.0, false, false}; //объявление 4-х суточных таймеров и их начальные значения 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 EEMEM float TstatTempEE; //EE температура термостатирования EEMEM float TemperatureCorrEE; // EE коррекция температуры EEMEM float HysteresisEE; // EE гистерезис EEMEM boolean BeepEnabledEE; // EE признак разрешения звука EEMEM float AlarmTempEE; // EE значение недопустимого снижения температуры EEMEM buffer_template TimerEE[4]; // EE структуры для 4 суточных таймеров // ===== 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 EEPROM.setMaxAllowedWrites(32767); if ((digitalRead(encoderK)) == 0) { // если первая запись однокристалки (зажата кнопка при включении питания)- записать начальные значения в EE lcd.setCursor(0, 0); //инфо на LCD lcd.print(F("Cold start...")); for (int i=0; i<4; i++) { // Timer[i].Hours = Timer[i].Minutes = 0; // Timer[i].Temperature = 23.0; // Timer[i].Enabled = Timer[i].Activated = false; EEPROM.updateBlock(int(&TimerEE[i]), Timer[i]); } EEPROM.updateFloat(int(&TstatTempEE), TstatTemp); EEPROM.updateByte(int(&BeepEnabledEE), BeepEnabled); EEPROM.updateFloat(int(&TemperatureCorrEE), TemperatureCorr); EEPROM.updateFloat(int(&HysteresisEE), Hysteresis); EEPROM.updateFloat(int(&AlarmTempEE), AlarmTemp); tone(BeepPin,2000,50); delay(50); tone(BeepPin,3000,50); delay(50); tone(BeepPin,4000,50); delay(1000); } lcd.clear(); lcd.setCursor(0, 0); //инфо на LCD lcd.print(F("Read settings...")); BeepEnabled = EEPROM.readByte(int(&BeepEnabledEE)); TstatTemp = EEPROM.readFloat(int(&TstatTempEE)); TemperatureCorr = EEPROM.readFloat(int(&TemperatureCorrEE)); Hysteresis = EEPROM.readFloat(int(&HysteresisEE)); AlarmTemp = EEPROM.readFloat(int(&AlarmTempEE)); for (int i=0; i<4; i++) { EEPROM.readBlock(int(&TimerEE[i]), Timer[i]); } DS18B20.begin(); DS18B20.getAddress(DS18B20Address, 0); DS18B20.setResolution(DS18B20Address, 12); DS18B20.setWaitForConversion(false); DS18B20.requestTemperatures(); tone(BeepPin,4000,50); delay(100); tone(BeepPin,4000,50); delay(1000); lcd.clear(); RTC.start(); } // ===== 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); // значок градуса // если таймер включен - надпись светится, если сработал - мигает, обрабатываем все 4 таймера lcd.setCursor(0, 1); //инфо на LCD for (int i=0;i<4;i++){ if ((Timer[i].Enabled)&!((Timer[i].Activated)&(blink500ms))) { lcd.print(F("T")); lcd.print(i+1); } 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.readFloat(int(&TstatTempEE)) != TstatTemp)&(Seconds == 0)) { EEPROM.updateFloat(int(&TstatTempEE), TstatTemp); } // проверка таймеров и изменение уставки термостата при совпадении for (int i=0;i<4;i++) { if ((Hours == Timer[i].Hours)&(Minutes == Timer[i].Minutes)&(Timer[i].Enabled)&(Seconds == 0)) { // время T совпадает с RTC Timer[0].Activated = Timer[1].Activated = Timer[2].Activated = Timer[3].Activated = false; Timer[i].Activated = true; TstatTemp = Timer[i].Temperature; EEPROM.updateFloat(int(&TstatTempEE), TstatTemp); if (BeepEnabled) { tone(BeepPin,4000,5); } break; // это чтобы статус Activated остался взведённым } } // дебаг-инфо - в терминал #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; Timer[0].Activated = Timer[1].Activated = Timer[2].Activated = Timer[3].Activated = 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 > 9 ) { menuitem = 0; } // границы пунктов меню if ( menuitem < 0 ) { menuitem = 9; } 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.TIMER4 SET ")); break; case 5: lcd.print(F("5.CLOCK SET ")); break; case 6: lcd.print(F("6.HYSTERESIS SET")); break; case 7: lcd.print(F("7.T-CORRECT SET ")); break; case 8: lcd.print(F("8.SOUND SET ")); break; case 9: lcd.print(F("9.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: TimerXSetup(0); break; // case 1 out // ====== пункт 2 - установка Timer2 case 2: TimerXSetup(1); break; // case 2 out // ====== пункт 3 - установка Timer3 case 3: TimerXSetup(2); break; // case 3 out // ====== пункт 4 - установка Timer4 case 4: TimerXSetup(3); break; // case 4 out // ====== пункт 5 - установка RTC case 5: 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(); RTC.start(); } else { if (BeepEnabled) { tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO" } } } else { if (BeepEnabled) { tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO" } } break; // case 5 out // ====== пункт 6 - установка гистерезиса case 6: 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.updateFloat(int(&HysteresisEE), Hysteresis); // запись в ЕЕПРОМ if (BeepEnabled) { tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES" } } else { Hysteresis = HysteresisOld; 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("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.updateFloat(int(&TemperatureCorrEE), TemperatureCorr); // запись в ЕЕПРОМ if (BeepEnabled) { tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES" } } else { TemperatureCorr = EEPROM.readFloat(int(&TemperatureCorrEE)); if (BeepEnabled) { tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO" } } break; // case 7 out // ====== пункт 8 - вкл/выкл звука case 8: 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.updateByte(int(&BeepEnabledEE), BeepEnabled); } if (MenuTimeoutTimer == 0) { BeepEnabled = EEPROM.readByte(int(&BeepEnabledEE)); } break; // case 8 out // ====== пункт 9 - установка предупреждалки о холоде case 9: 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.updateFloat(int(&AlarmTempEE), AlarmTemp); // запись в ЕЕПРОМ if (BeepEnabled) { tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES" } } else { AlarmTemp = EEPROM.readFloat(int(&AlarmTempEE)); if (BeepEnabled) { tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO" } } break; // case 9 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("]")); } } // ============================ 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 --; // ежесекундный декремент этого таймера } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ void TimerXSetup(int X) { MenuTimeoutTimer = 10; //таймер таймаута, секунд lcd.clear(); lcd.setCursor(0, 0); //инфо на LCD lcd.print(F("SETUP TIMER")); lcd.print(X+1); // выводим номер таймера на LCD delay(200); Hours=Timer[X].Hours; Minutes=Timer[X].Minutes; SetYesNo = false; PrintYesNo = true; SetTime(0,1); // в позиции 0,1 - запрос ввода времени if (MenuTimeoutTimer != 0) { if (SetYesNo) // если при установке времени выбрано "Yes" { if (BeepEnabled) { tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES" } Timer[X].Hours = Hours; Timer[X].Minutes = Minutes; Timer[X].Enabled = true; EEPROM.updateBlock(int(&TimerEE[X]), Timer[X]); MenuTimeoutTimer = 10; //таймер таймаута, секунд lcd.clear(); lcd.setCursor(0, 0); //инфо на LCD lcd.print(F("Timer")); lcd.print(X+1); lcd.print(F(" Temp. Set")); delay(200); do { lcd.setCursor(0,1); if (blink500ms) { lcd.print(F(" ")); } else { lcd.print(Timer[X].Temperature, 1); lcd.write(0x02); // значок градуса } rotating = true; // reset the debouncer if (encoderR) { Timer[X].Temperature += 0.1; encoderR = false; } if (encoderL) { Timer[X].Temperature -= 0.1; encoderL = false; } Timer[X].Temperature = constrain(Timer[X].Temperature, 10, 35); // крайние значения } while ((digitalRead(encoderK)==1)|(MenuTimeoutTimer==0)); if (MenuTimeoutTimer != 0) { // если после выбора температуры нажата кнопка энкодера EEPROM.updateBlock(int(&TimerEE[X]), Timer[X]); if (BeepEnabled) { tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES" } } else { // если не нажата - используем старую температуру EEPROM.readBlock(int(&TimerEE[X]), Timer[X]); if (BeepEnabled) { tone(BeepPin,BeepToneYes,BeepToneYesDuration); //звук "YES" } } } else // если при установке времени выбрано "No" { if (BeepEnabled) { tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO" } EEPROM.readBlock(int(&TimerEE[X]), Timer[X]); Timer[X].Enabled = false; EEPROM.updateBlock(int(&TimerEE[X]), Timer[X]); } } else { if (BeepEnabled) { tone(BeepPin,BeepToneNo,BeepToneNoDuration); //звук "NO" } } } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~````Уважаемый vlad219i отличный проект. Не обращайте внимание на скучающих теоретиков. Кто-то умничает без конструктива, а содеянное работает и приносит пользу. Если не возражаете, как автор, хочу повторить Вашу конструкцию, возможно внесу какие-то изменения применимо к своим задачам. Буду весьма благодарен, если пришлете на s-chuprin@mail.ru схему, скетч, описание, фото конструкции.
Собственно, в этой ветке есть всё, что Вы хотите. Свежий скетч - под спойлером в предыдущем сообщении, схему как таковую я не рисовал, но подключение периферии расписано в комментариях прямо в скетче. Повторяйте на здоровье, какие могут быть возражения...
Благодарю Вас за ответ. Приступаю к реализации.
Подобный термостат работает 2 года и у меня.
ProMini прошитая как Uno, часики на ds3231, приемник 433мгц, релюшка, кнопки.
Дистанционный датчик:
ProMini ставшая Uno ), ds18b20, передатчик 433 мгц, индикатор от мертвого ксерокса, кнопка.
Когда делал тоже начитался теоретиков (пид, температура внутри-снаружи, теплопроводность стен и т.д.), забил на все это и сделал.
Функционал: дневная-ночная температура, дистанционный датчик (в случае поломки, работа от местного датчика), индикация режимов работы/ошибки, регулировка частоты отправки температуры с дист. датчика и кое-что по-мелочам.
Работает 2 года в паре с баксиком, полет нормальный - я доволен как слон. Вам посоветовал бы: часы 1307 заменить на 3231 (за 2 года убежали на ~2 минуты !), добавить watchdog.
P.S. Gigabyte к моему термостату никакого отношения не имеет, логотип был приклеен как альтернатива выбрасыванию в мусорную корзину :)
Уважаемый Stas046, Ваш проект мог бы заинтересовать многих практиков. К примеру на форуме termoportal, многие ищут варианты решений для автоматизации систем отопления. Многие самоделкины, изготовившие самостоятельно горелки Бабингтона для котлов отопления в поисках решений автоматизации. Если не жалко времени, опубликуйте код и схему. Так же буду благодарен, если пришлете мне на s-chuprin@mail.ru.
Давайте так. Здесь выкладывать не буду, ибо топик не о моем термостате, не этично как-то ). А раз хоть кому-то интересна моя "поделка", соберусь с силами и запилю на выходных свой топик.
Доброго времени суток. Не могу подвязать библиотеки. Можно архив со всеми использующимися библиотеками. Очень хочу повторить данный термостат. Заранее спасибо. мой адрес: sidorenkoz@mail.ru
В частности не получается найти и привязать следующие библиотеки:#include <RealTimeClockDS1307.h> // RTC#include <EEPROMex.h> // EE#include <TimerOne.h> // прерывания по таймеру1Прошу помощи!
Получайте
https://github.com/davidhbrown/RealTimeClockDS1307
https://github.com/ryantenney/EEPROMex
https://github.com/PaulStoffregen/TimerOne
Да, представляю себе как вам тяжело без гугля жить....
Привязал эти библиотеки, но не понимает 2 библиотеки и пишет ошибку:
Arduino: 1.6.5 (Windows 7), Плата"Arduino/Genuino Uno"
Изменена опция сборки, пересобираем все
In file included from sketch_oct26a.ino:12:0:
C:\Users\universe\Documents\Arduino\libraries\EEPROMex-master/EEPROMex.h:23:20: fatal error: EEPROM.h: No such file or directory
#include <EEPROM.h>
^
compilation terminated.
Ошибка компиляции.
Никогда не сталкивался с такой проблемой, всегда удачно подвязывались библиотеки.
1. Закрыть и снова открыть ИДЕ после копирования библиотек
2. Инклюд этих библиотек из верхнего меню имеется?
3. Примеры от библиотек работают?
1. Закрывал и открывал вновь и не один раз.
2. Инклуд работает, но эти две библиотеки не светятся жёлтым цветом при инклюде.
3. Пример от библиотеки часов реального времени компилируется, а от EEPROMex компилируется с ошибками.
EEPROMex.h:23:20: fatal error: EEPROM.h: No such file or directory
У вас не стоит библиотека EEPROM.h.......
А EEPROMex.h хочет её в 23 строке инклюдить.....
Или вот здесь почитайте https://forum.pjrc.com/threads/24589-Another-library-fails-to-compile%E2...
Добрый день, коллеги по увлечению. В развитие темы предлагаю совместными усилиями доработать следующий проект. В наличии есть скетч термостата, который с определенной периодичностью замеряет комнатную, уличную и температуру воды котла. На управление котлом пока влияет 1-ый параметр. Есть три режима (ночной, утренний и дневной), время начала которых и температуры устанавливаются из меню с кнопок. Необходимая информация выводится на lcd1602. Что хотелось бы совместными силами доработать. Создать центральный блок управления с tft на 7 дюймов, который посредством nrf24l01 будет с определенной периодичностью получать информацию от термостата и выводить на экран.
Попытаюсь снова заинтересовать проблематикой. Составленная программа выполняет следующее. С определенной периодичностью считывает температуры с датчиков (в комнате раз в 30 сек., на улице раз в 3 мин., по воде пока еще не сделал). Программа проверяет на наличие грубых ошибок при считывании и учитывает фактор дунавения ветра и т.п. с целью исключения тактирования котла. На экран выводится текущая инфа - время, временной режим, комнатная и уличная температуры, а также факт включения котла. Устанавливаемые в меню программирования сведения о начале временных режимов и температур сохраняются в EEPROM. Программа может определять подключение новых датчиков температур, записывать их в EEPROM и присваивать им статус комнатного, уличного или водяного. Предлагаю рассмотреть возможные алгоритмы: 1) управления температурой нагрева котлом воды только через контакты для термостата; 2) обмена информацией между термостатом и центральным блоком посредством nrf24l01.
Попытаюсь снова заинтересовать проблематикой.
Думаю, что с таким развёрнутым ТЗ лучше обратиться сюда: http://arduino.ru/forumy/ishchu-ispolnitelya
На самом деле я не ищу исполнителя. Потихоньку осваиваю все сам. Немного сделал. Без подключения к котлу программа работает уже 3 недели. Пока ни одного сбоя. Все функции работают нормально. Планирую на новогодних праздниках подключить термостат к котлу и проверить его в боевых условиях. Хотел бы услышать мнения и пожелания уважаемых форумчан, кто в данном вопросе понимает больше меня. Поэтому и написал в данной ветке.
Уважаемые форумчане. Предлагаю следующий подход к управлению температурой нагрева котлом воды для системы отопления без влезания внутрь котла, а использовать только стандартный разъем для подключения термостата. Штатной ручкой управления температурой нагрева воды устанавливаем мощность 3/4. При снижении температуры в комнате ниже установленного уровня, включается котел на нагрев. Однако при достижении воды на выходе из котла температуры в зависимости от уличной, котел выключается. При достижении температуры воды из котла ниже нижнего предела в зависимости от уличной котел включается. И так до тех пор, пока комнатная температура не достигнет установленной. Например уличная 0, вода котла 35-50; улица -10, вода 40-55; улица -20, вода 45-60.
Например уличная 0, вода котла 35-50; улица -10, вода 40-55; улица -20, вода 45-60.
У какой у Вас котёл (марка, модель)?
1 ....... использовать только стандартный разъем для подключения термостата.
2. ....... Штатной ручкой управления температурой нагрева воды устанавливаем мощность 3/4.
3 ....... При снижении температуры в комнате ниже установленного уровня, включается котел на нагрев.
4. .....Однако при достижении воды на выходе из котла температуры в зависимости от уличной, котел выключается. При достижении температуры воды из котла ниже нижнего предела в зависимости от уличной котел включается. И так до тех пор, пока комнатная температура не достигнет установленной. Например уличная 0, вода котла 35-50; улица -10, вода 40-55; улица -20, вода 45-60.
1. И это очень правильно!
2. Вы не мощьность устанавливаете. Вы устанавливаете температуру подачи.
Мощьность котёл с модулируещей горелкой устанавливает и регулирует сам.
3. Если у вас температура в комнате упала ниже или поднялась выше необходимой
значит вы неправильно настроили погодозависимый регулятор ( из пункта 4 ), его график .
Надо просто откорректировать.
И что значит температура в комнате?
В какой комнате? С северной? В южной? А люди там есть? А вентиляция работает?
Под потолком? У пола? У окна? Радиаторы? Тёплый пол? А солнце в окна светит?
Везде разная температура
4. И это очень правильно!
Я считал скользящее среднее по 10-ти измерениям раз в 10 секунд ( 100 секунд- цикл).
Это чтобы котёл часто не стартовалю
Ну и проблемма отключения насоса при управлении по клеммам комнатного термостата
через 3 минуты ( у Юнкерса) тоже присутствует: дёргал выход раз в две минуты
на время меньшее чем котёл успевал включить подачу газа .
Котел - vitopend100.
Исправляюсь. Ручкой регулирую не мощность, а температуру теплоносителя. Не планирую управлять котлом с учетом температуры в каждом помещении дома. С учетом проведенных наблюдений температура во всех помещениях дома практически одинакова. Минимум от максимума отличается не более 1 градуса. Основная цель - поддержание температуры в помещениях с учетом времени суток. Утром потеплее, днем средняя, ночью попрохладнее. Комнатный датчик будет располагаться в помещении 40 кв.м., а именно в центре на расстоянии 1,5 м. от пола (имеется возможность), большая стена которой на северной стороне.
По поводу температуры теплоносителя это я примерно указал. А так полагаю, надо этой зимой котел поставить в ручной режим (ручку температуры теплоносителя крутить в зависимости от уличной температуры) и записывать все параметры на sd-карту.
У меня у соседа такой. Действительно простейший агрегат... Всё просит сделать подобное.
Но проще котёл на конденсатный поменять. Сразу с погодником
Другому соседу на Юнкерсе регулировал именно тепературу подачи измеряя её Далласом на трубе и включая-выключая котёл.
Помню 25-35 градусов были пределы температуры.
У него была проблемма в том что Евролайн не может выдавать меньше 50-ти , а для тёплого пола это полный перебор.
Делал быстро и просто так как не сделал никакого мощьного меню настроек.
А погодник именно "крутит" ручку температуры, сам, по уличной температуре и графику.
У самого ночью и днём в будни снижаю на 1-2 градуса по часам.
Больше не надо, разгон полов пару часов длится.
Тоже планирую на новогодних праздниках даллас на трубу из котла ставить и записывать показания до середины весны. Летом датчик поставлю в гребенку и с учетом снятых показаний сделаю зависимость нагрева воды от уличной температуры. Хотя посещает мысль о целесообразности погодозависимости. Поставил температуры теплоносителя на 3/4 от максимума. А термостат сам включит.
Не надо ничего записывать.
Посмотрите картинку на 3 странице http://www.gazeskatli.lv/documents/Junkers_TA211E_Rus.pdf
1. Когда при +10+5 мёрзнем (перегреваемся) точку С двигаем вверх(вниз)
2. Когда при -15 -20 мёрзнем (перегреваемся) точку Е двигаем вверх(вниз)
Спасибо. Но мне кажется, что температура теплоносителя также зависит от качества утепления стен дома. Соответственно при -15° на улице для стены из пенобетона 40 см температуры теплоносителя достаточно будет 60°, а для той же стены с утеплителем к примеру 10 см. будет достаточно и 50° теплоносителя. Цифры конечно условные. Основным является,чтобы температура теплоносителя был достаточной для прогрева помещения при самой низкой температуре на улице. А если на улице вдруг потеплеет, то в помещении температура начнет подниматься и термостат выключит котел. Вопрос - какой будет выгода с использованием термостата поддерживать заданную температуру в помещении при нагреве теплоносителя до более высокой температуры.
Да, зависит.
И эту зависимость вы выясните только когда сделаете регулятор.
И этот график регулятора под вашим полным контролем.
Основным является то что потери через теплоизоляцию зависят от разницы температур внутри-снаружи.
http://ostroymaterialah.ru/utepliteli/penoplast-2-sm-teploprovodnost.html
.......единица выражается в м² К / Вт и показывает, сколько тепла в Вт проходит через 1 м² площади стены или кровли заданной толщины за единицу времени при перепаде температур 1°К.
Если на улице потеплеет то котёл не выключится, а станет давать меньшую температуру согласно графика.
И как раз настройкой точек графика вы получите стабильную температуру внутри.
Отключение- это точка А на графике.
У меня дома 12 выставлено.
В комнатах практически стабильно 20-21
Из реальных многолетних данных при "0" подача = 30-35, при "-20" = 40-45
В тёплый пол подача идёт 27 при 0 и 33-35 при -20
Там где радиаторы- они заменены на " гигантский" размер. Сколько влазило- двухметровые.
Поэтому они и эффективны при низкой температуре теплоносителя.
Что очень хорошо для работы конденсатного котла.
Trembo, посоветуйте, пжл. Есть помещение размерами 8×5 м, состоящее из зоны кухни 3,5×3 м и зала. В зоне кухни висит котел. Грубо говоря, посередине этого помещения располагается несущий металлический столб, от которого до радиаторов, плиты и котла не мене 3-х метров. Думаю, на этом столбе повесить датчик комнатной температуры. Сама температура столба будет влиять на показания от датчика? А то когда рукой дотрагиваешься до него, кажется прохладным. Сам столб стоит на теплой основе.