GSM устройство управления котлами Webasto и не только

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Приветствую! Уже начал рисовать схему чтобы выложить её здесь для "ленивых" но Вы опередили! Что за программу используете для рисования?

Изменил в 115 строке время как Вы и советовали. Теперь всё ОК!

Пробежался по схеме нашёл косячёк - делитель напряжения для АКБ (R22 / R23). Всё остальное как будто в порядке.

И появился вопрос к Вам. После запуска приходит смс о том что котёл включился "Webasto ON" а следующей строчкой "StartWebasto FAIL" При этом я просто поставил перемычку +12В вых --- +12В сост.котла. Так и должно быть?

blades
Offline
Зарегистрирован: 21.11.2017

MaksVV пишет:

схема надеюсь нигде не накосячил. 

СПАСИБО! Так мне намного проще понять как там чего и зачем

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

uu5jhu пишет:

Приветствую! Уже начал рисовать схему чтобы выложить её здесь для "ленивых" но Вы опередили! Что за программу используете для рисования?

Изменил в 115 строке время как Вы и советовали. Теперь всё ОК!

Пробежался по схеме нашёл косячёк - делитель напряжения для АКБ (R22 / R23). Всё остальное как будто в порядке.

И появился вопрос к Вам. После запуска приходит смс о том что котёл включился "Webasto ON" а следующей строчкой "StartWebasto FAIL" При этом я просто поставил перемычку +12В вых --- +12В сост.котла. Так и должно быть?

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

2. Резисторы на схеме поправлю спасибо. 

3. Правильно, что поставили перемычку, с помощью неё устройство определяет наличие команды на включение котла, т.е. это показывает надпись "Webasto ON". А надпись "StartWebasto FAIL" показывает реальное состояние котла. В вашем варианте (запуск котла потенциалом, а также и для импульсного запуска) реальное состояние котла определяется по разнице температур улицы и выхлопа. Если разница больше установленной величины на момент отправки отчета - котел реально запустился и будет надпись  "StartWebasto OK" 

При запуске по протоколу W-BUS я хотел выуживать эту инфу по шине, но это пока не реализовано, т.к. не на чем потренироваться. 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

uu5jhu пишет:

Значит можно попробовать подключиться к шине используя Вашу схему!?

Сейчас уже схему не вспомню но кажется именно по этой шине котёл соединён с приборной панелью и имеет название i-bus а уже приборная панель с CAN шиной. 

вот попалась полезная инфа по вашей шине, которая отвечает на ваш вопрос. Ваша шина физически это тот же к-лайн (W-BUS). Настройки шины такие -  9600бит/сек, 8бит данных, бит четности even, 1 стоп бит. Значит да, можно использовать подключение к этой шине с помощью моего устройства по пину W-BUS. 

Каждый такой блок управления несёт свою функциональную нагрузку, будь то поддержание температуры салона, регулировка положения сидений, воспроизведение музыки и видео, навигация и прочее. Весь этот набор блоков управления должен взаимодействовать друг с другом, управляться с места водителя и пассажиров, передавать диагностические данные. Для этой цели и была разработана сеть I-bus. В последствии появилась технически идентичная сеть K-bus и их объединение I/K-bus.
Архитектура сети I-bus выполнена по схеме «общая шина», т. е. импульсы данных от узлов (блоков управления) передаются по обычному медному проводу соединённых в одной точке. Поэтому узлы должны делить общую среду передачи и передавать данные по очереди. Как определяется эта очередь или приоритетность я не знаю, полагаю просто прослушивается шина на наличие занятости и с учётом защитного интервала и незанятости шины принимается решение о передачи. В «молчаливом» состоянии уровень потенциала на шине относительно корпуса составляет от 7 В до напряжения питания автомобиля. При подаче доминантного бита в шину потенциал снижается до 2 В и ниже. Битовая скорость взаимодействия узлов постоянная и составляет 9600 бит/с. Цифра знакомая из UART. Но не только в скорости передачи имеются сходства, также формат символов в I-bus соответствует одной из вариаций доступных в UART. Символ состоит из 11 бит: стартовый бит, 8 бит данных, бит чётности, стоповый бит. Эти особенности позволяют физически подключаться к шине через интерфейсы UART или RS-232. Только необходимо позаботиться о преобразовании уровней сигнала с помощью простенькой схемы или готового преобразователя. Для этой цели вполне сойдёт k-line адаптер известный в диагностических интерфейсах. На физическом уровне они полностью совместимы. Я кстати им и пользуюсь.
Про физический уровень сети I-bus я в общем рассказал, теперь опишу кратко канальный уровень, это если следовать последовательности многоуровневой модели OSI. Так будет логичнее. Как я упомянул ранее, для передачи используется общая среда, которую надо делить по времени и передавать данные различным адресатам. Тут можно провести аналогию с Ethernet — данные передаются кадрами в которых содержится адрес отправителя, адрес получателя, полезная нагрузка (данные) и контрольная сумма. Кадр не имеет фиксированного размера и лежит в пределах 5 — 37 символов. Формат кадра я нарисовал ниже:

Здесь TX ID — адрес отправителя, 1 символ;
LEN — размер кадра с вычетом двух первых символов, 1 символ;
RX ID — адрес получателя, 1 символ;
DATA — полезная нагрузка, 1 — 33 символа;
CK SUM — контрольная сумма, 1 символ.

Корректность принятого кадра определяется символом контрольной суммы.

 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

Когда соберете моё устройство можно промониторить шину таким образом. Берете этот монитор порта. Замыкаете Reset ардуины на GND в собранном устройстве, подключаете к шине и компу через юсб. Настройки монитора порта на рис.

Lemur
Offline
Зарегистрирован: 11.01.2016

MaksVV огромное спасибо за такой труд, надеюсь сегодня поеду за вебастой и куплю, хотел уж было сам писать, а тут как говорится, на ловца и зверь бежит

в общем псмотрим, что да как, что добавлю - здесь выложу

по CAN вопрос то же интересен, надо на али платку заказать, канхакер сделать

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Доброго времени суток!

 

Пока что в K-Line так далеко не залазил. Лично не проверял но когда-то давно курил форум где говорили что например при помощи адаптера через диагностический разъём авто используя WTT к котлу не подключиться (нужно подключаться напрямую - так и делал). Вытягивать данные из шины (температуру ОЖ и пр) очень интересно было бы но пока что не совсем могу себе представить как ими (даже если вытянуть большое количество данных) воспользоваться или понять что и куда. При помощи своего адаптера (для диагностики авто) я например, могу узнать даже индекс шины, на котором сидит котёл (что возможно упрощает использование программы кархакер), но всё равно для меня пока что это тёмный лес - так базовые понятия из курса института о программировании, увы.

Вот выкладываю фото уже второго варианта собранного по Вашей схеме  для своих нужд! (организован только запуск потенциалом +12V без LM393 и пр). Делать ПП уже немного лениво для "5и" соединений да и модифицировать такой вариант проще.

 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

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

uu5jhu
Offline
Зарегистрирован: 21.11.2017

И да Вы правы - вот нашёл в интернете схему конкретно по своему авто (и им подобным) с подключением котла - соединяется он по K-Bus. Пока только нашёл свободную фишку в багажнике на которую можно прицепить Telestart (A128 приёмник Автономной системы отопления) и подцепил туда устройство собранное по Вашей статье! Доволен как слон!

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

Не кархакер, а CanHacker. Т.е им можно только шину CAN смотреть. К-BUS является по сути шиной к-лайн и посниффить canhacker ом у вас ее не получится. Как посниффить k-bus написано #105

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Да, не заметил - описался, имел в виду именно каНхакер (CanHacker)

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

uu5jhu пишет:
и подцепил туда устройство собранное по Вашей статье! Доволен как слон!


А что , уже заработало? ) что то я сомневаюсь , что там те же байты для запуска

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Telestert (которым можно дооснастить авто но не стану - GSM удобнее) запускает подачей +12V на пин 1 (6-и пинового разъма котла). Запускал пару раз именно так. W-bus пока не пробовал.

Единственное пожелание пока появилось это отправка смс по окончанию работы котла. И спящий режим тоже бы конечно хотелось бы иметь - сейчас устройство потребляет 36-38mA

uu5jhu
Offline
Зарегистрирован: 21.11.2017

MaksVV пишет:

Когда соберете моё устройство

 

 

Имеете в виду из поста #84?

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

uu5jhu пишет:
Имеете в виду из поста #84?

Нет, основовное из поста #1, просто по сути это и будет тоже самое что в посте #84, Замыкая Reset ардуино на Gnd, на сколько я знаю , встроенный юсб <-> уарт начинает работать "насквозь" на пины 1 и 0, при этом МК не работает и не важно какая там прошивка

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

uu5jhu пишет:

 запускает подачей +12V на пин 1 (6-и пинового разъма котла). Запускал пару раз именно так. W-bus пока не пробовал.

Единственное пожелание пока появилось это отправка смс по окончанию работы котла. И спящий режим тоже бы конечно хотелось бы иметь - сейчас устройство потребляет 36-38mA

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

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

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

сегодня у одного из первых двух пользователей подключили данный девайс к сигнализации starline E91. Честно говоря, проверить функции, касаемые подключения к сигнализации, на столе я не мог. Приятно был удивлен, что когда выполнили подключение и сделали все настройки, которые изначально были задуманы, всё заработало, СРАЗУ. Такого у меня никогда не было. А именно с ДЖСМ модуля: 

- запуск и останов ДВС.

- контроль работы ДВС, зажигания, состояния охраны, состояния тревоги. 

- запуск/останов котла от доп каналов сигнализации.

В таблице программирования AF сигнализации необходимо запрограммировать следующие функции (помечены красными галочками): Это всё справедливо для сигнализаций B94, D94, E90, E91. Для A94 будет немного отличаться, надо корректировать номера доп.каналов. 

Далее на доп.каналы настраиваем следующие события включения и задержки: 

CH-1:   T1-0;  T2-999; T3-0;  T4-0;  ЗП-06;  УО-0;  ОС-07;  УО-0;  dy-OF; db-On

CH-2:   T1-0;  T2-001; T3-0;  T4-0;  ЗП-01;  УО-0;  ОС-00;  УО-0;  dy-OF; db-ОF

CH-4:   T1-0;  T2-999; T3-0;  T4-0;  ЗП-13;  УО-0;  ОС-18;  УО-0;  dy-OF; db-On

CH-5:   T1-0;  T2-001; T3-0;  T4-0;  ЗП-01;  УО-0;  ОС-00;  УО-0;  dy-OF; db-ОF

CH-6:   T1-0;  T2-999; T3-0;  T4-0;  ЗП-10;  УО-0;  ОС-03;  УО-0;  dy-On; db-On

 

 

Wladislav_1
Offline
Зарегистрирован: 22.12.2016

Доброго времени суток! Чудо а не тема! Как раз сейчас поставили передо мной задачу сделать запуск вебасто с джисм, с вебастой и гидроником ни разу не сталкивался, разберусь не сомненно, но пока что может в двух словах объясните.... даласы 3 штуки что измеряют? у котла нет своих датчиков? какую все таки информацию получаем по Калине? или передаем? ну пока что все наверное... у меня задача впринципе проще надо запустить и желательно убедится что запущено, как запустить я так понял самый простой вариант подпаяться к кнопке через оптрон запускать... а как узнать что котел запустился? самый простой способ? 

P.S.

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

По поводу кондеров брал в магазине специально с температурными харрактеристиками от -60(есть от -85 но у нас в Новосибе нету?) только на заказ.

По поводу резета... не понял почему вы сделали через реле и по питанию? почему допустим не сделать резет ардуино через транзистор, а 800 чез оптрон и все это одновременно?

Да и по поводу питания 800 в инете много встречается варинт от питания 5вольт ставят два диода последовательно и все, я так не пробовал но простота подталкивает опробовать... может есть у кого опыт?

 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

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

Читайте внимательно всю тему. Там написано что есть котлы (универсальные Webasto termo top C, E, универсальные гидроники первые ), которые по аналогу запускаются - т.е. подачей 12В на определённый провод и по Калине, как вы выражаетесь, в данном случае ничего не передаём и не получаем. Убеждаемся что запущено в данном варианте по разнице температур улицы и выхлопа котла, если разница больше определённой величины - котёл стартанул успешно.

Есть может и попроще способ, но менее удобный. Взять штатный выход котла на включние отопителя, но он активируется при достижении t антифриза +30*C , а это не быстро и мы можем узнать что котёл например НЕ запустился, довольно поздно, когда уже ехать надо, неудобно. 

Котел я запускаю без оптрона, подпаиваюсь напрямую от порта ардуино к кнопке в штатном пульте. По крайней мере в вебастовском нет 12В когда не нажата, порт ардуино не горит. 

А есть котлы которые по цифровой шине запускаются W-BUS. По физическим свойствам это тот же К-лайн. Поэтому с W-Bus можно работать простым к-лайн адаптером. Т.к. такого котла у меня нет, я просто подслушал шину от штатного круглого таймера - что он шлёт для запуска котла в W-BUS и что для остановки. 

Т.е. таймер при запуске (а потом и при работе котла) периодически шлёт сообщения "Запуск" (а потом для поддержания связи то же сообщение) раз в 5 сек гдето. Для инициирования остановки котла таймер 5 раз отсылает сообщение "Стоп". Вот и весь алгоритм. Но это всё не проверено в реальных условиях, т.к. нету в пользовании котла с запуском по W-BUS типа Webasto TT EVO. Если кто попробует данный функционал на моем устройстве окажет неоценимую помощь проекту. 

Про реле. Проще в китае заказывать если время позволяет, готовые модули или мосфеты например. 

Ресет сим800 сделал по питанию потому что читал в нескольких местах, что через пин Reset не всегда получается привести в чувство gsm модуль. А ардуино зачем тоже перезагружать если она не зависла? Если всё же делать по питанию ресет, то не могу представить схему , когда транзистор будет разрывать питание и тем более оптрон, может нарисуете? 

Питание 4В от 5В через диоды врядли это будет надёжно. Но если вы попробуете, соберёте статистику что всё гуд, готов переделать печатную плату. А можно вооще не париться, такой модуль заказать , там уже сделано 4В диодами. И есть согласование уровней Tx Rx и антенна в комплекте. такто что DC - DC можно один ставить на 5V и всё. Заказал себе такой, придёт посмотрим. 

 

Wladislav_1
Offline
Зарегистрирован: 22.12.2016

Вот теперь понятно, что то не увидел вроде все читал, про датчик на выхлоп! Я так понимаю что он достаточно сильно нагреется не расплавятся ли провода? 

По поводу диодов на питание не пробовал и не хочу сам эксперементировать)))) но так вдруг у вас уже был опыт!_)))))

А по поводу запуска я так понял по вашей схеме что кнопка на пульте вебасто замыкает на минус? 

На счет запуска котла... я видел как вебасто после трех попыток запуститься переходила в режим ошибки... (допустим фильтр загадился) так вот при запусках она все равно зажигалась и выхлоп шел теплый т.е. датчик воспримет что котел запустился и отправит смс с ложной инфой? как то продумывали такой момент? какую паузу или какую температуру ставили?

по поводу потребления тока у меня получилось 25 мА как то решали вопрос? или нафиг?

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

Ahatolii
Offline
Зарегистрирован: 10.12.2017

Доброго времени суток. Классная статейка я давно думал тоже собрать что то похожее а тут вот оно готовое устройство.

Спасибо автору. Я вот хучу предложить, если команды в скейче оптимизировать под фирменную программу WEBASTO ThermoCall

эта программа тоже отправляет СМС сообщения. Как вы думаете?

Ahatolii
Offline
Зарегистрирован: 10.12.2017
MaksVV
Онлайн
Зарегистрирован: 06.08.2015

ок, попробую пошукать это приложение, что оно там отправляет. 

Ahatolii
Offline
Зарегистрирован: 10.12.2017

Да простое оно. НО используя это фирменное приложение я думаю будет очень круто!!!

Да и можно вас еще попросить если поправите прошивку под него дайте знать.

blades
Offline
Зарегистрирован: 21.11.2017

Планирую использовать только часть Ваших наработок, по сути только gsm реле. Т.е. Не нужны неидатчики температуры
, ни запуск двс. Отсюда следует что скетч можно сделать намного меньше, да и схему упростить. Нужно только управление включением/отключением, временем работы и отчет об успешности получения команды. Не силен в программировании, не подскажите что можно удалить и что нужно оставить?

Wladislav_1
Offline
Зарегистрирован: 22.12.2016

blades пишет:
Планирую использовать только часть Ваших наработок, по сути только gsm реле. Т.е. Не нужны неидатчики температуры , ни запуск двс. Отсюда следует что скетч можно сделать намного меньше, да и схему упростить. Нужно только управление включением/отключением, временем работы и отчет об успешности получения команды. Не силен в программировании, не подскажите что можно удалить и что нужно оставить?

вообще если не сильны то хочу посоветовать вам FLprog! и вперед в пределах этой програмы много чего сможете, а то так по сокращениям скетчей далеко не уйдете постоянно что то корректировать нужно или улучшать

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

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

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

Ahatolii пишет:

Да и можно вас еще попросить если поправите прошивку под него дайте знать.

берите исправляйте текст SMS - команд в прошивке , чтоб они соответсвовали командам с приложения и всё должно работать по идее. 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

Wladislav_1 пишет:

Вот теперь понятно, что то не увидел вроде все читал, про датчик на выхлоп! Я так понимаю что он достаточно сильно нагреется не расплавятся ли провода?

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

Wladislav_1 пишет:
А по поводу запуска я так понял по вашей схеме что кнопка на пульте вебасто замыкает на минус?

не по моей схеме. Это в штатном пульте Вебасто кнопка пуск замыкается на минус при нажатии. Вот к ней то мы и припаиваемся. Т.е. подавая "свой" минус, имитируем нажатие кнопки. 

Wladislav_1 пишет:
На счет запуска котла... я видел как вебасто после трех попыток запуститься переходила в режим ошибки... (допустим фильтр загадился) так вот при запусках она все равно зажигалась и выхлоп шел теплый т.е. датчик воспримет что котел запустился и отправит смс с ложной инфой? как то продумывали такой момент? какую паузу или какую температуру ставили?

контроль успешности запуска осуществляется через 6 мин, разница температур улицы и выхлопа настроена на 20 гр. (нужно кнонечно побольше сделать, т.к. выхлоп до 90...100 греется).  Если котел не стартанул то через 6 мин уже должен остыть выхлоп, даже если это не так, то правильной разницей температур в скетче можно добиться легко нужного результата

 

Wladislav_1 пишет:
по поводу потребления тока у меня получилось 25 мА как то решали вопрос? или нафиг?

по энергопотреблению ещё не решал. И это только для тех нужно, кто а/м больше чем на полмесяца оставляет без запусков ДВС. 

Wladislav_1 пишет:
и по поводу модулей что то пришли два модуля вставляю симку и ничего сеть не находит как то рпаньше не сталкивался с таким просто подавал питание ивставлял симку и все быстро поморгает и находит сеть и т.д. ну а дальше уже  ат командами ... сталкивались с такой проблемой?

питание хорошее обеспечьте и НЕ через бредборд китайскими мама-папами. Эти джсм модули капризны к качеству питания. 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

нашел ОЧЕНЬ нужный пост для развития данного проекта. Чел раскрыл алгоритм обмена ,я так понял,  обычного (для доп установки) котла Webasto termo Top C, который управляется просто плюсом, но при этом естественно имеет шину W-BUS для диагностики. Вот так можно вытягивать инфу от котла по цифре. Берём на вооружение.

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

а вот вам пожалуйста и протокол Webasto EVO  уже с запуском по цифре . Тоже нужная инфа, так можно и не имея котла всё наладить, всё за нас уже сделали). Правда здесь показан сниф связки : овальный таймер 1533 и котел EVO. И присмотревшись можно понять, что никакой полезной инфы в этом обмене нет, просто команды запуска и остановки, а между ними - команда поддержания связи раз в 15 секунд. Ну что ж, эта инфа нам тоже полезна, что при простом запуске котла EVO штатным таймером, никакой полезной инфы котел при этом не шлёт. 

Т.е. чтобы научиться вытаскивать полезную инфу - состояние пламени, температуры, напряжения (и т.д.) нам нужно также искать сниф связки вебасто EVO  и диагностики Termotest (как это сделано по ссылке в предыдущем посте для аналогового котла Termo top C)

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

собрал ещё один образец. плата v4 из сообщения #82. Теперь будет возможность проверить на столе скетч v2.2. Ардуины только кончились, вот жду. Как и планировал миниатюрное реле влезло между контактами GSM модуля и по высоте тоже ОК. Даже зазор небольшой есть.   

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

Добавил контроль зависания GSM модуля. Логика такая - каждые 30 мин ардуино шлет на GSM модуль команду "АТ" и начинает ждать ответ "ОК".  Если в течение 6 сек ответ не пришел - опять посылается "АТ". Если GSM модуль так и не ответил 5 раз - включается реле отключения питания GSM модуля на 6 сек (питание GSM висит на НЗ контактах реле и когда происходит ресет, включается реле на 6 сек, НЗ контакты размыкаются и питание пропадает на 6 сек). 

Скетч v 2.2 имеет ошибки и не работал должным образом. Вот скетч v2.3. с исправленными ошибками

#include <EEPROM.h>
#include <Button.h>

Button test;

// для GSM модуля *********************
#include <SoftwareSerial.h>
SoftwareSerial mySerial(14, 15); //Rx, Tx
//#define mySerial Serial 
String currStr = "";

String TelNumber1 = "000000000000";

String TelNumber2 = "000000000000";

String BufferNumber = "000000000000";

bool SaveNumber2 = 0;  // флаг когда необходима запись номера#2, он true

int isStringMessage = 0; 
int KTOzapros = 0;
int KTOreport = 1;
//************************


int Protocol = 1; // протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
                  // 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
                  // 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)

                  
//_______Все для цикла void voltmetr()*************
float vout = 0.0;      // Напряжение на входе аналового входа
float Vpit = 0.0;      // Измеряемое напряжение на выходе ИБП
  int volt = 0;        // Напряжение на входе АЦП

// входы выходы на соостветствующие пины **************
#define DopOn 4      // сюда доп канал от сигналки на включение вебасто
#define DopOff  5    // сюда доп канал от сигналки на выключение вебасто
#define VyhodWebasto  12     // это импульсный минусовой выход вкл/выкл вебасто к таймеру. 
#define VyhodWebastoAnalog  3  // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера). 
#define Sost  9      // Сюда состояние вебасто (+12В когда работает)

#define Ohrana  6      // Сюда состояние охраны сигналки
#define Trevoga  7      // Сюда состояние тревоги
#define StartEng 8   // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
#define IGN 10       // Сюда состояние зажигания
#define Eng 11       // Сюда состояние работы ДВС
#define ResetGSM 16       // пин ресета GSM (A2) подключен к реле, разрывающее питание модуля. 
#define StartButton 17       // пин тактовой кнопки (А3) вкл/выкл котла
#define StatusWebastoLED 13  // пин индикация включенности котла





// для шины 1-wire и датчиков DS18B20****************

#include <OneWire.h> // библиотека для DS18B20
OneWire ds(2); // датчики DS18B20 на 2 пин

byte VyhlopC[8] ={0x28, 0xFF, 0xE6, 0x14, 0x90, 0x15, 0x04, 0x62}; 
byte EngineC[8] ={0x28, 0xFF, 0x06, 0x15, 0x90, 0x15, 0x04, 0x37}; 
byte UlicaC[8] ={0x28, 0xFF, 0x43, 0x42, 0xA8, 0x15, 0x03, 0x2A};  
byte SalonC[8] ={0x28, 0xFF, 0xE0, 0x19, 0xA8, 0x15, 0x01, 0xA7};  
volatile int  TempVyhlopC = 20;
volatile int  TempEngineC = 20;
volatile int  TempUlicaC = 20;
volatile int  TempSalonC = 20;

// для организации W-BUS и различные таймеры********************
byte Zapusk20[5] = {0xF4,0x03, 0x20, 0x3B, 0xEC} ;
byte Zapusk21[5] = {0xF4,0x03, 0x21, 0x3B, 0xED} ;
byte Stop[4] = {0xF4,0x02, 0x10, 0xE6} ;

bool flagStartPresent = 1;               //флаг что отправляем в момент периодического поддержания связи W-Bus status или start
int StartMessageRepeat = 0;              //количество отправленных сообщений на старт котла
int StopMessageRepeat = 0;               //количество отправленных сообщений на остановку котла

unsigned long TimeWebasto = 1800000;   //время работы котла, 1800000 = 30мин
unsigned long EndReportMillis = 0;     //переменная для таймера отправки отчета об успешности запуска котла
unsigned long EndReportEngine = 0;     //переменная для таймера отправки отчета об успешности запуска ДВС
unsigned long Prev_PeriodW_BusMessage = 0;     //переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus 
unsigned long Prev_PeriodW_BusStartStop = 0;       //переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus 

//для таймера  - активация котла - импульс массы 0,8 сек на провод, впаянный в таймер вебасто)
unsigned long time, timer=0;
bool timerenabled=false;
#define TIMEREXPIRED (time-timer)>800


//для таймера  - старт двигателя - импульс +5В на оптопару, в итоге минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС)
unsigned long  timerStartEng=0; bool timerenabledStartEng=false;
#define TIMEREXPIRED_StartEng (millis()-timerStartEng)>1500


//для таймера  - старт котла по W-BUS )
unsigned long timerStart_W_BUS=0; bool timerenabledStart_W_BUS=false;
#define TIMEREXPIRED_Start_W_BUS (millis()-timerStart_W_BUS)> TimeWebasto 


//ниже всё для организации ресета GSM модуля, если с ним отсутствует свзяь

unsigned long  prevReset=0;      // для таймера периодичности проверки (командой "АТ")
int intervalReset = 30;          // каждые столько мин  будет ресет
unsigned long  timerWaitOK=0;    // для таймера ожидания ответа после посылки команды "АТ"
bool timerenabledWaitOK=false;   // для таймера ожидания ответа после посылки команды "АТ"
int errors=0;                    // количество неответов  от GSM модуля
bool gsmOK = 1;                  // флаг есть свяpь с GSM модулем или нет
bool resettimer = 0;             // для таймера удерживания реле в режиме сброс питания
unsigned long  resetTimer=0;     // для таймера удерживания реле в режиме сброс питания
int ResetNumber = 0;             //количество ресетов GSM модуля для статистики (хранится в еепром)

//**************************


//Основные переменные  
bool webasto = 0;            // состояние команды на работу Webasto. 0 - котел выключен, 1 - котел включен
bool startWebasto_OK = 0;    // состояние успешного запуска котла
bool report = false;      // состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
bool reportEngine = false;// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять

bool engine =0;    //флаг работает ли ДВС или нет
bool ignition=0;   //флаг включено ли зажигание или нет
bool ohrana=0;     //флаг включена ли охрана или нет
bool trevoga=0;    //флаг включена ли тревога или нет
bool alarmSMS = 0; //флаг отправлена ли смс о тревоге или нет





// СТАРТОВЫЙ ЦИКЛ
void setup() 
{
 delay (2500);

test.NO(); 
test.pullUp();
test.duration_bounce       (  50);
test.duration_click_Db     ( 250);
test.duration_inactivity_Up(5000);
test.duration_inactivity_Dn(1000);
test.duration_press        ( 500);
test.button(StartButton); // arduino pins connected to button
 
  WDTCSR=(1<<WDCE)|(1<<WDE); //для датчиков DS18B20
 
  WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0); // для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
  pinMode (DopOn,  INPUT);   digitalWrite (DopOn,  HIGH);
  pinMode (DopOff, INPUT);   digitalWrite (DopOff, HIGH);
  pinMode (Sost,   INPUT);   digitalWrite (Sost,   HIGH);
  pinMode (VyhodWebasto,  OUTPUT);  digitalWrite (VyhodWebasto,  HIGH);
  pinMode (VyhodWebastoAnalog,  OUTPUT);  digitalWrite (VyhodWebastoAnalog,  LOW);
  pinMode (StartEng,  OUTPUT);  digitalWrite (StartEng,  LOW);
  pinMode (StatusWebastoLED,     OUTPUT);  digitalWrite (StatusWebastoLED,     LOW);
  pinMode (ResetGSM,     OUTPUT);  digitalWrite (ResetGSM,    HIGH);

  pinMode (Ohrana, INPUT);  digitalWrite (Ohrana,  HIGH);
  pinMode (Trevoga, INPUT);  digitalWrite (Trevoga,  HIGH);
  pinMode (IGN, INPUT);  digitalWrite (IGN,  HIGH);
  pinMode (Eng, INPUT);  digitalWrite (Eng,  HIGH);
  
  
Serial.begin (2400, SERIAL_8E1);   // сериал соединение протокол W-Bus

mySerial.begin(19200);           // сериал соединение для gsm модуля


    delay(2000);

  NastroykaGSM ();

TimeWebasto = EEPROM.read(1)*60000UL;
Protocol = EEPROM.read(2);
ResetNumber = EEPROM.read(0);
for (int i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
for (int i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);

}


void loop() {
test.read();
digitalWrite (StatusWebastoLED, webasto);
//если нажали тактовую кнопку меняем состояние котла на противоположное 
if (test.event_click_Dn (StartButton)) {
  if (!webasto) {StartWebasto(); report = false;}
  else StopWebasto();
    }

if (Protocol!=2) {if (TempVyhlopC - TempUlicaC > 40) startWebasto_OK = 1;
                  else startWebasto_OK = 0;}

if (Protocol==1) webasto = !digitalRead (Sost);

if (Protocol==2) W_Bus();

//ниже для таймера старта котла по W-BUS и аналогу 
 
  if (timerenabledStart_W_BUS && TIMEREXPIRED_Start_W_BUS) StopWebasto();

//ниже для таймера создания импульса на старт ДВС 

if (timerenabledStartEng && TIMEREXPIRED_StartEng) {digitalWrite (StartEng, LOW); timerenabledStartEng=false;}
    
 engine =  !digitalRead (Eng);
 ignition= !digitalRead (IGN); 
 ohrana=   !digitalRead (Ohrana);  
 trevoga=  !digitalRead (Trevoga);
  
if (webasto && report) timerReport ();
if (reportEngine) timerReportEngine ();
if (trevoga && !alarmSMS) AlarmSMS ();
if (!ohrana) alarmSMS = false;

if (gsmOK)readSMS();
Reset_gsm();
voltmetr();
WebastoOprosImpulse ();


}

void voltmetr()  //____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП

{
   volt = analogRead(A7);                       // А7 аналоговый вход вольтметра
   vout = (volt * 4.92) / 1024;             
   Vpit = vout / (9950.0/(98930.0+9950.0));  // По формуле Vpit = vout / (R2/(R1+R2)) 
   if (Vpit<0.09)  Vpit=0.0;                  // Округление до нуля 
}






// Вектор прерывания для Dallas DS18B20
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.write(0xCC);//обращение ко всем датчикам
        ds.write(0x44);// начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(VyhlopC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempVyhlopC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempVyhlopC = TempVyhlopC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(EngineC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempEngineC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempEngineC = TempEngineC/16;
        ds.reset();
        ds.select(UlicaC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempUlicaC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempUlicaC = TempUlicaC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(SalonC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSalonC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempSalonC = TempSalonC/16 ;
}}




                    


void StartWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StartMessageRepeat = 0;
  webasto = 1; digitalWrite (VyhodWebastoAnalog, HIGH);
  timerStart_W_BUS=millis();
  timerenabledStart_W_BUS = true;}

  report = true; EndReportMillis = millis();
}

void StopWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StopMessageRepeat = 0;
  webasto = 0; digitalWrite (VyhodWebastoAnalog, LOW);
  timerenabledStart_W_BUS = false;}
   report = false;
}




void WebastoOprosImpulse (){

// опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла 
  time = millis();
  if (timerenabled) {if (TIMEREXPIRED) {digitalWrite (VyhodWebasto, HIGH); timerenabled=false;}}
  else  {if (!digitalRead (DopOn)  && !webasto) {StartWebasto(); KTOreport = 1;}
         if (!digitalRead (DopOff) && webasto) StopWebasto();
         }}


// цикл таймера отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
void timerReport () {
   if(millis() - EndReportMillis > 360000UL) 
   {EndReportMillis = millis(); report = false; SMSzapros();  }} 

// цикл таймера отправки отчета об успешности запуска ДВС  (отчёт через 30сек после старта)                       
void timerReportEngine () {
   if(millis() - EndReportEngine > 30000) 
   {EndReportEngine = millis(); reportEngine = false; SMSzapros();}} 





   void NastroykaGSM () {
      mySerial.print(F("AT+CMGF=1\r"));         //устанавливает текстовый режим смс-сообщения
    delay(200);
  mySerial.print(F("+IFC=1, 1\r"));       //устанавливает программный контроль потоком передачи данных
    delay(200);
  mySerial.print(F("AT+CPBS=\"SM\"\r"));    //открывает доступ к данным телефонной книги SIM-карты
    delay(200);
  mySerial.print(F("AT+GSMBUSY=1\r"));   //запрет всех входящих звонков
    delay(300);
  mySerial.print(F("AT+CNMI=1,2,2,1,0\r")); //включает оповещение о новых сообщениях
    delay(300);
  mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
}

void startNumber1SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
{
      mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
  mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber1); mySerial.println("\""); 
      delay(400);
}

void startNumber2SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber2); mySerial.println(F("\"")); 
      delay(400);
}

void startBufferNumberSMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(BufferNumber); mySerial.println(F("\"")); 
      delay(400);
}

void EndSMS ()
{
   mySerial.println((char)26);                       // Команда отправки СМС
   delay(3000);
   mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(1500);
}


void readSMS() //_____Цикл чтения входящих СМС-сообщений______________     
{
    if (!mySerial.available()) return;
    char currSymb = mySerial.read();
//  Serial.print (currSymb);
    if ('\r' == currSymb)
       {
         if (isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
                {
if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}               // Передача параметров по СМС
else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС



else if (!currStr.compareTo("Webasto-ON"))  { if (!webasto)  {StartWebasto ();  // если получили команду на включение и вебаста в настоящий момент выключена - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Webasto Vkluchena")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS(); 
                                                                        mySerial.println(F("Webasto uzhe vkluchena")); EndSMS();}}

                                                            
               else if (!currStr.compareTo("Webasto-OFF"))   {if (webasto){StopWebasto ();  // если получили команду на выключение и вебаста в настоящий момент включена - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Webasto Otkluchena")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS(); 
                                                                         mySerial.println(F("Webasto uzhe otkluchena")); EndSMS();}}          


                else if (!currStr.compareTo("Engine-ON"))  {if (!engine)  { digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = true; EndReportEngine = timerStartEng; // если получили команду на включение ДВС и он в настоящий момент выключен - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS();  KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Engine Start")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel uzhe rabotaet")); EndSMS();}}
                                                                                 
               else if (!currStr.compareTo("Engine-OFF"))   {if (engine){ digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = false; // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS();
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel ostanovlen")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS();
                                                                         mySerial.println(F("dvigatel uzhe ostanovlen")); EndSMS(); }}          
                                                    

               else if (!currStr.compareTo("Impulse"))   {Protocol = 1;  EEPROM.write(2,Protocol);     if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}}                                                               

               else if (!currStr.compareTo("W-BUS"))   {Protocol = 2; EEPROM.write(2,Protocol);  webasto = 0;  if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk W-BUS")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk W_BUS")); EndSMS();}}

               else if (!currStr.compareTo("Potenzial"))   {Protocol = 3; EEPROM.write(2,Protocol);   if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}} 

               
                else if (currStr.endsWith("min"))   {TimeWebasto = currStr.toInt()*60000UL; // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
               if (TimeWebasto>3540000UL) TimeWebasto = 3540000UL;
               if (TimeWebasto<=600000UL) TimeWebasto = 600000UL;
               EEPROM.write(1,TimeWebasto/60000UL);
                     if (isStringMessage == 1)startNumber1SMS(); 
               else  if (isStringMessage == 2) startNumber2SMS(); 
               mySerial.print(F("Webasto time: ")); mySerial.print(TimeWebasto/60000UL); mySerial.print(F("min")); EndSMS();}
               

               else if (!currStr.compareTo("ResetNumbers"))   {if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("Phone numbers are erased")); EndSMS(); 
                                                                     
             TelNumber1 = "000000000000"; TelNumber2 = "000000000000"; for (int i=0; i<12; i++) {EEPROM.write (i+10,  TelNumber1[i]); EEPROM.write (i+30,  TelNumber2[i]); }}}

              else if (!currStr.compareTo("WriteNumber2")&& isStringMessage == 1)   { 
                SaveNumber2 = 1; startNumber1SMS(); mySerial.println(F("Otpravte lyuboye SMS s nomera2 dlya sochraneniya nomera")); EndSMS();} 

                                                                        

                                                     
               else if (!currStr.compareTo("Balance"))    SMSbalance();
            isStringMessage = 0;
                }
              else if (isStringMessage==10){ if (!currStr.compareTo("WriteNumber1"))   { TelNumber1 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
              startNumber1SMS(); mySerial.println(F("Tel Number#1 is saving in memory"));  mySerial.print("Tel#1: ");  mySerial.println (TelNumber1); EndSMS();
              } 
                                             else if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}   
                                             else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС            
               isStringMessage = 0;
              
              }           



                
         else if (isStringMessage==0) {  if (TelNumber1!="000000000000" && !SaveNumber2 && TelNumber1!="яяяяяяяяяяяя"){
         
                     if (currStr.startsWith("+CMT: \""+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }   
                else if (currStr.startsWith("+CMT: \""+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }   
                else if (currStr.startsWith("+CUSD: 0,"))  //если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
                  {
                       if (KTOzapros == 1) startNumber1SMS();
                  else if (KTOzapros == 2) startNumber2SMS();
                  mySerial.print (currStr);
                  EndSMS();
                  }    
                                                }

                else if    (currStr.startsWith("+CMT:") && !SaveNumber2) { isStringMessage = 10; for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
                else if    (currStr.startsWith("+CMT:") && SaveNumber2) { for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];} TelNumber2 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+30, BufferNumber[i]);}
              startNumber2SMS(); mySerial.println(F("Vash nomer sochranyon kak Number#2 v pamyati!")); 
              mySerial.print(F("Tel1: ")); mySerial.println(TelNumber1); mySerial.print(F("Tel#2: "));  mySerial.println (TelNumber2); EndSMS(); SaveNumber2 = 0; } 
              
              } 
               
        currStr = "";
      } 
 
    else if ('\n' != currSymb) { currStr += String(currSymb);}
}


void SMSzapros()
{   if (isStringMessage == 10){
 startBufferNumberSMS();

 mySerial.println (F("Tel.number#1 has been no save in memory!"));
 mySerial.println (F("For save Tel#1 send SMS command \"WriteNumber1\""));
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  }
  
  
  
  else {
  
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 0) {if  (KTOreport == 1) startNumber1SMS();
                             else if  (KTOreport == 2) startNumber2SMS();}
        if (webasto) { mySerial.println (F("Webasto ON"));
           if (startWebasto_OK) mySerial.println (F("StartWebasto OK"));
           else mySerial.println (F("StartWebasto FAIL"));}
     else mySerial.println (F("Webasto OFF"));  

     if (engine)  mySerial.println (F("Engine ON"));
     else mySerial.println (F("Engine OFF"));  

     if (ignition)  mySerial.println (F("IGN ON"));
     else mySerial.println (F("IGN OFF"));  

     if (ohrana)  mySerial.println (F("OHRANA ON"));
     else mySerial.println (F("OHRANA OFF"));  

     if (trevoga)  mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
     
  mySerial.print(F("Battery: ")); mySerial.print (Vpit); mySerial.println(F("V"));
  mySerial.print(F("Engine: ")); mySerial.print (TempEngineC); mySerial.println(F("*C"));
  mySerial.print(F("Vyhlop: ")); mySerial.print (TempVyhlopC); mySerial.println(F("*C"));
  mySerial.print(F("Ulica: ")); mySerial.print (TempUlicaC); mySerial.println(F("*C"));
  mySerial.print(F("Salon: ")); mySerial.print (TempSalonC); mySerial.println(F("*C"));  
  mySerial.print(F("Protocol: "));
       if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));
  mySerial.print(F("Resets: ")); mySerial.println (ResetNumber); 
 
  }  
   EndSMS();                                 
}

void SMSzaprosTEL(){
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 10) { startBufferNumberSMS();}
  
  
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  if (TelNumber1!="000000000000" && TelNumber1!="яяяяяяяяяяяя"){
  mySerial.print(F("Protocol: "));
  if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));
  mySerial.print(F("Resets: ")); mySerial.println (ResetNumber); 
  }
  EndSMS();                                 
  }


void SMSbalance() {
  mySerial.print(F("AT+CMGF=1\r"));
      delay(200);

mySerial.println (F("AT+CUSD=1,\"#100#\""));
    
//mySerial.println("AT+CMGS=\"#100#\"");
//      mySerial.println("ATD#100#");
      //mySerial.println("AT + CMGS = \"111\""); // 
      delay(2000);                              // команда на замену на транслит *111*6*2#
      //mySerial.println ("11");
      //EndSMS();
}


void AlarmSMS() {
 startNumber1SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 startNumber2SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 alarmSMS = true;
}

void W_Bus (){
if (webasto) {
    if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){

 for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    //делаем периодическое поддержание связи W-BUS
    // наверное сканает отправка сообщения о состоянии котла
    // т.е. ,например, отправляем периодически запрос на показания датчиков
    // состоянием работы котла будет наличие или отсутствие пламени
if (flagStartPresent) {for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); }
//else {for (int i = 0; i<5; i++) Serial.write (StateMessage[i]);}
flagStartPresent = !flagStartPresent;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





else if (StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
  for (int i = 0; i<4; i++) Serial.write (Stop[i]); 
StopMessageRepeat++; 
StartMessageRepeat = 0;
   Prev_PeriodW_BusStartStop = millis();
  
  
  }

}



void Reset_gsm (){
  if (millis()-prevReset>(unsigned long)intervalReset*60000UL){
  mySerial.println (F("AT")); 
  timerenabledWaitOK = 1; timerWaitOK = millis();
  gsmOK= false;
  prevReset = millis(); }

if (timerenabledWaitOK && millis()-timerWaitOK>6000) {
    timerenabledWaitOK = 0;
    if (!gsmOK) {
      mySerial.println (F("AT")); timerenabledWaitOK = 1; timerWaitOK = millis();
      errors++; if (errors>5) errors = 5; 
      
      }
}

  
 if (!gsmOK)  { 
  if (mySerial.available()>0){                                   
    char currSymb = mySerial.read();                           
    if ('\r' == currSymb) {                                      
                                  
       if (!currStr.compareTo("OK")) {   gsmOK = true;  timerenabledWaitOK = 0; errors=0;}
       currStr = "";                                           
    }
    
    else if ('\n' != currSymb) {currStr += String(currSymb);}}}
    
    
    if (errors>=5) Reset();
    
    }

 void Reset(){
     
      if (!resettimer) {digitalWrite (ResetGSM, 0); resettimer = 1; resetTimer = millis();} 
else if (millis()- resetTimer>6000 ) {
digitalWrite (ResetGSM, 1); 
resettimer = 0; 
errors=0; 
ResetNumber++; 
EEPROM.write (0, ResetNumber);
delay (3000); NastroykaGSM ();}
           
      
      
      }

На плате из сообщения #82 для управления реле служит PC817, но такая схема не работает, тока, чтоли не хватает. Попробовал включение через pnp транзистор bc557 - заработало. Плату можно оставить без изменений, т.к. bc557 можно легко запаять в посадочное место PC817

было : 

 

 

Стало так :

 

Ahatolii
Offline
Зарегистрирован: 10.12.2017

Доброго времени суток. Спасибо вам большое за ваш проект!!!

Но почему то у меня не выходит скомпелировать скейч 2.3. библиотеки вроде все верные.

Вот такая ошибка.

 

 

Arduino: 1.8.1 (Windows 7), Плата:"Arduino Pro or Pro Mini, ATmega328 (5V, 16 MHz)"
 
WEBASTO.SIM800L:4: error: no matching function for call to 'Button::Button()'
 
C:\Users\Анатолий\Desktop\WEBASTO SIM800L\WEBASTO.SIM800L\WEBASTO.SIM800L.ino:4:8: note: candidates are:
 
In file included from C:\Users\Анатолий\Desktop\WEBASTO SIM800L\WEBASTO.SIM800L\WEBASTO.SIM800L.ino:2:0:
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:27:5: note: Button::Button(int, bool, unsigned char*)
 
     Button(int myBit, bool myMode, unsigned char *myRegister);
 
     ^
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:27:5: note:   candidate expects 3 arguments, 0 provided
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:26:5: note: Button::Button(int, bool)
 
     Button(int myPin, bool myMode);
 
     ^
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:26:5: note:   candidate expects 2 arguments, 0 provided
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:21:7: note: constexpr Button::Button(const Button&)
 
 class Button {
 
       ^
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:21:7: note:   candidate expects 1 argument, 0 provided
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:21:7: note: constexpr Button::Button(Button&&)
 
C:\Users\Анатолий\Documents\Arduino\libraries\Arduino-Library-Button-master/Button.h:21:7: note:   candidate expects 1 argument, 0 provided
 
C:\Users\Анатолий\Desktop\WEBASTO SIM800L\WEBASTO.SIM800L\WEBASTO.SIM800L.ino: In function 'void setup()':
 
WEBASTO.SIM800L:137: error: 'class Button' has no member named 'NO'
 
WEBASTO.SIM800L:138: error: 'class Button' has no member named 'pullUp'
 
WEBASTO.SIM800L:139: error: 'class Button' has no member named 'duration_bounce'
 
WEBASTO.SIM800L:140: error: 'class Button' has no member named 'duration_click_Db'
 
WEBASTO.SIM800L:141: error: 'class Button' has no member named 'duration_inactivity_Up'
 
WEBASTO.SIM800L:142: error: 'class Button' has no member named 'duration_inactivity_Dn'
 
WEBASTO.SIM800L:143: error: 'class Button' has no member named 'duration_press'
 
WEBASTO.SIM800L:144: error: 'class Button' has no member named 'button'
 
C:\Users\Анатолий\Desktop\WEBASTO SIM800L\WEBASTO.SIM800L\WEBASTO.SIM800L.ino: In function 'void loop()':
 
WEBASTO.SIM800L:183: error: 'class Button' has no member named 'read'
 
WEBASTO.SIM800L:186: error: 'class Button' has no member named 'event_click_Dn'
 
exit status 1
no matching function for call to 'Button::Button()'
 
 
 
MaksVV
Онлайн
Зарегистрирован: 06.08.2015

похоже у вас не хватает библиотеки титанового велосипеда для работы с кнопкой 

Ahatolii
Offline
Зарегистрирован: 10.12.2017

MaksVV пишет:

похоже у вас не хватает библиотеки титанового велосипеда для работы с кнопкой 

 

СПАСИБО БОЛЬШОЕ усе гуд. Буду тоже собирать.

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Присоединяюсь к благодарностям. Собрал урезанную мною, версию автора (под свои нужды запуска котла) пока всем доволен. С удовольствием слежу за проектом, скорее всего (если модуль хотя бы раз подведёт и зависнет) соберу и схему с реле для перезагрузки.

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

uu5jhu пишет:

Присоединяюсь к благодарностям. Собрал урезанную мною, версию автора (под свои нужды запуска котла) пока всем доволен. С удовольствием слежу за проектом, скорее всего (если модуль хотя бы раз подведёт и зависнет) соберу и схему с реле для перезагрузки.

вы используете включение котла потенциалом +12В? Мною проверен только протокол включения котла минусовым импульсом. Хотелось, чтобы пользователи отчитывались как у них подключено, по какому протоколу работает и есть ли косяки. Нужно собрать статистику стабильности работы всех функций устройства. 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

MaksVV пишет:

uu5jhu пишет:

Присоединяюсь к благодарностям. Собрал урезанную мною, версию автора (под свои нужды запуска котла) пока всем доволен. С удовольствием слежу за проектом, скорее всего (если модуль хотя бы раз подведёт и зависнет) соберу и схему с реле для перезагрузки.

вы используете включение котла потенциалом +12В? Мною проверен только протокол включения котла минусовым импульсом. Хотелось, чтобы пользователи отчитывались как у них подключено, по какому протоколу работает и есть ли косяки. Нужно собрать статистику стабильности работы всех функций устройства. 

Да использую я включение котла (Thermo Top Z ---- Webasto 9003552B) потенциалом +12В. Косяков пока не обнаружил - правда и запускал только по смс один раз (погода пока стоит теплая - в среднем +9 градусов). Запускал на 20 минут - спустя 20 минут котёл с продувкой остановился.

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

ОК, принято к сведению. 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

Обнаружил, что тактовая кнопка вкл/выкл котла не работает, нашел неточность в скетче v2.3 (сообщение #133). Исправил данный косяк

вот исправленный скетч v2.3.1

#include <EEPROM.h>
#include <Button.h>

Button test;

// для GSM модуля *********************
#include <SoftwareSerial.h>
SoftwareSerial mySerial(14, 15); //Rx, Tx
//#define mySerial Serial 
String currStr = "";

String TelNumber1 = "000000000000";

String TelNumber2 = "000000000000";

String BufferNumber = "000000000000";

bool SaveNumber2 = 0;  // флаг когда необходима запись номера#2, он true

int isStringMessage = 0; 
int KTOzapros = 0;
int KTOreport = 1;
//************************


int Protocol = 1; // протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
                  // 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
                  // 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)

                  
//_______Все для цикла void voltmetr()*************
float vout = 0.0;      // Напряжение на входе аналового входа
float Vpit = 0.0;      // Измеряемое напряжение на выходе ИБП
  int volt = 0;        // Напряжение на входе АЦП

// входы выходы на соостветствующие пины **************
#define DopOn 4      // сюда доп канал от сигналки на включение вебасто
#define DopOff  5    // сюда доп канал от сигналки на выключение вебасто
#define VyhodWebasto  12     // это импульсный минусовой выход вкл/выкл вебасто к таймеру. 
#define VyhodWebastoAnalog  3  // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера). 
#define Sost  9      // Сюда состояние вебасто (+12В когда работает)

#define Ohrana  6      // Сюда состояние охраны сигналки
#define Trevoga  7      // Сюда состояние тревоги
#define StartEng 8   // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
#define IGN 10       // Сюда состояние зажигания
#define Eng 11       // Сюда состояние работы ДВС
#define ResetGSM 16       // пин ресета GSM (A2) подключен к реле, разрывающее питание модуля. 
#define StartButton 0       // программный номер тактовой кнопки вкл/выкл котла 
#define StatusWebastoLED 13  // пин индикация включенности котла





// для шины 1-wire и датчиков DS18B20****************

#include <OneWire.h> // библиотека для DS18B20
OneWire ds(2); // датчики DS18B20 на 2 пин

byte VyhlopC[8] ={0x28, 0xFF, 0xE6, 0x14, 0x90, 0x15, 0x04, 0x62}; 
byte EngineC[8] ={0x28, 0xFF, 0x06, 0x15, 0x90, 0x15, 0x04, 0x37}; 
byte UlicaC[8] ={0x28, 0xFF, 0x43, 0x42, 0xA8, 0x15, 0x03, 0x2A};  
byte SalonC[8] ={0x28, 0xFF, 0xE0, 0x19, 0xA8, 0x15, 0x01, 0xA7};  
volatile int  TempVyhlopC = 20;
volatile int  TempEngineC = 20;
volatile int  TempUlicaC = 20;
volatile int  TempSalonC = 20;

// для организации W-BUS и различные таймеры********************
byte Zapusk20[5] = {0xF4,0x03, 0x20, 0x3B, 0xEC} ;
byte Zapusk21[5] = {0xF4,0x03, 0x21, 0x3B, 0xED} ;
byte Stop[4] = {0xF4,0x02, 0x10, 0xE6} ;

bool flagStartPresent = 1;               //флаг что отправляем в момент периодического поддержания связи W-Bus status или start
int StartMessageRepeat = 0;              //количество отправленных сообщений на старт котла
int StopMessageRepeat = 0;               //количество отправленных сообщений на остановку котла

unsigned long TimeWebasto = 1800000;   //время работы котла, 1800000 = 30мин
unsigned long EndReportMillis = 0;     //переменная для таймера отправки отчета об успешности запуска котла
unsigned long EndReportEngine = 0;     //переменная для таймера отправки отчета об успешности запуска ДВС
unsigned long Prev_PeriodW_BusMessage = 0;     //переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus 
unsigned long Prev_PeriodW_BusStartStop = 0;       //переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus 

//для таймера  - активация котла - импульс массы 0,8 сек на провод, впаянный в таймер вебасто)
unsigned long time, timer=0;
bool timerenabled=false;
#define TIMEREXPIRED (time-timer)>800


//для таймера  - старт двигателя - импульс +5В на оптопару, в итоге минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС)
unsigned long  timerStartEng=0; bool timerenabledStartEng=false;
#define TIMEREXPIRED_StartEng (millis()-timerStartEng)>1500


//для таймера  - старт котла по W-BUS )
unsigned long timerStart_W_BUS=0; bool timerenabledStart_W_BUS=false;
#define TIMEREXPIRED_Start_W_BUS (millis()-timerStart_W_BUS)> TimeWebasto 


//ниже всё для организации ресета GSM модуля, если с ним отсутствует свзяь

unsigned long  prevReset=0;      // для таймера периодичности проверки (командой "АТ")
int intervalReset = 30;          // каждые столько мин  будет ресет
unsigned long  timerWaitOK=0;    // для таймера ожидания ответа после посылки команды "АТ"
bool timerenabledWaitOK=false;   // для таймера ожидания ответа после посылки команды "АТ"
int errors=0;                    // количество неответов  от GSM модуля
bool gsmOK = 1;                  // флаг есть свяpь с GSM модулем или нет
bool resettimer = 0;             // для таймера удерживания реле в режиме сброс питания
unsigned long  resetTimer=0;     // для таймера удерживания реле в режиме сброс питания
int ResetNumber = 0;             //количество ресетов GSM модуля для статистики (хранится в еепром)

//**************************


//Основные переменные  
bool webasto = 0;            // состояние команды на работу Webasto. 0 - котел выключен, 1 - котел включен
bool startWebasto_OK = 0;    // состояние успешного запуска котла
bool report = false;      // состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
bool reportEngine = false;// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять

bool engine =0;    //флаг работает ли ДВС или нет
bool ignition=0;   //флаг включено ли зажигание или нет
bool ohrana=0;     //флаг включена ли охрана или нет
bool trevoga=0;    //флаг включена ли тревога или нет
bool alarmSMS = 0; //флаг отправлена ли смс о тревоге или нет





// СТАРТОВЫЙ ЦИКЛ
void setup() 
{
 delay (2500);

test.NO(); 
test.pullUp();
test.duration_bounce       (  50);
test.duration_click_Db     ( 250);
test.duration_inactivity_Up(5000);
test.duration_inactivity_Dn(1000);
test.duration_press        ( 500);
test.button(17); //пин 17 (А3) сюда подключена тактовая кнопка вкл/выкл котла (программный номер у неё будет 0)
 
  WDTCSR=(1<<WDCE)|(1<<WDE); //для датчиков DS18B20
 
  WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0); // для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
  pinMode (DopOn,  INPUT);   digitalWrite (DopOn,  HIGH);
  pinMode (DopOff, INPUT);   digitalWrite (DopOff, HIGH);
  pinMode (Sost,   INPUT);   digitalWrite (Sost,   HIGH);
  pinMode (VyhodWebasto,  OUTPUT);  digitalWrite (VyhodWebasto,  HIGH);
  pinMode (VyhodWebastoAnalog,  OUTPUT);  digitalWrite (VyhodWebastoAnalog,  LOW);
  pinMode (StartEng,  OUTPUT);  digitalWrite (StartEng,  LOW);
  pinMode (StatusWebastoLED,     OUTPUT);  digitalWrite (StatusWebastoLED,     LOW);
  pinMode (ResetGSM,     OUTPUT);  digitalWrite (ResetGSM,    HIGH);

  pinMode (Ohrana, INPUT);  digitalWrite (Ohrana,  HIGH);
  pinMode (Trevoga, INPUT);  digitalWrite (Trevoga,  HIGH);
  pinMode (IGN, INPUT);  digitalWrite (IGN,  HIGH);
  pinMode (Eng, INPUT);  digitalWrite (Eng,  HIGH);
  
  
Serial.begin (2400, SERIAL_8E1);   // сериал соединение протокол W-Bus

mySerial.begin(19200);           // сериал соединение для gsm модуля


    delay(2000);

  NastroykaGSM ();

TimeWebasto = EEPROM.read(1)*60000UL;
Protocol = EEPROM.read(2);
ResetNumber = EEPROM.read(0);
for (int i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
for (int i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);

}


void loop() {
test.read();
digitalWrite (StatusWebastoLED, webasto);
//если нажали тактовую кнопку меняем состояние котла на противоположное 
if (test.event_click_Dn (StartButton)) {
  if (!webasto) {StartWebasto(); report = false;}
  else StopWebasto();
    }

if (Protocol!=2) {if (TempVyhlopC - TempUlicaC > 40) startWebasto_OK = 1;
                  else startWebasto_OK = 0;}

if (Protocol==1) webasto = !digitalRead (Sost);

if (Protocol==2) W_Bus();

//ниже для таймера старта котла по W-BUS и аналогу 
 
  if (timerenabledStart_W_BUS && TIMEREXPIRED_Start_W_BUS) StopWebasto();

//ниже для таймера создания импульса на старт ДВС 

if (timerenabledStartEng && TIMEREXPIRED_StartEng) {digitalWrite (StartEng, LOW); timerenabledStartEng=false;}
    
 engine =  !digitalRead (Eng);
 ignition= !digitalRead (IGN); 
 ohrana=   !digitalRead (Ohrana);  
 trevoga=  !digitalRead (Trevoga);
  
if (webasto && report) timerReport ();
if (reportEngine) timerReportEngine ();
if (trevoga && !alarmSMS) AlarmSMS ();
if (!ohrana) alarmSMS = false;

if (gsmOK)readSMS();
Reset_gsm();
voltmetr();
WebastoOprosImpulse ();


}

void voltmetr()  //____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП

{
   volt = analogRead(A7);                       // А7 аналоговый вход вольтметра
   vout = (volt * 4.92) / 1024;             
   Vpit = vout / (9950.0/(98930.0+9950.0));  // По формуле Vpit = vout / (R2/(R1+R2)) 
   if (Vpit<0.09)  Vpit=0.0;                  // Округление до нуля 
}






// Вектор прерывания для Dallas DS18B20
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.write(0xCC);//обращение ко всем датчикам
        ds.write(0x44);// начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(VyhlopC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempVyhlopC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempVyhlopC = TempVyhlopC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(EngineC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempEngineC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempEngineC = TempEngineC/16;
        ds.reset();
        ds.select(UlicaC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempUlicaC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempUlicaC = TempUlicaC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(SalonC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSalonC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempSalonC = TempSalonC/16 ;
}}




                    


void StartWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StartMessageRepeat = 0;
  webasto = 1; digitalWrite (VyhodWebastoAnalog, HIGH);
  timerStart_W_BUS=millis();
  timerenabledStart_W_BUS = true;}

  report = true; EndReportMillis = millis();
}

void StopWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StopMessageRepeat = 0;
  webasto = 0; digitalWrite (VyhodWebastoAnalog, LOW);
  timerenabledStart_W_BUS = false;}
   report = false;
}




void WebastoOprosImpulse (){

// опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла 
  time = millis();
  if (timerenabled) {if (TIMEREXPIRED) {digitalWrite (VyhodWebasto, HIGH); timerenabled=false;}}
  else  {if (!digitalRead (DopOn)  && !webasto) {StartWebasto(); KTOreport = 1;}
         if (!digitalRead (DopOff) && webasto) StopWebasto();
         }}


// цикл таймера отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
void timerReport () {
   if(millis() - EndReportMillis > 360000UL) 
   {EndReportMillis = millis(); report = false; SMSzapros();  }} 

// цикл таймера отправки отчета об успешности запуска ДВС  (отчёт через 30сек после старта)                       
void timerReportEngine () {
   if(millis() - EndReportEngine > 30000) 
   {EndReportEngine = millis(); reportEngine = false; SMSzapros();}} 





   void NastroykaGSM () {
      mySerial.print(F("AT+CMGF=1\r"));         //устанавливает текстовый режим смс-сообщения
    delay(200);
  mySerial.print(F("+IFC=1, 1\r"));       //устанавливает программный контроль потоком передачи данных
    delay(200);
  mySerial.print(F("AT+CPBS=\"SM\"\r"));    //открывает доступ к данным телефонной книги SIM-карты
    delay(200);
  mySerial.print(F("AT+GSMBUSY=1\r"));   //запрет всех входящих звонков
    delay(300);
  mySerial.print(F("AT+CNMI=1,2,2,1,0\r")); //включает оповещение о новых сообщениях
    delay(300);
  mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
}

void startNumber1SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
{
      mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
  mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber1); mySerial.println("\""); 
      delay(400);
}

void startNumber2SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber2); mySerial.println(F("\"")); 
      delay(400);
}

void startBufferNumberSMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(BufferNumber); mySerial.println(F("\"")); 
      delay(400);
}

void EndSMS ()
{
   mySerial.println((char)26);                       // Команда отправки СМС
   delay(3000);
   mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(1500);
}


void readSMS() //_____Цикл чтения входящих СМС-сообщений______________     
{
    if (!mySerial.available()) return;
    char currSymb = mySerial.read();
//  Serial.print (currSymb);
    if ('\r' == currSymb)
       {
         if (isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
                {
if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}               // Передача параметров по СМС
else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС



else if (!currStr.compareTo("Webasto-ON"))  { if (!webasto)  {StartWebasto ();  // если получили команду на включение и вебаста в настоящий момент выключена - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Webasto Vkluchena")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS(); 
                                                                        mySerial.println(F("Webasto uzhe vkluchena")); EndSMS();}}

                                                            
               else if (!currStr.compareTo("Webasto-OFF"))   {if (webasto){StopWebasto ();  // если получили команду на выключение и вебаста в настоящий момент включена - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Webasto Otkluchena")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS(); 
                                                                         mySerial.println(F("Webasto uzhe otkluchena")); EndSMS();}}          


                else if (!currStr.compareTo("Engine-ON"))  {if (!engine)  { digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = true; EndReportEngine = timerStartEng; // если получили команду на включение ДВС и он в настоящий момент выключен - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS();  KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Engine Start")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel uzhe rabotaet")); EndSMS();}}
                                                                                 
               else if (!currStr.compareTo("Engine-OFF"))   {if (engine){ digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = false; // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS();
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel ostanovlen")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS();
                                                                         mySerial.println(F("dvigatel uzhe ostanovlen")); EndSMS(); }}          
                                                    

               else if (!currStr.compareTo("Impulse"))   {Protocol = 1;  EEPROM.write(2,Protocol);     if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}}                                                               

               else if (!currStr.compareTo("W-BUS"))   {Protocol = 2; EEPROM.write(2,Protocol);  webasto = 0;  if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk W-BUS")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk W_BUS")); EndSMS();}}

               else if (!currStr.compareTo("Potenzial"))   {Protocol = 3; EEPROM.write(2,Protocol);   if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}} 

               
                else if (currStr.endsWith("min"))   {TimeWebasto = currStr.toInt()*60000UL; // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
               if (TimeWebasto>3540000UL) TimeWebasto = 3540000UL;
               if (TimeWebasto<=600000UL) TimeWebasto = 600000UL;
               EEPROM.write(1,TimeWebasto/60000UL);
                     if (isStringMessage == 1)startNumber1SMS(); 
               else  if (isStringMessage == 2) startNumber2SMS(); 
               mySerial.print(F("Webasto time: ")); mySerial.print(TimeWebasto/60000UL); mySerial.print(F("min")); EndSMS();}
               

               else if (!currStr.compareTo("ResetNumbers"))   {if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("Phone numbers are erased")); EndSMS(); 
                                                                     
             TelNumber1 = "000000000000"; TelNumber2 = "000000000000"; for (int i=0; i<12; i++) {EEPROM.write (i+10,  TelNumber1[i]); EEPROM.write (i+30,  TelNumber2[i]); }}}

              else if (!currStr.compareTo("WriteNumber2")&& isStringMessage == 1)   { 
                SaveNumber2 = 1; startNumber1SMS(); mySerial.println(F("Otpravte lyuboye SMS s nomera2 dlya sochraneniya nomera")); EndSMS();} 

                                                                        

                                                     
               else if (!currStr.compareTo("Balance"))    SMSbalance();
            isStringMessage = 0;
                }
              else if (isStringMessage==10){ if (!currStr.compareTo("WriteNumber1"))   { TelNumber1 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
              startNumber1SMS(); mySerial.println(F("Tel Number#1 is saving in memory"));  mySerial.print("Tel#1: ");  mySerial.println (TelNumber1); EndSMS();
              } 
                                             else if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}   
                                             else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС            
               isStringMessage = 0;
              
              }           



                
         else if (isStringMessage==0) {  if (TelNumber1!="000000000000" && !SaveNumber2 && TelNumber1!="яяяяяяяяяяяя"){
         
                     if (currStr.startsWith("+CMT: \""+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }   
                else if (currStr.startsWith("+CMT: \""+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }   
                else if (currStr.startsWith("+CUSD: 0,"))  //если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
                  {
                       if (KTOzapros == 1) startNumber1SMS();
                  else if (KTOzapros == 2) startNumber2SMS();
                  mySerial.print (currStr);
                  EndSMS();
                  }    
                                                }

                else if    (currStr.startsWith("+CMT:") && !SaveNumber2) { isStringMessage = 10; for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
                else if    (currStr.startsWith("+CMT:") && SaveNumber2) { for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];} TelNumber2 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+30, BufferNumber[i]);}
              startNumber2SMS(); mySerial.println(F("Vash nomer sochranyon kak Number#2 v pamyati!")); 
              mySerial.print(F("Tel1: ")); mySerial.println(TelNumber1); mySerial.print(F("Tel#2: "));  mySerial.println (TelNumber2); EndSMS(); SaveNumber2 = 0; } 
              
              } 
               
        currStr = "";
      } 
 
    else if ('\n' != currSymb) { currStr += String(currSymb);}
}


void SMSzapros()
{   if (isStringMessage == 10){
 startBufferNumberSMS();

 mySerial.println (F("Tel.number#1 has been no save in memory!"));
 mySerial.println (F("For save Tel#1 send SMS command \"WriteNumber1\""));
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  }
  
  
  
  else {
  
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 0) {if  (KTOreport == 1) startNumber1SMS();
                             else if  (KTOreport == 2) startNumber2SMS();}
        if (webasto) { mySerial.println (F("Webasto ON"));
           if (startWebasto_OK) mySerial.println (F("StartWebasto OK"));
           else mySerial.println (F("StartWebasto FAIL"));}
     else mySerial.println (F("Webasto OFF"));  

     if (engine)  mySerial.println (F("Engine ON"));
     else mySerial.println (F("Engine OFF"));  

     if (ignition)  mySerial.println (F("IGN ON"));
     else mySerial.println (F("IGN OFF"));  

     if (ohrana)  mySerial.println (F("OHRANA ON"));
     else mySerial.println (F("OHRANA OFF"));  

     if (trevoga)  mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
     
  mySerial.print(F("Battery: ")); mySerial.print (Vpit); mySerial.println(F("V"));
  mySerial.print(F("Engine: ")); mySerial.print (TempEngineC); mySerial.println(F("*C"));
  mySerial.print(F("Vyhlop: ")); mySerial.print (TempVyhlopC); mySerial.println(F("*C"));
  mySerial.print(F("Ulica: ")); mySerial.print (TempUlicaC); mySerial.println(F("*C"));
  mySerial.print(F("Salon: ")); mySerial.print (TempSalonC); mySerial.println(F("*C"));  
  mySerial.print(F("Protocol: "));
       if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));
  mySerial.print(F("Resets: ")); mySerial.println (ResetNumber); 
 
  }  
   EndSMS();                                 
}

void SMSzaprosTEL(){
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 10) { startBufferNumberSMS();}
  
  
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  if (TelNumber1!="000000000000" && TelNumber1!="яяяяяяяяяяяя"){
  mySerial.print(F("Protocol: "));
  if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));
  mySerial.print(F("Resets: ")); mySerial.println (ResetNumber); 
  }
  EndSMS();                                 
  }


void SMSbalance() {
  mySerial.print(F("AT+CMGF=1\r"));
      delay(200);

mySerial.println (F("AT+CUSD=1,\"#100#\""));
    
//mySerial.println("AT+CMGS=\"#100#\"");
//      mySerial.println("ATD#100#");
      //mySerial.println("AT + CMGS = \"111\""); // 
      delay(2000);                              // команда на замену на транслит *111*6*2#
      //mySerial.println ("11");
      //EndSMS();
}


void AlarmSMS() {
 startNumber1SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 startNumber2SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 alarmSMS = true;
}

void W_Bus (){
if (webasto) {
    if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){

 for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    //делаем периодическое поддержание связи W-BUS
    // наверное сканает отправка сообщения о состоянии котла
    // т.е. ,например, отправляем периодически запрос на показания датчиков
    // состоянием работы котла будет наличие или отсутствие пламени
if (flagStartPresent) {for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); }
//else {for (int i = 0; i<5; i++) Serial.write (StateMessage[i]);}
flagStartPresent = !flagStartPresent;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





else if (StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
  for (int i = 0; i<4; i++) Serial.write (Stop[i]); 
StopMessageRepeat++; 
StartMessageRepeat = 0;
   Prev_PeriodW_BusStartStop = millis();
  
  
  }

}



void Reset_gsm (){
  if (millis()-prevReset>(unsigned long)intervalReset*60000UL){
  mySerial.println (F("AT")); 
  timerenabledWaitOK = 1; timerWaitOK = millis();
  gsmOK= false;
  prevReset = millis(); }

if (timerenabledWaitOK && millis()-timerWaitOK>6000) {
    timerenabledWaitOK = 0;
    if (!gsmOK) {
      mySerial.println (F("AT")); timerenabledWaitOK = 1; timerWaitOK = millis();
      errors++; if (errors>5) errors = 5; 
      
      }
}

  
 if (!gsmOK)  { 
  if (mySerial.available()>0){                                   
    char currSymb = mySerial.read();                           
    if ('\r' == currSymb) {                                      
                                  
       if (!currStr.compareTo("OK")) {   gsmOK = true;  timerenabledWaitOK = 0; errors=0;}
       currStr = "";                                           
    }
    
    else if ('\n' != currSymb) {currStr += String(currSymb);}}}
    
    
    if (errors>=5) Reset();
    
    }

 void Reset(){
     
      if (!resettimer) {digitalWrite (ResetGSM, 0); resettimer = 1; resetTimer = millis();} 
else if (millis()- resetTimer>6000 ) {
digitalWrite (ResetGSM, 1); 
resettimer = 0; 
errors=0; 
ResetNumber++; 
EEPROM.write (0, ResetNumber);
delay (3000); NastroykaGSM ();}
           
      
      
      }

 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

попробовал добавить в проект реализацию энергосберегающего режима SIM800L. По способу, указанному тут . 

принципиальная схема платы v5

Плата v5

Скетч v2.4.

#include <EEPROM.h>
#include <Button.h>

Button test;

// для GSM модуля *********************
#include <SoftwareSerial.h>
SoftwareSerial mySerial(14, 15); //Rx, Tx
//#define mySerial Serial 
String currStr = "";

String TelNumber1 = "000000000000";

String TelNumber2 = "000000000000";

String BufferNumber = "000000000000";

bool SaveNumber2 = 0;  // флаг когда необходима запись номера#2, он true

int isStringMessage = 0; 
int KTOzapros = 0;
int KTOreport = 1;
//************************


int Protocol = 1; // протокол, по которому будет происходить выход на запуск котла: 1 - импульсный минусовой выход (на впайку в таймер вебасто например)
                  // 2 - по протоколу W-BUS ( котлы TermoTOP EVO)
                  // 3 - по подаче потенциала 12В, т.е. пока висит +12В - котел включен (котлы по аналогу - TermoTOP C,E)

                  
//_______Все для цикла void voltmetr()*************
float vout = 0.0;      // Напряжение на входе аналового входа
float Vpit = 0.0;      // Измеряемое напряжение на выходе ИБП
  int volt = 0;        // Напряжение на входе АЦП

// входы выходы на соостветствующие пины **************
#define DopOn 4      // сюда доп канал от сигналки на включение вебасто
#define DopOff  5    // сюда доп канал от сигналки на выключение вебасто
#define VyhodWebasto  12     // это импульсный минусовой выход вкл/выкл вебасто к таймеру. 
#define VyhodWebastoAnalog  3  // это потенциальный плюсовой выход вкл/выкл вебасто (напрямую к котлу без таймера). 
#define Sost  9      // Сюда состояние вебасто (+12В когда работает)

#define Ohrana  6      // Сюда состояние охраны сигналки
#define Trevoga  7      // Сюда состояние тревоги
#define StartEng 8   // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
#define IGN 10       // Сюда состояние зажигания
#define Eng 11       // Сюда состояние работы ДВС
#define ResetGSM 16       // пин ресета GSM (A2) подключен к реле, разрывающее питание модуля. 
#define StartButton 0       // программный номер тактовой кнопки вкл/выкл котла 
#define StatusWebastoLED 13  // пин индикация включенности котла
#define DTR 20  // пин (А6), управляющий энергосберегающим режимом GSM модуля





// для шины 1-wire и датчиков DS18B20****************

#include <OneWire.h> // библиотека для DS18B20
OneWire ds(2); // датчики DS18B20 на 2 пин

byte VyhlopC[8] ={0x28, 0xFF, 0xE6, 0x14, 0x90, 0x15, 0x04, 0x62}; 
byte EngineC[8] ={0x28, 0xFF, 0x06, 0x15, 0x90, 0x15, 0x04, 0x37}; 
byte UlicaC[8] ={0x28, 0xFF, 0x43, 0x42, 0xA8, 0x15, 0x03, 0x2A};  
byte SalonC[8] ={0x28, 0xFF, 0xE0, 0x19, 0xA8, 0x15, 0x01, 0xA7};  
volatile int  TempVyhlopC = 20;
volatile int  TempEngineC = 20;
volatile int  TempUlicaC = 20;
volatile int  TempSalonC = 20;

// для организации W-BUS и различные таймеры********************
byte Zapusk20[5] = {0xF4,0x03, 0x20, 0x3B, 0xEC} ;
byte Zapusk21[5] = {0xF4,0x03, 0x21, 0x3B, 0xED} ;
byte Stop[4] = {0xF4,0x02, 0x10, 0xE6} ;

bool flagStartPresent = 1;               //флаг что отправляем в момент периодического поддержания связи W-Bus status или start
int StartMessageRepeat = 0;              //количество отправленных сообщений на старт котла
int StopMessageRepeat = 0;               //количество отправленных сообщений на остановку котла

unsigned long TimeWebasto = 1800000;   //время работы котла, 1800000 = 30мин
unsigned long EndReportMillis = 0;     //переменная для таймера отправки отчета об успешности запуска котла
unsigned long EndReportEngine = 0;     //переменная для таймера отправки отчета об успешности запуска ДВС
unsigned long Prev_PeriodW_BusMessage = 0;     //переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus 
unsigned long Prev_PeriodW_BusStartStop = 0;       //переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus 
unsigned long prevdelSMS = 0;       //переменная для таймера периодического удаления СМС 

//для таймера  - активация котла - импульс массы 0,8 сек на провод, впаянный в таймер вебасто)
unsigned long time, timer=0;
bool timerenabled=false;
#define TIMEREXPIRED (time-timer)>800


//для таймера  - старт двигателя - импульс +5В на оптопару, в итоге минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС)
unsigned long  timerStartEng=0; bool timerenabledStartEng=false;
#define TIMEREXPIRED_StartEng (millis()-timerStartEng)>1500


//для таймера  - старт котла по W-BUS )
unsigned long timerStart_W_BUS=0; bool timerenabledStart_W_BUS=false;
#define TIMEREXPIRED_Start_W_BUS (millis()-timerStart_W_BUS)> TimeWebasto 



//ниже всё для организации ресета GSM модуля, если с ним отсутствует свзяь

unsigned long  prevReset=0;      // для таймера периодичности проверки (командой "АТ")
int intervalReset = 30;          // каждые столько мин  будет ресет
unsigned long  timerWaitOK=0;    // для таймера ожидания ответа после посылки команды "АТ"
bool timerenabledWaitOK=false;   // для таймера ожидания ответа после посылки команды "АТ"
int errors=0;                    // количество неответов  от GSM модуля
bool gsmOK = 1;                  // флаг есть свяpь с GSM модулем или нет
bool resettimer = 0;             // для таймера удерживания реле в режиме сброс питания
unsigned long  resetTimer=0;     // для таймера удерживания реле в режиме сброс питания
int ResetNumber = 0;             //количество ресетов GSM модуля для статистики (хранится в еепром)

//**************************


//Основные переменные  
bool webasto = 0;            // состояние команды на работу Webasto. 0 - котел выключен, 1 - котел включен
bool startWebasto_OK = 0;    // состояние успешного запуска котла
bool report = false;      // состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять
bool reportEngine = false;// состояние нужности отправки отчета false - не нужно отправлять, true - нужно отправлять

bool engine =0;    //флаг работает ли ДВС или нет
bool ignition=0;   //флаг включено ли зажигание или нет
bool ohrana=0;     //флаг включена ли охрана или нет
bool trevoga=0;    //флаг включена ли тревога или нет
bool alarmSMS = 0; //флаг отправлена ли смс о тревоге или нет





// СТАРТОВЫЙ ЦИКЛ
void setup() 
{
 delay (2500);

test.NO(); 
test.pullUp();
test.duration_bounce       (  50);
test.duration_click_Db     ( 250);
test.duration_inactivity_Up(5000);
test.duration_inactivity_Dn(1000);
test.duration_press        ( 500);
test.button(17); //пин 17 (А3) тактовой кнопки вкл/выкл котла (программный номер у неё будет 0)
 
  WDTCSR=(1<<WDCE)|(1<<WDE); //для датчиков DS18B20
 
  WDTCSR=(1<<WDIE)| (1<<WDP3)|(1<<WDP0); // для датчиков DS18B20 (разрешение прерывания + выдержка 8 секунд)
  pinMode (DopOn,  INPUT);   digitalWrite (DopOn,  HIGH);
  pinMode (DopOff, INPUT);   digitalWrite (DopOff, HIGH);
  pinMode (Sost,   INPUT);   digitalWrite (Sost,   HIGH);
  pinMode (VyhodWebasto,  OUTPUT);  digitalWrite (VyhodWebasto,  HIGH);
  pinMode (VyhodWebastoAnalog,  OUTPUT);  digitalWrite (VyhodWebastoAnalog,  LOW);
  pinMode (StartEng,  OUTPUT);  digitalWrite (StartEng,  LOW);
  pinMode (StatusWebastoLED,     OUTPUT);  digitalWrite (StatusWebastoLED,     LOW);
  pinMode (ResetGSM,     OUTPUT);  digitalWrite (ResetGSM,    HIGH);
  pinMode (DTR,     OUTPUT);  digitalWrite (ResetGSM, LOW);  // низкий уровень - для пробуждения GSM из "спячки"

  pinMode (Ohrana, INPUT);  digitalWrite (Ohrana,  HIGH);
  pinMode (Trevoga, INPUT);  digitalWrite (Trevoga,  HIGH);
  pinMode (IGN, INPUT);  digitalWrite (IGN,  HIGH);
  pinMode (Eng, INPUT);  digitalWrite (Eng,  HIGH);
  
  
Serial.begin (2400, SERIAL_8E1);   // сериал соединение протокол W-Bus

mySerial.begin(19200);           // сериал соединение для gsm модуля


    delay(2000);

  NastroykaGSM ();

TimeWebasto = EEPROM.read(1)*60000UL;
Protocol = EEPROM.read(2);
ResetNumber = EEPROM.read(0);
for (int i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
for (int i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);

}


void loop() {
test.read();
digitalWrite (StatusWebastoLED, webasto);
//если нажали тактовую кнопку меняем состояние котла на противоположное 
if (test.event_click_Dn (StartButton)) {
  if (!webasto) {StartWebasto(); report = false;}
  else StopWebasto();
    }

if (Protocol!=2) {if (TempVyhlopC - TempUlicaC > 40) startWebasto_OK = 1;
                  else startWebasto_OK = 0;}

if (Protocol==1) webasto = !digitalRead (Sost);

if (Protocol==2) W_Bus();

//ниже для таймера старта котла по W-BUS и аналогу 
 
  if (timerenabledStart_W_BUS && TIMEREXPIRED_Start_W_BUS) StopWebasto();

//ниже для таймера создания импульса на старт ДВС 

if (timerenabledStartEng && TIMEREXPIRED_StartEng) {digitalWrite (StartEng, LOW); timerenabledStartEng=false;}
    
 engine =  !digitalRead (Eng);
 ignition= !digitalRead (IGN); 
 ohrana=   !digitalRead (Ohrana);  
 trevoga=  !digitalRead (Trevoga);
  
if (webasto && report) timerReport ();
if (reportEngine) timerReportEngine ();
if (trevoga && !alarmSMS) AlarmSMS ();
if (!ohrana) alarmSMS = false;

if (gsmOK)readSMS();
Reset_gsm();
voltmetr();
WebastoOprosImpulse ();
delSMS();


}

void voltmetr()  //____________Цикл "Вольтметр"__измерение напряжения на выходе ИБП

{
   volt = analogRead(A7);                       // А7 аналоговый вход вольтметра
   vout = (volt * 4.92) / 1024;             
   Vpit = vout / (9950.0/(98930.0+9950.0));  // По формуле Vpit = vout / (R2/(R1+R2)) 
   if (Vpit<0.09)  Vpit=0.0;                  // Округление до нуля 
}






// Вектор прерывания для Dallas DS18B20
ISR (WDT_vect){ //вектор прерывания WD
static boolean n=0; // флаг работы: запрос температуры или её чтение
n=!n;
if (n) {ds.reset();  // сброс шины
        ds.write(0xCC);//обращение ко всем датчикам
        ds.write(0x44);// начать преобразование (без паразитного питания)  
       }
else   {ds.reset();
        ds.select(VyhlopC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempVyhlopC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempVyhlopC = TempVyhlopC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(EngineC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempEngineC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempEngineC = TempEngineC/16;
        ds.reset();
        ds.select(UlicaC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempUlicaC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта       
        TempUlicaC = TempUlicaC / 16;
        // получение с 2-го датчика
        ds.reset();
        ds.select(SalonC);    
        ds.write(0xBE); // Read Scratchpad (чтение регистров)  
        TempSalonC =  ds.read() | (ds.read()<<8); //прочитаны 2 байта  
        TempSalonC = TempSalonC/16 ;
}}




                    


void StartWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StartMessageRepeat = 0;
  webasto = 1; digitalWrite (VyhodWebastoAnalog, HIGH);
  timerStart_W_BUS=millis();
  timerenabledStart_W_BUS = true;}

  report = true; EndReportMillis = millis();
}

void StopWebasto()
{
 if (Protocol==1){ digitalWrite (VyhodWebasto, LOW); 
  timer=time; 
  timerenabled=true;}

 else if (Protocol==2||Protocol==3){
  StopMessageRepeat = 0;
  webasto = 0; digitalWrite (VyhodWebastoAnalog, LOW);
  timerenabledStart_W_BUS = false;}
   report = false;
}




void WebastoOprosImpulse (){

// опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла 
  time = millis();
  if (timerenabled) {if (TIMEREXPIRED) {digitalWrite (VyhodWebasto, HIGH); timerenabled=false;}}
  else  {if (!digitalRead (DopOn)  && !webasto) {StartWebasto(); KTOreport = 1;}
         if (!digitalRead (DopOff) && webasto) StopWebasto();
         }}


// цикл таймера отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
void timerReport () {
   if(millis() - EndReportMillis > 360000UL) 
   {EndReportMillis = millis(); report = false; SMSzapros();  }} 

// цикл таймера отправки отчета об успешности запуска ДВС  (отчёт через 30сек после старта)                       
void timerReportEngine () {
   if(millis() - EndReportEngine > 30000) 
   {EndReportEngine = millis(); reportEngine = false; SMSzapros();}} 





   void NastroykaGSM () {
  digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
    delay (150);
  mySerial.print(F("AT+CMGF=1\r"));         //устанавливает текстовый режим смс-сообщения
    delay(200);
  mySerial.print(F("+IFC=1, 1\r"));       //устанавливает программный контроль потоком передачи данных
    delay(200);
  mySerial.print(F("AT+CPBS=\"SM\"\r"));    //открывает доступ к данным телефонной книги SIM-карты
    delay(200);
  mySerial.print(F("AT+GSMBUSY=1\r"));   //запрет всех входящих звонков
    delay(300);
  mySerial.print(F("AT+CNMI=1,2,2,1,0\r")); //включает оповещение о новых сообщениях
    delay(300);
  mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
  mySerial.println(F("AT+CSCLK=1")); //включает энергосберегающий режим 
  delay(150);
  digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль высоким уровнем на пине DTR
  delay(150);
  
}

void startNumber1SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
{
     digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
     mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
     mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber1); mySerial.println("\""); 
         delay(400);
}

void startNumber2SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
      mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(TelNumber2); mySerial.println(F("\"")); 
         delay(400);
}

void startBufferNumberSMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по второму  номеру
{
      digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
      mySerial.print(F("AT+CMGF=1\r"));
         delay(200);
      mySerial.print(F("AT+CMGS=\"")); mySerial.print(BufferNumber); mySerial.println(F("\"")); 
         delay(400);
}

void EndSMS ()
{
   mySerial.println((char)26);                       // Команда отправки СМС
   delay(2000);
   digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
   delay (150);
}

void delSMS ()
{
if (millis() - prevdelSMS > 7200000ul){  //раз в 2 часа 
 digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
    delay (150);
 mySerial.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки
   delay(2000);
 digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
   delay (150);

  prevdelSMS = millis();}
}


void readSMS() //_____Цикл чтения входящих СМС-сообщений______________     
{
    if (!mySerial.available()) return;
    char currSymb = mySerial.read();
//  Serial.print (currSymb);
    if ('\r' == currSymb)
       {
         if (isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
                {
if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}               // Передача параметров по СМС
else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС



else if (!currStr.compareTo("Webasto-ON"))  { if (!webasto)  {StartWebasto ();  // если получили команду на включение и вебаста в настоящий момент выключена - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS(); KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Webasto Vkluchena")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS(); 
                                                                        mySerial.println(F("Webasto uzhe vkluchena")); EndSMS();}}

                                                            
               else if (!currStr.compareTo("Webasto-OFF"))   {if (webasto){StopWebasto ();  // если получили команду на выключение и вебаста в настоящий момент включена - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Webasto Otkluchena")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS(); 
                                                                         mySerial.println(F("Webasto uzhe otkluchena")); EndSMS();}}          


                else if (!currStr.compareTo("Engine-ON"))  {if (!engine)  { digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = true; EndReportEngine = timerStartEng; // если получили команду на включение ДВС и он в настоящий момент выключен - включаем
                                                                              if (isStringMessage == 1) {startNumber1SMS();  KTOreport = 1;}
                                                                         else if (isStringMessage == 2) {startNumber2SMS();  KTOreport = 2;}
                                                                         mySerial.println(F("Engine Start")); EndSMS();}
                                                                       
                                                   else                     {if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel uzhe rabotaet")); EndSMS();}}
                                                                                 
               else if (!currStr.compareTo("Engine-OFF"))   {if (engine){ digitalWrite (StartEng, HIGH);  timerStartEng=millis(); timerenabledStartEng=true; reportEngine = false; // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
                                                                              if (isStringMessage == 1) startNumber1SMS();
                                                                        else  if (isStringMessage == 2) startNumber2SMS();
                                                                        mySerial.println(F("Dvigatel ostanovlen")); EndSMS();}


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS();
                                                                         mySerial.println(F("dvigatel uzhe ostanovlen")); EndSMS(); }}          
                                                    

               else if (!currStr.compareTo("Impulse"))   {if (!webasto) {Protocol = 1;  EEPROM.write(2,Protocol);     if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk GND_impulse")); EndSMS();}}}                                                               

               else if (!currStr.compareTo("W-BUS"))   {if (!webasto) {Protocol = 2; EEPROM.write(2,Protocol);  webasto = 0;  if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk W-BUS")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk W_BUS")); EndSMS();}}}

               else if (!currStr.compareTo("Potenzial"))   {if (!webasto) {Protocol = 3; EEPROM.write(2,Protocol);   if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}
                                                                        else  if (isStringMessage == 2) {startNumber2SMS(); mySerial.println(F("zapusk +12V Potencial")); EndSMS();}}}

               
                else if (currStr.endsWith("min"))   {if (!webasto) {TimeWebasto = currStr.toInt()*60000UL; // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин
               if (TimeWebasto>3540000UL) TimeWebasto = 3540000UL;
               if (TimeWebasto<=600000UL) TimeWebasto = 600000UL;
               EEPROM.write(1,TimeWebasto/60000UL);
                     if (isStringMessage == 1)startNumber1SMS(); 
               else  if (isStringMessage == 2) startNumber2SMS(); 
               mySerial.print(F("Webasto time: ")); mySerial.print(TimeWebasto/60000UL); mySerial.print(F("min")); EndSMS();}}
               

               else if (!currStr.compareTo("ResetNumbers"))   {if (isStringMessage == 1) {startNumber1SMS(); mySerial.println(F("Phone numbers are erased")); EndSMS(); 
                                                                     
             TelNumber1 = "000000000000"; TelNumber2 = "000000000000"; for (int i=0; i<12; i++) {EEPROM.write (i+10,  TelNumber1[i]); EEPROM.write (i+30,  TelNumber2[i]); }}}

              else if (!currStr.compareTo("WriteNumber2")&& isStringMessage == 1)   { 
                SaveNumber2 = 1; startNumber1SMS(); mySerial.println(F("Otpravte lyuboye SMS s nomera2 dlya sochraneniya nomera")); EndSMS();} 

                                                                        

                                                     
               else if (!currStr.compareTo("Balance"))    SMSbalance();
            isStringMessage = 0;
                }
              else if (isStringMessage==10){ if (!currStr.compareTo("WriteNumber1"))   { TelNumber1 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+10, BufferNumber[i]);}
              startNumber1SMS(); mySerial.println(F("Tel Number#1 is saving in memory"));  mySerial.print("Tel#1: ");  mySerial.println (TelNumber1); EndSMS();
              } 
                                             else if (!currStr.compareTo("ZAPROS"))   { SMSzapros();}   
                                             else if (!currStr.compareTo("ZAPROSTEL"))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС            
               isStringMessage = 0;
              
              }           



                
         else if (isStringMessage==0) {  if (TelNumber1!="000000000000" && !SaveNumber2 && TelNumber1!="яяяяяяяяяяяя"){
         
                     if (currStr.startsWith("+CMT: \""+TelNumber1)) { isStringMessage = 1; KTOzapros = 1; }   
                else if (currStr.startsWith("+CMT: \""+TelNumber2)) { isStringMessage = 2; KTOzapros = 2; }   
                else if (currStr.startsWith("+CUSD: 0,"))  //если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса
                  {
                       if (KTOzapros == 1) startNumber1SMS();
                  else if (KTOzapros == 2) startNumber2SMS();
                  mySerial.print (currStr);
                  EndSMS();
                  }    
                                                }

                else if    (currStr.startsWith("+CMT:") && !SaveNumber2) { isStringMessage = 10; for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];}}
                else if    (currStr.startsWith("+CMT:") && SaveNumber2) { for (int i =0; i<12; i++) {BufferNumber[i]=currStr[i+7];} TelNumber2 = BufferNumber; for (int i=0; i<12; i++) {EEPROM.write (i+30, BufferNumber[i]);}
              startNumber2SMS(); mySerial.println(F("Vash nomer sochranyon kak Number#2 v pamyati!")); 
              mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1); mySerial.print(F("Tel#2: "));  mySerial.println (TelNumber2); EndSMS(); SaveNumber2 = 0; } 
              
              } 
               
        currStr = "";
      } 
 
    else if ('\n' != currSymb) { currStr += String(currSymb);}
}


void SMSzapros()
{   if (isStringMessage == 10){
 startBufferNumberSMS();

 mySerial.println (F("Tel.number#1 has been no save in memory!"));
 mySerial.println (F("For save Tel#1 send SMS command \"WriteNumber1\""));
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  }
  
  
  
  else {
  
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 0) {if  (KTOreport == 1) startNumber1SMS();
                             else if  (KTOreport == 2) startNumber2SMS();}
        if (webasto) { mySerial.println (F("Webasto ON"));
           if (startWebasto_OK) mySerial.println (F("StartWebasto OK"));
           else mySerial.println (F("StartWebasto FAIL"));}
     else mySerial.println (F("Webasto OFF"));  

     if (engine)  mySerial.println (F("Engine ON"));
     else mySerial.println (F("Engine OFF"));  

     if (ignition)  mySerial.println (F("IGN ON"));
     else mySerial.println (F("IGN OFF"));  

     if (ohrana)  mySerial.println (F("OHRANA ON"));
     else mySerial.println (F("OHRANA OFF"));  

     if (trevoga)  mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
     
  mySerial.print(F("Battery: ")); mySerial.print (Vpit); mySerial.println(F("V"));
  mySerial.print(F("Engine: ")); mySerial.print (TempEngineC); mySerial.println(F("*C"));
  mySerial.print(F("Vyhlop: ")); mySerial.print (TempVyhlopC); mySerial.println(F("*C"));
  mySerial.print(F("Ulica: ")); mySerial.print (TempUlicaC); mySerial.println(F("*C"));
  mySerial.print(F("Salon: ")); mySerial.print (TempSalonC); mySerial.println(F("*C"));  
  mySerial.print(F("Protocol: "));
       if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  if (Protocol!=1) {mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));}
  mySerial.print(F("GSM Resets: ")); mySerial.println (ResetNumber); 
 
  }  
   EndSMS();                                 
}

void SMSzaprosTEL(){
  if (isStringMessage == 1) { startNumber1SMS();}
  else if (isStringMessage == 2) { startNumber2SMS();}
  else if (isStringMessage == 10) { startBufferNumberSMS();}
  
  
  mySerial.print(F("Tel#1: ")); mySerial.println(TelNumber1);
  mySerial.print(F("Tel#2: ")); mySerial.println(TelNumber2); 
  if (TelNumber1!="000000000000" && TelNumber1!="яяяяяяяяяяяя"){
  mySerial.print(F("Protocol: "));
  if (Protocol==1) mySerial.println(F("GND Impulse"));
  else if (Protocol==2) mySerial.println(F("W-BUS"));
  else if (Protocol==3) mySerial.println(F("+12V Potencial"));
  mySerial.print(F("Webasto Time: ")); mySerial.print (TimeWebasto/60000UL); mySerial.println(F("min"));
  mySerial.print(F("Resets: ")); mySerial.println (ResetNumber); 
  }
  EndSMS();                                 
  }


void SMSbalance() {
digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
      delay (150);
mySerial.print(F("AT+CMGF=1\r"));
      delay(200);
mySerial.println (F("AT+CUSD=1,\"#100#\""));    // команда на замену на транслит *111*6*2# у МТС 
      delay(2000);  
digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль 
      delay (150);  
                             
     
}


void AlarmSMS() {
 
 startNumber1SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 startNumber2SMS();
mySerial.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 alarmSMS = true;
}

void W_Bus (){
if (webasto) {
    if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){

 for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    //делаем периодическое поддержание связи W-BUS
    // наверное сканает отправка сообщения о состоянии котла
    // т.е. ,например, отправляем периодически запрос на показания датчиков
    // состоянием работы котла будет наличие или отсутствие пламени
if (flagStartPresent) {for (int i = 0; i<5; i++) Serial.write (Zapusk21[i]); }
//else {for (int i = 0; i<5; i++) Serial.write (StateMessage[i]);}
flagStartPresent = !flagStartPresent;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





else if (StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){
  for (int i = 0; i<4; i++) Serial.write (Stop[i]); 
StopMessageRepeat++; 
StartMessageRepeat = 0;
   Prev_PeriodW_BusStartStop = millis();
  
  
  }

}



void Reset_gsm (){
  if (millis()-prevReset>(unsigned long)intervalReset*60000UL){
  digitalWrite (DTR, LOW); delay (130);
  mySerial.println (F("AT")); 
  timerenabledWaitOK = 1; timerWaitOK = millis();
  gsmOK= false;
  prevReset = millis(); }

if (timerenabledWaitOK && millis()-timerWaitOK>6000) {
    timerenabledWaitOK = 0;
    if (!gsmOK) {
      mySerial.println (F("AT")); timerenabledWaitOK = 1; timerWaitOK = millis();
      errors++; if (errors>5) errors = 5; 
      
      }
}

  
 if (!gsmOK)  { 
  if (mySerial.available()>0){                                   
    char currSymb = mySerial.read();                           
    if ('\r' == currSymb) {                                      
                                  
       if (!currStr.compareTo("OK")) {   gsmOK = true;  timerenabledWaitOK = 0; errors=0; digitalWrite (DTR, HIGH);}
       currStr = "";                                           
    }
    
    else if ('\n' != currSymb) {currStr += String(currSymb);}}}
    
    
    if (errors>=5) Reset();
    
    }

 void Reset(){
     
      if (!resettimer) {digitalWrite (ResetGSM, 0); resettimer = 1; resetTimer = millis();} 
else if (millis()- resetTimer>6000 ) {
digitalWrite (ResetGSM, 1); 
resettimer = 0; 
errors=0; 
ResetNumber++; 
EEPROM.write (0, ResetNumber);
delay (3000); NastroykaGSM ();}
           
      
      
      }

Как всегда это всё альфа версия и нужно всё проверять. Не успеваю в одно лицо проект тащить. Может кто соберёт, проверит. 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

MaksVV пишет:
Помогите допилить три вещи. 

1. Запись номера телефона пользователя по смс, ну или по звонку. 

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

3. Научить всё это дело засыпать, чтоб поменьше кушало энергии. замерял вроде где-то 25...30 мА. Многовато, если учесть ещё потребление сигнализации старлайн. 

таким образом, если дополнения заработают как надо, все хотелки почти реализованы. 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

MaksVV пишет:

попробовал добавить в проект реализацию энергосберегающего режима SIM800L. По способу, указанному тут . 

принципиальная схема платы v5

Плата v5

Скетч v2.4.

Как всегда это всё альфа версия и нужно всё проверять. Не успеваю в одно лицо проект тащить. Может кто соберёт, проверит. 

Готов сегодня - завтра проверить. Так понял (быстро пробежав по схеме) добавлены 2 резистора по входу DTR c А6 и всё!?

Один вопрос только - хочу сразу проверить потребление тока, через какое время по программе модуль переходит в режим сна?

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Странно, добавил библиотеку титанового велосипеда (с сайта автора - там архив zip) - всё удачно добавилось, но при компиляции ругается, даже просто взял загрузил пример из IDE и всё равно ругатся. В архиве почему-то нет файла .cpp - что за глюк не пойму. Пробовал сносить и заново ставить прогрумму - ничего не получается - первый Ваш скетч загружается без проблем а начиная уже с "кнопки" - ошибки при компиляции.

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

uu5jhu пишет:
Так понял (быстро пробежав по схеме) добавлены 2 резистора по входу DTR c А6 и всё!?

Да

uu5jhu пишет:
Один вопрос только - хочу сразу проверить потребление тока, через какое время по программе модуль переходит в режим сна?

Из сетапа вызыается функция NastroykaGSM() после которой должнен уснуть, т.е. Примерно через 10...15 сек после включения питания. 

 

uu5jhu пишет:

Странно, добавил библиотеку титанового велосипеда (с сайта автора - там архив zip) - всё удачно добавилось, но при компиляции ругается, даже просто взял загрузил пример из IDE и всё равно ругатся. В архиве почему-то нет файла .cpp - что за глюк не пойму. Пробовал сносить и заново ставить прогрумму - ничего не получается - первый Ваш скетч загружается без проблем а начиная уже с "кнопки" - ошибки при компиляции.

вот у человека вроде получилось 

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Что было сказать не могу но после полного удаления, чистки и новой установки всё пошло. Пробовал оба скетча v2.1 и v2.4........ странно но спустя несколько секунд (измерения по потребляемому току проводил мультиметром Fluke) что в с первым что со вторым скетчем потребляемый ток модуля SIM800 составил 2-5 мА. Общий потребляемый ток конструкции (спустя некоторое время) составляет 36-38 мА. Разницы поему-то не обнаружил. (Не знаю влияет ли на это отсутсвие кнопки - у меня на А3 ничего не заведено).

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

т.е. если отсоединить модуль SIM800 будет ток 30мА? 

MaksVV
Онлайн
Зарегистрирован: 06.08.2015

я думал он львиную долю потребляет

uu5jhu
Offline
Зарегистрирован: 21.11.2017

Сейчас скажу точно сколько