там ток управление реле этим - 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-х метров. Думаю, на этом столбе повесить датчик комнатной температуры. Сама температура столба будет влиять на показания от датчика? А то когда рукой дотрагиваешься до него, кажется прохладным. Сам столб стоит на теплой основе.