Сделал задержку 4 секунды вместо 3.5 , и глюк прошел вроде, глюк себя проявлял при снятии аккума или после подключения питания после прошивки, как будто синхронизация модема с друиной не происходила или может dc-dc медленно раскачивается.
А какой предохранитель ставил? Можно маркировку, размер?
Детальки едут, остальное надо докупать)
Такие самовосстанавливаемые смд в размере 1206. Взял на 1,5А. напряжение у них до 25В. Можно по 12В линии поставить на 2А, а по 4В линии на 1,5. Я везде на 1,5А поставил, т.к. купил только их. Работает.
vgk_com, ну как пришли платы ? собрал девайс? готовлю обновление скетча. в планах добавить взаимодействие смартфона с девайсом по MQTT протоколу, то бишь по GPRS. реагирует так гораздо быстрее смс ок. и приятнее пользоваться. к тому же дешевле. но вот скетч усложняется конечно, не знаю влезет ли все. нужно оптимизировать.
Завтра отвечу , я его только сегодня в новую промини залил , завтра потестю. А глюк со снятием аккумулятора повторился, снимал аккум. на подзарядку, когда поствил решил проверить. отправил смс запрос состояния, отчет о том что смс принята пришел , а в ответ опять тишина, разъем питания передёрнул и все заработало, не помогла значит установка в 4 секунды вместо 3.5. Не могу понять почему так происходит, по конструктиву все как у вас, даже преобразователь такой же , реле правда немного другое на проводках под под модемом на боку приклеено, а так все как у вас. Ну и разъема у меня нет такого , все на проводах нуружу выведено, но у там всего то на кнопку , на датчики и 3 провода питание и wbus.
Это вообще крутяк крутой будет , через тырнет лучше , а то смски вчерашний день , а так вашему творению не будет конкурента, с его возможностями, я ни во одном аналогичном устройсве не видел функции чтения и стирания ошибок. Да и смски нынче дороги , в моем тарифе на симкоме всего 200 смс но зато 5 гигов тырнета, по протоколу MQTT его на все хватит, на личном смартфоне 25 гигов в месяц, а так плачу еще за безлим смс на своем смартфоне и за безлим на симкоме.
ага. причем на протокол MQTT даже при постоянном обмене данными раз в минуту, нужно максимум 50 Мб (Мегабайт!, Карл) в месяц - копейки. Единственный совсем не большой минус - это потребление тока увеличится аж целых на 3...4 мА, от части даже из за того, что сигнальный светодиод на сим800 при открытой GPRS сессии очень часто мигает.
Платы пришли, пока не собирал. На улице уже почти тепло, вебаста не нужна. Буду готовиться к следующей зиме. Да и реле с разъемами еще не пришло с Китая. Уже больше месяца идут, но уже в России. На счет mqtt это классно, но наверное нужно переходить на другую платформу, памяти маловато.
скачал старую версию gsm tinker 4.01 на 4пда , установил и запретил обновляться. Все работает по старому , долбаный гугл , будь он проклят со своими политиками.
Я сразу не сообразил , у меня такая же надпись вылазила , я поставил галку и закрыл сообщение , я подумал что полная версия платная . читать наверное разучился .
заметил проблему с хардовым ресетом SIM800 при помощи реле. Еcтественно ресет я не ждал, а специально инициировал. Дело в том, что при ресете реле размыкает питание сим800 на 6 секунд,тут все гуд, но вот когда реле обратно замыкается, подавая вновь питание на сим800, происходит почему-то также ресет самой ардуины.
также отмечено, что если вытащить сим800 (т.е. реле просто щёлкает впустую) ардуина уже НЕ ресетится, также ардуино НЕ ресетится если просто вытащить сим800 и вставить обратно (т.е. НЕ в момент процедуры ресета сим800). Еще пробовал вытащить сим800 в момент процедры ресета, когда реле прерывает питание, но вставить уже чуть чуть позже замыкания реле, то тоже ардуино НЕ ресетится.
Думал что:
- вступая в работу, сим800 в начале потребляет много и происходит просадка по питанию ардуино (она питается от тех же 4В). Померил этот момент осциллографом - всё четко, линия 4В даже не шелохнётся.
- выносная антенна даёт какието наводки на ардуино, отключал - не помогает;
Попробую ещё померить осликом, что на пине "ресет" дуни и контактах рх тх в момент проявления косяка. Если у кого есть какие соображения по причинам просходящего, рад выслушать.
потратил часа два чтобы найти данный косяк с незапланированным рестартом ардуины. Все таки ардуина ресетилась из-за нехватки питания. Хотя напряжение не проседает (причём совсем), видимо по току идёт нехватка. Припаял ещё один кондёр 470мФ прямо к ноге VCC ардуино и проблема ушла. Надо опять плату модернизировать)) А на готовых платах опять колхоз с конденсатором будет.
Может идет какой нибудь кратковременный выброс по питанию, а доп. конденсатор его гасит, потому что если напряжение не проседает совсем ,то и ток не должен проседать , или искровая помеха от реле , без нагрузки ее не будет, как то была подобная проблема , долго искали почему на ниссан эксперт ошибка вылазила , по ДПКВ, а проблема была в игольчатом выбросе от свечей зажигания новых , но не тех что надо , а наш осцыллограф не мог эту иголку поймать толком , кое как ее заметил.
если речь про hydronic 1 - управлять можно и по шине и по плюсу. Управляя по шине, лишаемся возможности получать диагностические параметры, поэтому рентабельнее включать по плюсу, а по шине вытягивать данные. По другим еберам не разбирался.
в моем случае котел D5wz. он вроде бы первый hydrinic. я его хочу из догревайки превратить в полноценный предпусковой и управлять пуском/стопом дистанционно. что в данном возможно по плюсу?
Да. Приеду с отпуска займусь. В середине августа. Конструкцию mqtt опробовал на умном доме. Вещь очень удобная . Работает надежно пока. Один раз был сбой на сервере mqtt. Не работало полчаса. Но в таких случаях можно и с тринкета смсками порулить. Траффик за месяц целых 5 мегабайт. Смски теперь нужны только для экстренного оповещения. Или при сбоях сервиса мкютт
Да. Приеду с отпуска займусь. В середине августа. Конструкцию mqtt опробовал на умном доме. Вещь очень удобная . Работает надежно пока. Один раз был сбой на сервере mqtt. Не работало полчаса. Но в таких случаях можно и с тринкета смсками порулить. Траффик за месяц целых 5 мегабайт. Смски теперь нужны только для экстренного оповещения. Или при сбоях сервиса мкютт
Как вариант можно использовать DTMF для управления..
Вечер добрый уважаемый MaksVV, собрал сей девайс, при тестировании не мог получить ответы на отправленнве запросы, пока не додумался что причина в том что мой номер телефона на одну цифру короче (11знаков) попробывал другой номер (12знаков) всё работает идеально. Есть ли вожможность сделать изменения в коде чтобы номер телефона не был привязан к количеству знаков.
Постараюсь подправить в ближайшее время плату. Добавив конденсатор и диоды, чтобы развязать питание мк и джсм . После этого можно в заказ
Я тут немного пробовал поменять все местами( развернул модуль, чтобы можно было sim вставить не разбирая корпуса) и под свой корпус, но теперь не уверен в правильности разводки. Может закину свой проект и библиотеки элементов, а вы сможете глянуть на правильность?
Добрый вечер! Наконец-то добрался до сборки платы, скоро зима а я еще не опробовал. Сижу второй вечер, уже мозги кипят, а плата не хочет работать. Не пойму в чем дело. Уже ради пробы просто подключил UNO к сим800 модулю проводами без платы, залил сперва очищающую прошивку потом прошивку v.3.66 и ни как не реагирует на смс запрос номеров ни на добавление номера. Обратных смс нет. Деньги на симке есть. Не чего не трогая перепрошиваю на другой код проверки сим800, все работает и смс отправляет и принимает.
При проверки работы к плате кроме питания не чего не подключал. СМС без подключения котла работать ведь должны?
плата 8.91. и Гербер файлы для отправки на изготовление в Китай рекомендую здесь . Развязал питание сим800 и ардуины через диоды и добавил кондёр по питанию. Теперь на dc-dc нужно будет настроить такое напряжение, чтобы после диода на сим800 было 4В. Думаю это будет около 5В. Проверяйте, лишним не будет. Косяки не исключены.
Сделал задержку 4 секунды вместо 3.5 , и глюк прошел вроде, глюк себя проявлял при снятии аккума или после подключения питания после прошивки, как будто синхронизация модема с друиной не происходила или может dc-dc медленно раскачивается.
Детальки едут, остальное надо докупать)
Такие самовосстанавливаемые смд в размере 1206. Взял на 1,5А. напряжение у них до 25В. Можно по 12В линии поставить на 2А, а по 4В линии на 1,5. Я везде на 1,5А поставил, т.к. купил только их. Работает.
Весь список деталей пост #254
vgk_com, ну как пришли платы ? собрал девайс? готовлю обновление скетча. в планах добавить взаимодействие смартфона с девайсом по MQTT протоколу, то бишь по GPRS. реагирует так гораздо быстрее смс ок. и приятнее пользоваться. к тому же дешевле. но вот скетч усложняется конечно, не знаю влезет ли все. нужно оптимизировать.
и жду отчета о последнем скетче от Dushman7776, как работает?
Завтра отвечу , я его только сегодня в новую промини залил , завтра потестю. А глюк со снятием аккумулятора повторился, снимал аккум. на подзарядку, когда поствил решил проверить. отправил смс запрос состояния, отчет о том что смс принята пришел , а в ответ опять тишина, разъем питания передёрнул и все заработало, не помогла значит установка в 4 секунды вместо 3.5. Не могу понять почему так происходит, по конструктиву все как у вас, даже преобразователь такой же , реле правда немного другое на проводках под под модемом на боку приклеено, а так все как у вас. Ну и разъема у меня нет такого , все на проводах нуружу выведено, но у там всего то на кнопку , на датчики и 3 провода питание и wbus.
Это вообще крутяк крутой будет , через тырнет лучше , а то смски вчерашний день , а так вашему творению не будет конкурента, с его возможностями, я ни во одном аналогичном устройсве не видел функции чтения и стирания ошибок. Да и смски нынче дороги , в моем тарифе на симкоме всего 200 смс но зато 5 гигов тырнета, по протоколу MQTT его на все хватит, на личном смартфоне 25 гигов в месяц, а так плачу еще за безлим смс на своем смартфоне и за безлим на симкоме.
ага. причем на протокол MQTT даже при постоянном обмене данными раз в минуту, нужно максимум 50 Мб (Мегабайт!, Карл) в месяц - копейки. Единственный совсем не большой минус - это потребление тока увеличится аж целых на 3...4 мА, от части даже из за того, что сигнальный светодиод на сим800 при открытой GPRS сессии очень часто мигает.
Скетч 3.65 работает всё, по крайней мере то что относиться к котлу, и даже глюка ,описанного ранее, не заметил. Ну и прописку далласов не проверял.
Сегодня обновился gsm trinket и теперь не отправляет и не принимает сообщения , пишет что запрещено новым законом, где взять старую версию?
Платы пришли, пока не собирал. На улице уже почти тепло, вебаста не нужна. Буду готовиться к следующей зиме. Да и реле с разъемами еще не пришло с Китая. Уже больше месяца идут, но уже в России. На счет mqtt это классно, но наверное нужно переходить на другую платформу, памяти маловато.
скачал старую версию gsm tinker 4.01 на 4пда , установил и запретил обновляться. Все работает по старому , долбаный гугл , будь он проклят со своими политиками.
а у меня, когда сейчас из плеймаркета ставлю джсм тринкет, он сам предлагает скачать нормальную версию где все работает.
Я сразу не сообразил , у меня такая же надпись вылазила , я поставил галку и закрыл сообщение , я подумал что полная версия платная . читать наверное разучился .
заметил проблему с хардовым ресетом SIM800 при помощи реле. Еcтественно ресет я не ждал, а специально инициировал. Дело в том, что при ресете реле размыкает питание сим800 на 6 секунд,тут все гуд, но вот когда реле обратно замыкается, подавая вновь питание на сим800, происходит почему-то также ресет самой ардуины.
также отмечено, что если вытащить сим800 (т.е. реле просто щёлкает впустую) ардуина уже НЕ ресетится, также ардуино НЕ ресетится если просто вытащить сим800 и вставить обратно (т.е. НЕ в момент процедуры ресета сим800). Еще пробовал вытащить сим800 в момент процедры ресета, когда реле прерывает питание, но вставить уже чуть чуть позже замыкания реле, то тоже ардуино НЕ ресетится.
Думал что:
- вступая в работу, сим800 в начале потребляет много и происходит просадка по питанию ардуино (она питается от тех же 4В). Померил этот момент осциллографом - всё четко, линия 4В даже не шелохнётся.
- выносная антенна даёт какието наводки на ардуино, отключал - не помогает;
Попробую ещё померить осликом, что на пине "ресет" дуни и контактах рх тх в момент проявления косяка. Если у кого есть какие соображения по причинам просходящего, рад выслушать.
потратил часа два чтобы найти данный косяк с незапланированным рестартом ардуины. Все таки ардуина ресетилась из-за нехватки питания. Хотя напряжение не проседает (причём совсем), видимо по току идёт нехватка. Припаял ещё один кондёр 470мФ прямо к ноге VCC ардуино и проблема ушла. Надо опять плату модернизировать)) А на готовых платах опять колхоз с конденсатором будет.
Может идет какой нибудь кратковременный выброс по питанию, а доп. конденсатор его гасит, потому что если напряжение не проседает совсем ,то и ток не должен проседать , или искровая помеха от реле , без нагрузки ее не будет, как то была подобная проблема , долго искали почему на ниссан эксперт ошибка вылазила , по ДПКВ, а проблема была в игольчатом выбросе от свечей зажигания новых , но не тех что надо , а наш осцыллограф не мог эту иголку поймать толком , кое как ее заметил.
ну возможно. Я вроде растягивал осциллограмму. Иголок не было. Хотя осцил да, дешевый у меня.
с webasto все хорошо. а как быть с eberspacher. можно ли им управлять и в каком обьеме?
если речь про hydronic 1 - управлять можно и по шине и по плюсу. Управляя по шине, лишаемся возможности получать диагностические параметры, поэтому рентабельнее включать по плюсу, а по шине вытягивать данные. По другим еберам не разбирался.
Всё это ещё НЕ реализовано в сабжевом девайсе.
Протокол Ebera 1 я исследовал раньше. Инфа тут
в моем случае котел D5wz. он вроде бы первый hydrinic. я его хочу из догревайки превратить в полноценный предпусковой и управлять пуском/стопом дистанционно. что в данном возможно по плюсу?
а инфу то уже собрали как превратить в предпусковой? Выше по ссылке самый лучший форум по печкам. Штудируйте.
А как обстоят дела с MQTT? И с новой версией вашего девайса. Лето пролетит очень быстро , пора начинать готовить сани.
Да. Приеду с отпуска займусь. В середине августа. Конструкцию mqtt опробовал на умном доме. Вещь очень удобная . Работает надежно пока. Один раз был сбой на сервере mqtt. Не работало полчаса. Но в таких случаях можно и с тринкета смсками порулить. Траффик за месяц целых 5 мегабайт. Смски теперь нужны только для экстренного оповещения. Или при сбоях сервиса мкютт
Примерно так будет выглядеть панель управления
Классно выглядет, а программка для андроида или IOS.
mqtt dash. Android. На ios может тоже есть, не знаю.
Класс, а по железу будет что-нибудь меняться ? Нужно что-нибудь заказывать у братьев китайцев?
Нет , кроме косяка озвученного чуть выше , вроде пока нечего менять
Выкинул из своей схемы предохранитель полимерный, без него модуль связи работает стабильнее.
Да. Приеду с отпуска займусь. В середине августа. Конструкцию mqtt опробовал на умном доме. Вещь очень удобная . Работает надежно пока. Один раз был сбой на сервере mqtt. Не работало полчаса. Но в таких случаях можно и с тринкета смсками порулить. Траффик за месяц целых 5 мегабайт. Смски теперь нужны только для экстренного оповещения. Или при сбоях сервиса мкютт
Как вариант можно использовать DTMF для управления..
ПОчти конец лета . можно готовить сани .
Так и есть один котел на 99той , и еще один ево . уже и прикупл осцилограф .
Вечер добрый уважаемый MaksVV, собрал сей девайс, при тестировании не мог получить ответы на отправленнве запросы, пока не додумался что причина в том что мой номер телефона на одну цифру короче (11знаков) попробывал другой номер (12знаков) всё работает идеально. Есть ли вожможность сделать изменения в коде чтобы номер телефона не был привязан к количеству знаков.
?
да можно. какой скетч используете?
v3.66 , это 3,65 переделанный под 11 значный номер тел.
char ver[] = "Firmware 3.66"; // версия прошивки //----------------------------------название ячеек еепром---------------------------------------------------------------- #include <EEPROM.h> enum Cells { ResetNumber_cell, //0 TimeWebasto_cell, //1 ProtocolSTART_cell, //2 StartByte_cell, //3 ProtocolSTATUS_cell, //4 Heater_cell, //5 delta_cell, //6 TelNumber1_cell =20, //20 TelNumber2_cell =40, //40 DallasAddr_cell =60 //60 }; //-------------------------------------для voltmetr----------------------------------------------------------------------- float vout = 0.0; // Напряжение на входе аналового входа float Vpit = 0.0; // Измеряемое напряжение на выходе ИБП int volt = 0; // Напряжение на входе АЦП //------------------- распиновка ног ардуино (плата весий 8.5-8.8)-------------------------------------------------------- #define OutWebasto_12V 2 // это +12В выход потенциала вкл/выкл вебасто (напрямую к котлу без таймера). #define Dallas_pin 3 // пин шины OneWire для датчиков даллас #define DopOn 4 // сюда доп канал от сигналки на включение вебасто #define DopOff 5 // сюда доп канал от сигналки на выключение вебасто #define Ohrana 6 // Сюда состояние охраны сигналки #define Trevoga 7 // Сюда состояние тревоги #define IGN 8 // Сюда состояние зажигания #define Sost 9 // Сюда состояние вебасто (+12В когда работает) #define ResetGSM 12 // пин ресета GSM подключен к реле, разрывающее питание модуля. #define Eng 14 // (А0) Сюда состояние работы ДВС #define StatusWebastoLED 15 // (А1) пин LED индикация включенности котла #define StartButtonpin 16 // (А2) пин тактовой кнопки вкл/выкл котла #define DTR 17 // пин (А3), управляющий энергосберегающим режимом GSM модуля #define StartEng 18 // (A4) это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги. #define OutWebasto_GndImp 19 // (A5) это импульсный минусовой выход вкл/выкл вебасто (к впайке к кнопке таймера). #define Voltmeter_pin A7 // пин, которым измеряем напряжение питания #define StartButton 0 // программный номер тактовой кнопки вкл/выкл котла const bool RelayON = 1; // логика управления реле ресета GSM, в данном случае включается высоким уровнем на пине #define GSM_RX 10 // пин софт RX Arduino для соединения с TX модуля SIM800 #define GSM_TX 11 // пин софт TX Arduino для соединения с RX модуля SIM800 /* //------------------- распиновка ног ардуино (плата весий 5)--------------------------------------------------------------- #define Dallas_pin 2 // пин шины OneWire для датчиков даллас #define OutWebasto_12V 3 // это +12В выход потенциала вкл/выкл вебасто (напрямую к котлу без таймера). #define DopOn 4 // сюда доп канал от сигналки на включение вебасто #define DopOff 5 // сюда доп канал от сигналки на выключение вебасто #define Ohrana 6 // Сюда состояние охраны сигналки #define Trevoga 7 // Сюда состояние тревоги #define StartEng 8 // это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги. #define Sost 9 // Сюда состояние вебасто (+12В когда работает) #define IGN 10 // Сюда состояние зажигания #define Eng 11 // Сюда состояние работы ДВС #define OutWebasto_GndImp 12 // это импульсный минусовой выход вкл/выкл вебасто (к впайке к кнопке таймера). #define StatusWebastoLED 13 // пин индикация включенности котла #define ResetGSM 16 // пин ресета GSM (A2) подключен к реле, разрывающее питание модуля. #define StartButtonpin 17 // пин тактовой кнопки вкл/выкл котла #define DTR 19 // пин (А5), управляющий энергосберегающим режимом GSM модуля #define StartButton 0 // программный номер тактовой кнопки вкл/выкл котла const bool RelayON = 0; // логика управления реле ресета GSM, в данном случае включается низким уровнем на пине #define GSM_RX 14 // пин софт RX Arduino для соединения с TX модуля SIM800 #define GSM_TX 15 // пин софт TX Arduino для соединения с RX модуля SIM800 */ //------------------------------------для GSM модуля---------------------------------------------------------------------- #include <SoftwareSerial.h> SoftwareSerial SIM800 (GSM_RX, GSM_TX);//Rx, Tx //UART для соединения с GSM модулем String currStr = ""; String TelNumber[] = {"", "00000000000", "00000000000", "00000000000"}; byte isStringMessage = 0; byte KTOreport = 1; // флаг кто запросил отчет о запуске котла или ДВС byte KTOzapros = 0; // флаг кто запросил баланс или запрос параметров uint32_t prevReset=0; // для таймера периодичности проверки (командой "АТ") byte intervalReset = 15; // каждые столько мин будет проверка жив ли GSM модуль uint32_t timerWaitOK=0; // для таймера ожидания ответа после посылки команды "АТ" bool timerenabledWaitOK=false; // для таймера ожидания ответа после посылки команды "АТ" byte NoAnswersGSM=0; // количество неответов от GSM модуля bool gsmOK = 1; // флаг есть связь с GSM модулем или нет bool resettimer = 0; // для таймера удерживания реле в режиме сброс питания uint32_t resetTimer=0; // для таймера удерживания реле в режиме сброс питания byte ResetNumber = 0; // количество ресетов GSM модуля для статистики (хранится в еепром) //------------------- для шины 1-wire и датчиков DS18B20--------------------------------------------------------------------- #include <OneWire.h> // библиотека для DS18B20 OneWire ds(Dallas_pin); // датчики DS18B20 на нужный пин enum TempC {VyhlopC, EngineC, UlicaC, SalonC, size_arrayTemp}; // перечисление нужных температур (в конце размер массива температур) // ниже соответствие адресов датчиков различным температурам byte DS18B20 [size_arrayTemp][10] = { {0x28, 0xFF, 0xB2, 0xB5, 0xC1, 0x17, 0x05, 0xD1, VyhlopC, -100}, {0x28, 0xFF, 0xD3, 0xE2, 0xC1, 0x17, 0x04, 0x0D, EngineC, -100}, {0x28, 0xFF, 0xF8, 0xBC, 0xC1, 0x17, 0x04, 0x48, UlicaC, -100}, {0x28, 0xFF, 0x3F, 0xB7, 0xC1, 0x17, 0x05, 0xF1, SalonC, -100} }; byte delta = 50; // разница температур выхлопа и улицы, выше которой считается, что пламя в котле есть. int8_t HeaterC = -100; //---------------------------для организации W-BUS и различные таймеры----------------------------------------------------------- #include <Button.h> Button test; #define K_LINE Serial //UART для соединения с шиной котла #define TX 1 #define NEED 1 #define READY 10 byte header = 0; // состояние заголовка byte message_size = 0; // размер тела принимаемого сообщения, кол-во байт byte j = 2; // инкремент byte n = 2; const byte bufsize = 140; // размер буфера принятого сообщения byte buf [bufsize] = {0}; // буфер принятого сообщения byte checksum = 0; // контрольная сумма входящего сообщения uint32_t curmillis = 0; // снимок системного времени byte delaybyte_TX = 0 ; // задержка между байтами отправляемого сообщения byte waitbyte_RX = 1; // задержка, мс для успевания заполнения буфера RX (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) uint32_t timerdelay = 0; // таймер ожидания байт (для успевания заполнения буфера УАРТ) bool Delay = 0; // таймер ожидания байт (для успевания заполнения буфера УАРТ) #define TIMER_DELAY Delay = 0; timerdelay = curmillis // включение этого таймера uint32_t prevRESETheader=0; // таймер сброса заголовка если в момент приёма сообщения данные оборвались bool RESETheader_timer = 0; // таймер сброса заголовка если в момент приёма сообщения данные оборвались // команды для котлов ЭВО byte StartByte = 0x20; byte HEATER_BEGIN[] {0x51, 0x0A}; byte HEATER_START[] {StartByte, 0x3B}; byte HEATER_PRESENCE[] {0x44, StartByte, 0x00}; byte HEATER_STOP[] {0x10}; byte HEATER_STATUS_VEVO[] {0x50, 0x05}; byte HEATER_STATUS_EVO[] {0x50, 0x30, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x1E, 0x32}; byte HEATER_DTC_REQUEST[] {0x56, 0x01}; byte HEATER_DTC_ERASE[] {0x56, 0x03}; // команды для котлов ТТС/TTE byte START_SESSION[] {0x81}; byte REQUEST_2A10101[] {0x2A, 0x01, 0x01}; byte REQUEST_2A10102[] {0x2A, 0x01, 0x02}; byte REQUEST_2A10105[] {0x2A, 0x01, 0x05}; byte REQUEST_DTC[] {0xA1}; byte START_TTC[] {0x31, 0x22, 0xFF}; byte STOP_TTC[] {0x31, 0x22, 0x00}; enum needAction_ {NO_ACTION, NEED_SMSZAPROS, NEED_SERVICEINFO, NEED_DTCCLEAR};// возможные действия, стоящие в очереди byte needAction = NO_ACTION; // переменная действия, стоящего в очереди enum ProtocolSTATUS_ {STATUSBUS, ANALOG}; // возможные протоколы чтения статуса котла enum ProtocolSTART_ {STARTBUS, IMPULSE, POTENCIAL}; // возможные протоколы запуска котла enum Heater_ {TTC_E, VEVO, EVO, HYDRONIC}; // тип котла byte ProtocolSTATUS = STATUSBUS; byte ProtocolSTART = STARTBUS; byte Heater = EVO; bool noData = 0; // флаг пришли ли данные от котла после запроса. byte w_bus_init = 0; //флаг проведена или нет инициализация шины w-bus (25мс LOW, 25мс HIGH для ЭВО // либо 300ms LOW, 50ms HIGH, 25ms LOW, 3025ms HIGH для TTC byte requiredmessage = 1; //флаг, что отправляем в данный момент поддержание старта, запрос параметров или запрос ошибок byte StartMessageRepeat = 0; //количество отправленных сообщений на старт котла byte StopMessageRepeat = 4; //количество отправленных сообщений на остановку котла byte TimeWebasto = 30; //время работы котла, = 30мин uint32_t EndReportMillis = 0; //переменная для таймера отправки отчета об успешности запуска котла uint32_t EndReportEngine = 0; //переменная для таймера отправки отчета об успешности запуска ДВС uint32_t Prev_PeriodW_BusMessage = 0; //переменная для таймера периодической отправки сообщений состояния котла в шину W-Bus uint32_t Prev_PeriodW_BusStartStop = 0; //переменная для таймера периодической отправки сообщений старта/стопа котла в шину W-Bus uint32_t prevdelSMS = 0; //переменная для таймера периодического удаления СМС uint32_t prevVpit = 0; //переменная для таймера периодического измерения напряжения АКБ uint32_t prevInitreset = 0; //переменная для таймера сброса инита шины bool Initreset = 0; //переменная для таймера сброса инита шины uint32_t timerInit = 0; bool timerInitflag = 0; //для таймера инита шины W-BUS uint32_t prevNeedTimer = 0; bool NeedTimer = 0; //для таймера задержки функций SMSzapros() и ServiceINFO() на время обновления параметров по шине uint32_t last_Flame = 0; //для таймера сброса флага пламени, если нет ответов от котла //для таймера создания импульса GND - для протокола запуска котла импульсом GND uint32_t timer=0; bool timerenabled=false; #define TIMEREXPIRED (curmillis-timer)>800 //для таймера - старт двигателя - импульс +5В на транзистор, в итоге минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС) uint32_t timerStartEng=0; bool timerenabledStartEng=false; #define TIMEREXPIRED_StartEng (millis()-timerStartEng)>1500 //для таймера - старт котла по W-BUS ) uint32_t timerStart_W_BUS=0; bool timerenabledStart_W_BUS=false; #define TIMEREXPIRED_Start_W_BUS (curmillis-timerStart_W_BUS)> (uint32_t)TimeWebasto * 60000UL //---------------------------------Основные переменные-------------------------------------------------------------------------------- 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; // флаг отправлена ли смс о тревоге или нет bool waterpump = 0; // флаг работы циркуляционного насоса bool plug = 0; // флаг работы штифта накаливания bool airfan = 0; // флаг работы нагнетателя воздуха bool fuelpump = 0; // флаг работы топливного насоса bool blowerfan = 0; // флаг работы вентилятора печки автомобиля byte DTC[7] ={0}; // коды неисправностей котла //---------------------------СТАРТОВЫЙ ЦИКЛ-------------------------------------------------------------------------------------------- void setup() { delay (3500); 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(StartButtonpin); // в скобках пин тактовой кнопки вкл/выкл котла (программный номер у неё будет 0) pinMode (DopOn, INPUT_PULLUP); pinMode (DopOff, INPUT_PULLUP); pinMode (Sost, INPUT_PULLUP); pinMode (Ohrana, INPUT_PULLUP); pinMode (Trevoga, INPUT_PULLUP); pinMode (IGN, INPUT_PULLUP); pinMode (Eng, INPUT_PULLUP); pinMode (OutWebasto_12V, OUTPUT); digitalWrite (OutWebasto_12V, LOW); pinMode (StartEng, OUTPUT); digitalWrite (StartEng, LOW); pinMode (13, OUTPUT); digitalWrite (13, LOW); pinMode (StatusWebastoLED, OUTPUT); digitalWrite (StatusWebastoLED, LOW); pinMode (OutWebasto_GndImp, OUTPUT); digitalWrite (OutWebasto_GndImp, HIGH); pinMode (DTR, OUTPUT); digitalWrite (DTR, HIGH); // делаем высокий, а низкий уровень будет для пробуждения GSM из "спячки" pinMode (ResetGSM, OUTPUT); digitalWrite (ResetGSM, !RelayON); // реле ресет на данный момент делаем "неактивно" SIM800.begin(19200); // сериал соединение для gsm модуля delay(100); NastroykaGSM (); TimeWebasto = EEPROM.read(TimeWebasto_cell); ProtocolSTART = EEPROM.read(ProtocolSTART_cell); ProtocolSTATUS = EEPROM.read(ProtocolSTATUS_cell); ResetNumber = EEPROM.read(ResetNumber_cell); StartByte = EEPROM.read(StartByte_cell); Heater = EEPROM.read(Heater_cell); delta = EEPROM.read(delta_cell); for (int i=0; i<11; i++) TelNumber[1][i] = EEPROM.read (i+TelNumber1_cell); for (int i=0; i<11; i++) TelNumber[2][i] = EEPROM.read (i+TelNumber2_cell); // ниже читаем из еепром адреса датчиков температуры даллас for (byte i = 0; i<size_arrayTemp; i++) { for (byte k=0; k<9; k++) DS18B20 [i][k] = EEPROM.read(DallasAddr_cell+i*10+k); } if (Heater == EVO || Heater == VEVO) K_LINE.begin(2400, SERIAL_8E1); else if (Heater == TTC_E) K_LINE.begin(10400); for (byte i=0; i<20; i++) {digitalWrite (13, !digitalRead(13)); delay (80);} digitalWrite (13,0); } //------------------------------------------ЛУП----------------------------------------------------------------------------------- void loop() { curmillis = millis(); test.read(); digitalWrite (StatusWebastoLED, webasto); //digitalWrite (13, startWebasto_OK); //digitalWrite (13, webasto); //если нажали тактовую кнопку меняем состояние котла на противоположное if (test.event_press_short (StartButton)) { if (!webasto) {StartWebasto(); report = false;} else StopWebasto(); } if (ProtocolSTATUS==ANALOG) {if (Temper(VyhlopC) - Temper(UlicaC) > delta) startWebasto_OK = 1; else startWebasto_OK = 0;} if (ProtocolSTART==IMPULSE) webasto = !digitalRead (Sost); Heater_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 (!ohrana) alarmSMS = false; if (trevoga && !alarmSMS) AlarmSMS (); if (gsmOK)readSMS(); Reset_gsm(); delSMS(); WebastoOprosImpulse (); izmereniya(); } //-----------------------------------------------------------конец луп------------------------------------------------------------- void izmereniya() { if (millis()-prevVpit>7000){ //измерение напряжения борт сети if (ProtocolSTATUS==ANALOG){ volt = analogRead(Voltmeter_pin); vout = (volt * 4.13) / 1024; Vpit = vout / (9700.0/(98930.0+9700.0)); // По формуле Vpit = vout / (R2/(R1+R2)) if (Vpit<0.09) Vpit=0.0; // Округление до нуля } // ниже измерение датчиков даллас static bool n=0; // флаг работы: запрос температуры или её чтение n=!n; if (n) {ds.reset(); // сброс шины ds.write(0xCC); // обращение ко всем датчикам ds.write(0x44); // начать преобразование (без паразитного питания) } else { for (byte i=0; i<size_arrayTemp; i++){ int Temper_ = 20; byte buff[9]; ds.reset(); ds.select(DS18B20[i]); ds.write(0xBE); // чтение регистров датчиков for (byte j=0; j<9; j++) buff[j]=ds.read(); // читаем все 9 байт от датчика ds.reset(); if (OneWire::crc8(buff, 8) == buff[8]){ // если контрольная сумма совпадает Temper_ = buff[0]|(buff[1]<<8); // читаем температуру из первых двух байт (остальные были нужны только для проверки CRC) Temper_ = Temper_ / 16; if (Temper_<150 && Temper_>-55) DS18B20[i][9] = Temper_; } else DS18B20[i][9] = -101; // если контрольная сумма не совпала, пусть t будет -101 градус. }} prevVpit=millis(); }} int8_t Temper (const byte &addressTemp) {for(byte j=0; j<size_arrayTemp; j++){if(DS18B20[j][8]==addressTemp)return(int8_t)DS18B20[j][9];} return-99;} void WebastoOprosImpulse (){ // опрос допканалов от сигнализации включения/ выключение котла и таймер импульса старт/стоп котла if (timerenabled) {if (TIMEREXPIRED) {digitalWrite (OutWebasto_GndImp, 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(); }} // цикл таймера отправки отчета об успешности запуска ДВС (отчёт через 60сек после старта) void timerReportEngine () { if(millis() - EndReportEngine > 90000ul) {EndReportEngine = millis(); reportEngine = false; SMSzapros_();}} void NastroykaGSM () { digitalWrite (DTR, LOW); // выводим из спячки GSM модуль delay (150); SIM800.println(F("AT")); //просто AT для разогреву delay(250); SIM800.println(F("AT+CMGF=1")); //устанавливает текстовый режим смс-сообщения delay(250); SIM800.println(F("AT+IFC=0, 0")); //отключает программный контроль потоком передачи данных delay(250); SIM800.println(F("AT+GSMBUSY=1")); //запрет всех входящих звонков delay(250); SIM800.println(F("AT+CNMI=1,2,2,1,0")); //включает оповещение о новых сообщениях delay(250); SIM800.println(F("AT+CMGDA=\"DEL ALL\"")); // удаляем все смс, ки delay(1500); SIM800.println(F("AT+CSCLK=1")); //включает энергосберегающий режим delay(150); digitalWrite (DTR, HIGH); // вводим в спячку GSM модуль высоким уровнем на пине DTR } void startSMS(byte stat) //__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру { if (stat==0) stat = KTOreport; digitalWrite (DTR, LOW); // выводим из спячки GSM модуль delay (150); SIM800.print(F("AT+CMGF=1\r")); delay(200); SIM800.print(F("AT+CMGS=\"")); SIM800.print(TelNumber[stat]); SIM800.println("\""); delay(200); } void EndSMS () { SIM800.println((char)26); // Команда отправки СМС delay(1500); digitalWrite (DTR, HIGH); // вводим в спячку SIM800 модуль } void delSMS () { if (millis() - prevdelSMS > 7200000ul){ //раз в 2 часа digitalWrite (DTR, LOW); // выводим из спячки SIM800 модуль delay (150); SIM800.print(F("AT+CMGDA=\"DEL ALL\"\r")); // удаляем все смс, ки delay(1500); digitalWrite (DTR, HIGH); // вводим в спячку SIM800 модуль delay (150); prevdelSMS = millis();} } void SMSzapros_ () {if (webasto)SMSzapros(); else {NeedTimer = 1; prevNeedTimer = curmillis; needAction = NEED_SMSZAPROS; w_bus_init = 1;}} void readSMS() //_____Цикл чтения входящих СМС-сообщений______________ { if (!SIM800.available()) return; static bool SaveNumber2 = 0; // флаг когда необходима запись номера#2, он true char currSymb = SIM800.read(); if ('\r' == currSymb) { if (isStringMessage!=0&&isStringMessage!=3) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом { if (!currStr.compareTo("ZAPROS")) {SMSzapros_();} // Передача параметров по СМС else if (!currStr.compareTo("ZAPROSTEL")) {SMSzaprosTEL();} // Передача номеров телефонов пользователей по СМС else if (!currStr.compareTo("Service-info")) {if (webasto) ServiceINFO(); else {NeedTimer = 1; prevNeedTimer = curmillis; needAction = NEED_SERVICEINFO;w_bus_init = 1;}} // Передача сервисной информации по СМС else if (!currStr.compareTo("GSMResets-0")) {ResetNumber=0; EEPROM.write (ResetNumber_cell, ResetNumber); ServiceINFO();} //сброс счетчика ресетов GSM модуля else if (!currStr.compareTo("Version")) {startSMS(isStringMessage); SIM800.println (ver); EndSMS ();} //запрос версии ПО else if (!currStr.compareTo("Erase DTC")) {NeedTimer = 1; prevNeedTimer = curmillis; needAction = NEED_DTCCLEAR; if (w_bus_init == 0) w_bus_init = 1;} //запрос на стриание ошибок else if (!currStr.compareTo("Signal-level")) {digitalWrite (DTR, LOW); delay (150); SIM800.println(F("AT+CSQ")); digitalWrite (DTR, HIGH);} // запрос уровня сигнала GSM else if (!currStr.compareTo("Webasto-ON")) { startSMS(isStringMessage); SIM800.println(F("Webasto ")); if (!webasto) {StartWebasto (); KTOreport = isStringMessage;} else SIM800.println(F("uzhe ")); SIM800.println (F("vkluchena")); EndSMS();} else if (!currStr.compareTo("Webasto-OFF")) {startSMS(isStringMessage); SIM800.println(F("Webasto ")); if (webasto)StopWebasto (); // если получили команду на выключение и вебаста в настоящий момент включена - выключаем else SIM800.println(F("uzhe ")); SIM800.println(F("otkluchena"));EndSMS();} // если получили команду на включение ДВС и он в настоящий момент выключен - включаем else if (!currStr.compareTo("Engine-ON")) {startSMS(isStringMessage); SIM800.println(F("Dvigatel ")); if (!engine) { digitalWrite (StartEng, HIGH); timerStartEng=millis(); timerenabledStartEng=true; reportEngine = true; EndReportEngine = timerStartEng; KTOreport = isStringMessage;} else SIM800.println(F("uzhe ")); SIM800.println(F("start")); EndSMS();} else if (!currStr.compareTo("Engine-OFF")) {startSMS(isStringMessage); SIM800.println(F("Dvigatel ")); if (engine){ digitalWrite (StartEng, HIGH); timerStartEng=millis(); timerenabledStartEng=true; reportEngine = false;} // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем else SIM800.println(F("uzhe ")); SIM800.println(F("ostanovlen")); EndSMS();} else if (!currStr.compareTo("Impulse")) {if (!webasto) {ProtocolSTART = IMPULSE; EEPROM.write(ProtocolSTART_cell,ProtocolSTART); startSMS(isStringMessage); SIM800.println(F("zapusk GND_impulse")); EndSMS();}} else if (!currStr.compareTo("Startbus")) {if (!webasto) {ProtocolSTART = STARTBUS; EEPROM.write(ProtocolSTART_cell,ProtocolSTART); webasto = 0; startSMS(isStringMessage); SIM800.println(F("zapusk BUS")); EndSMS();}} else if (!currStr.compareTo("Potencial")) {if (!webasto) {ProtocolSTART = POTENCIAL; EEPROM.write(ProtocolSTART_cell,ProtocolSTART); startSMS(isStringMessage); SIM800.println(F("zapusk +12V Potencial")); EndSMS();}} else if (!currStr.compareTo("DallasAddr")) {startSMS(isStringMessage); SMSDallasAddr(); EndSMS();} else if (currStr.endsWith("Status")) {if (!webasto) {byte st = currStr.toInt(); if (st >= STATUSBUS && st<=ANALOG )ProtocolSTATUS = st; EEPROM.write(ProtocolSTATUS_cell,ProtocolSTATUS); startSMS(isStringMessage); SIM800.print (F("Status: ")); if (ProtocolSTATUS == 0)SIM800.println(F("BUS")); else if (ProtocolSTATUS == 1)SIM800.println(F("Analog")); EndSMS();}} else if (currStr.endsWith("HeaterType")) {if (!webasto) {byte st = currStr.toInt(); if (st >= TTC_E && st<=HYDRONIC) Heater = st; EEPROM.write(Heater_cell,Heater); startSMS(isStringMessage); SIM800.print (F("Heater: ")); if (Heater == 0)SIM800.println(F("TTC_E")), K_LINE.end(), K_LINE.begin(10400); else if (Heater == 1)SIM800.println(F("VEVO")), K_LINE.end(), K_LINE.begin(2400, SERIAL_8E1); else if (Heater == 2)SIM800.println(F("EVO")), K_LINE.end(), K_LINE.begin(2400, SERIAL_8E1); else if (Heater == 3)SIM800.println(F("HYDRONIC")); EndSMS();}} else if (currStr.endsWith("ADDR")) {if (!webasto) { startSMS(isStringMessage); byte savadr = ConvertAddr(); if (savadr>=0 && savadr<=3) {SIM800.print(F("address ")); TempName(savadr); SIM800.println (F(" saved OK!")); SMSDallasAddr(); } else SIM800.println(F("address is incorrect!")); EndSMS(); }} else if (currStr.endsWith("Delta")) {if (!webasto) {delta = currStr.toInt(); // EEPROM.write(delta_cell, delta); startSMS(isStringMessage); SIM800.print(F("DeltaT: ")); SIM800.print(delta); SIM800.print(F("*C")); EndSMS();}} else if (currStr.endsWith("min")) {if (!webasto) {TimeWebasto = currStr.toInt(); // для задания время цикла работы отправить сообщение вида "25 min", где 25 время работы в мин if (TimeWebasto>59) TimeWebasto = 59; if (TimeWebasto<=15) TimeWebasto = 15; EEPROM.write(TimeWebasto_cell,TimeWebasto); startSMS(isStringMessage); SIM800.print(F("Webasto time: ")); SIM800.print(TimeWebasto); SIM800.print(F("min")); EndSMS();}} else if (currStr.endsWith("StartByte")) {byte Z =currStr.toInt(); if (Z>=0x14 && Z<=0x17) StartByte= Z+12; startSMS(isStringMessage); SIM800.print(F("StartByte: ")); SIM800.print(StartByte, HEX); SIM800.print(F("h")); EndSMS();} else if (!currStr.compareTo("ResetNumbers")) {if (isStringMessage == 1) {startSMS(isStringMessage); SIM800.println(F("Phone numbers are erased")); EndSMS(); TelNumber[1] = "00000000000"; TelNumber[2] = "00000000000"; for (int i=0; i<11; i++) {EEPROM.write (i+TelNumber1_cell, TelNumber[1][i]); EEPROM.write (i+TelNumber2_cell, TelNumber[2][i]); }}} else if (!currStr.compareTo("WriteNumber2")&& isStringMessage == 1) { SaveNumber2 = 1; startSMS(isStringMessage); SIM800.println(F("Otpravte lyuboye SMS s nomera#2 dlya sohraneniya nomera")); EndSMS();} else if (!currStr.compareTo("Balance")) SMSbalance(); isStringMessage = 0; } else if (isStringMessage==3){ if (!currStr.compareTo("WriteNumber1")) { TelNumber[1] = TelNumber[3]; for (int i=0; i<11; i++) {EEPROM.write (i+TelNumber1_cell, TelNumber[3][i]);} startSMS(1); SIM800.println(F("Tel Number#1 is saving in memory")); SIM800.print("Tel#1: "); SIM800.println (TelNumber[1]); EndSMS(); } else if (!currStr.compareTo("ZAPROS")) { SMSzapros();} else if (!currStr.compareTo("ZAPROSTEL")) { SMSzaprosTEL();} // Передача номеров телефонов пользователей по СМС isStringMessage = 0; } else if (isStringMessage==0) { if (TelNumber[1]!="00000000000" && !SaveNumber2 && TelNumber[1]!="яяяяяяяяяяя"){ if (currStr.startsWith("+CMT: \""+TelNumber[1])) { isStringMessage = 1; KTOzapros = 1; } else if (currStr.startsWith("+CMT: \""+TelNumber[2])) { isStringMessage = 2; KTOzapros = 2; } else if (currStr.startsWith("+CUSD: 0,")) //если текущая строка начинается с "+CUSD",то следующая строка является запросом баланса { startSMS(KTOzapros); SIM800.print (currStr); EndSMS(); } else if (currStr.startsWith("+CSQ:")) //если текущая строка начинается с "+CSQ",то значит был запрос на уровень сигнала GSM, отправим ответ запрашивающему { startSMS(KTOzapros); SIM800.print (currStr); EndSMS(); } } else if (currStr.startsWith("+CMT:") && !SaveNumber2) { isStringMessage = 3; for (int i =0; i<11; i++) {TelNumber[3][i]=currStr[i+7];}} else if (currStr.startsWith("+CMT:") && SaveNumber2) { for (int i =0; i<11; i++) {TelNumber[3][i]=currStr[i+7];} TelNumber[2] = TelNumber[3]; for (int i=0; i<11; i++) {EEPROM.write (i+TelNumber2_cell, TelNumber[3][i]);} startSMS(2); SIM800.println(F("Vash nomer sochranyon kak Number#2 v pamyati!")); SIM800.print(F("Tel#1: ")); SIM800.println(TelNumber[1]); SIM800.print(F("Tel#2: ")); SIM800.println (TelNumber[2]); EndSMS(); SaveNumber2 = 0; } } currStr = ""; } else if ('\n' != currSymb && currSymb!=0x13 && currSymb!=0x11) currStr += String(currSymb); } byte ConvertAddr() { byte addrbuf[9]; byte Cs=0; for (byte i = 0; i<9; i++) { char str[]=" "; for (byte k = 0; k<2; k++) str[k] = currStr[3*i+k]; addrbuf[i] = strtol(str,NULL,HEX); if (i<7) Cs+= addrbuf[i] = strtol(str,NULL,HEX); } if (OneWire::crc8(addrbuf, 7) == addrbuf[7] && addrbuf[8]>=0 && addrbuf[8]<=3) { for (byte i = 0; i<size_arrayTemp; i++) { if (addrbuf[8]==DS18B20[i][8]) {for (byte k=0; k<9; k++) DS18B20 [i][k] = addrbuf[k], EEPROM.write (DallasAddr_cell+addrbuf[8]*10+k, addrbuf[k]);} } return addrbuf[8]; } else return 20; } void SMSDallasAddr(){ SIM800.println (F("Dallas Addresses:")); for (byte i = 0; i<size_arrayTemp; i++) { TempName(DS18B20[i][8]); SIM800.println(); for (byte k = 0; k<8; k++) {if (DS18B20[i][k]<=0x0F)SIM800.print(F("0")); SIM800.print(DS18B20[i][k],HEX); SIM800.print(F(" "));} SIM800.println(); } } void SMSzaprosTEL(){ startSMS(isStringMessage); PrintNumbers (); EndSMS(); } void SMSbalance() { digitalWrite (DTR, LOW); // выводим из спячки SIM800 модуль delay (150); SIM800.print(F("AT+CMGF=1\r")); delay(200); SIM800.println (F("AT+CUSD=1,\"#100#\"")); // команда на замену на транслит *111*6*2# у МТС delay(1500); digitalWrite (DTR, HIGH); // вводим в спячку SIM800 модуль delay (150); } void AlarmSMS() {for (byte i = 0; i<2; i++) {startSMS(i+1); SIM800.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!")); EndSMS();} alarmSMS = true;} void PrintNumbers () {for (byte i=0; i<2; i++) {SIM800.print(F("Tel#")); SIM800.print (i+1); SIM800.print(F(" ")); SIM800.println(TelNumber[i+1]);}} void TempName (const byte &_address_) { if (_address_== VyhlopC) SIM800.print(F("Vyhlop: ")); else if (_address_== EngineC) SIM800.print(F("Engine: ")); else if (_address_== UlicaC) SIM800.print(F("Ulica: ")); else if (_address_== SalonC) SIM800.print(F("Salon: ")); } void SMSzapros() { startSMS(isStringMessage); if (isStringMessage == 3){ SIM800.println (F("Tel.number#1 not has been save in memory")); SIM800.println (F("For save Tel#1 send SMS command \"WriteNumber1\"")); PrintNumbers (); } else { SIM800.print (F("Webasto ")); on_off (webasto); if (webasto) { SIM800.print (F("StartWebasto ")); if (startWebasto_OK) SIM800.println (F("OK")); else SIM800.println (F("FAIL"));} SIM800.print (F("Engine ")); on_off (engine); SIM800.print (F("IGN ")); on_off (ignition); SIM800.print (F("Ohrana ")); on_off (ohrana); if (trevoga) SIM800.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!")); SIM800.print(F("Battery: ")); if ((needAction>0 && !noData) || needAction == 0 || ProtocolSTATUS == ANALOG) {SIM800.print (Vpit,1); SIM800.println(F(" V"));} else if (needAction>0 && noData && ProtocolSTATUS != ANALOG) SIM800.println(F(" No Data")); SIM800.println(F("Temperatures:")); if (ProtocolSTATUS != ANALOG){ SIM800.print(F("Heater: ")); if ((needAction>0 && !noData) || needAction == 0) {SIM800.print (HeaterC); grad ();} else if (needAction>0 && noData) SIM800.println(F(" No Data"));} // ниже распечатаем все температуры for (byte i = 0; i<size_arrayTemp; i++) { if (DS18B20[i][8]==VyhlopC && ProtocolSTATUS != ANALOG) {} else {TempName(DS18B20[i][8]); SIM800.print (Temper(DS18B20[i][8])); grad ();}} if (ProtocolSTATUS == STATUSBUS){ SIM800.print(F("Errors: ")); if ((needAction>0 && !noData) || needAction == 0) SIM800.println (DTC[0]); else if (needAction>0 && noData) SIM800.println(F(" No Data"));} } EndSMS(); } void on_off (const bool &stat) {if (stat) SIM800.println (F("ON")); else SIM800.println (F("OFF")); } void grad () {SIM800.println (F("*C")); } void ServiceINFO(){ startSMS(isStringMessage); SIM800.print(F("Heater: ")); if (Heater==TTC_E) SIM800.println(F("TTC/E")); else if (Heater==VEVO) SIM800.println(F("VEVO")); else if (Heater==EVO) SIM800.println(F("EVO")); else if (Heater==HYDRONIC) SIM800.println(F("HYDRONIC")); SIM800.print(F("Start: ")); if (ProtocolSTART==IMPULSE) SIM800.println(F("GND Imp")); else if (ProtocolSTART==STARTBUS) {SIM800.print(F("BUS")); if (Heater== VEVO || Heater== EVO) {SIM800.print(F(" 0x")); SIM800.println (StartByte, HEX);} else SIM800.println();} else if (ProtocolSTART==POTENCIAL) SIM800.println(F("Potencial+12V")); SIM800.print(F("Status: ")); if (ProtocolSTATUS==ANALOG) SIM800.println(F("ANALOG")); else if (ProtocolSTATUS==STATUSBUS) SIM800.println(F("BUS")); if (ProtocolSTART!=IMPULSE) {SIM800.print(F("Webasto Time: ")); SIM800.print (TimeWebasto); SIM800.println(F("min"));} SIM800.print(F("SIM800 Resets: ")); SIM800.println (ResetNumber); if (ProtocolSTATUS==ANALOG) {SIM800.print(F("DeltaT: ")); SIM800.print(delta);SIM800.println(F("*C"));} if (ProtocolSTATUS==STATUSBUS){ if (!noData) { SIM800.print(F(" BurnFAN ")); on_off (airfan); SIM800.print(F(" WaterPUMP ")); on_off (waterpump); SIM800.print(F(" PLUG ")); on_off (plug); SIM800.print(F(" FuelPUMP ")); on_off (fuelpump); SIM800.print(F(" Blower ")); on_off (blowerfan); SIM800.print (F("Errors: ")); SIM800.println (DTC[0]); if (DTC[0] >0) for (byte i=0; i<DTC[0]; i++) { if (DTC[i+1]<=0x0F) SIM800.print(F("0")); SIM800.print (DTC[i+1], HEX); if (bitRead(DTC[6], i+1)) SIM800.println (F(" Active")); else SIM800.println (F(" Passive")); } } else SIM800.println(F("Heater not answer. No Data"));} EndSMS(); } void StartWebasto() { if (ProtocolSTART==IMPULSE){ digitalWrite (OutWebasto_GndImp, LOW); timer=curmillis; timerenabled=true;} else { StartMessageRepeat = 0; webasto = 1; digitalWrite (OutWebasto_12V, HIGH); timerStart_W_BUS=millis(); timerenabledStart_W_BUS = true;} report = true; EndReportMillis = millis(); w_bus_init = NEED; } void StopWebasto() { if (ProtocolSTART==IMPULSE){ digitalWrite (OutWebasto_GndImp, LOW); timer=curmillis; timerenabled=true;} else { StopMessageRepeat = 0; webasto = 0; digitalWrite (OutWebasto_12V, LOW); timerenabledStart_W_BUS = false;} report = false; } void Heater_BUS (){ if (Heater == EVO || Heater == VEVO){ if (webasto) { if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800) && w_bus_init >= 9){ sendMessage (HEATER_START, sizeof(HEATER_START)); StartMessageRepeat++; Prev_PeriodW_BusStartStop = millis(); } if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>4000) { if (requiredmessage==1) sendMessage (HEATER_PRESENCE, sizeof(HEATER_PRESENCE)); else if (requiredmessage==2) {if (Heater == EVO) sendMessage (HEATER_STATUS_EVO, sizeof(HEATER_STATUS_EVO)); if (Heater == VEVO)sendMessage (HEATER_STATUS_VEVO, sizeof(HEATER_STATUS_VEVO));} else if (requiredmessage==3) sendMessage (HEATER_DTC_REQUEST, sizeof(HEATER_DTC_REQUEST)); requiredmessage++; if (requiredmessage > 3) requiredmessage = 1; StopMessageRepeat = 0; Prev_PeriodW_BusMessage = millis(); }}} else if (StopMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800)){ sendMessage (HEATER_STOP, sizeof(HEATER_STOP)); StopMessageRepeat++; StartMessageRepeat = 0; Prev_PeriodW_BusStartStop = millis(); } if (!timerInitflag && w_bus_init==NEED) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = millis(); timerInitflag = 1;} if ( timerInitflag && (millis() - timerInit>24) && w_bus_init==NEED) {timerInit = millis(); digitalWrite(TX, 1); w_bus_init=2; } if ( timerInitflag && (millis() - timerInit>24) && w_bus_init==2) {K_LINE.begin (2400,SERIAL_8E1 );timerInitflag = 0; w_bus_init=9; if (needAction>0) sendMessage (HEATER_BEGIN, sizeof(HEATER_BEGIN)); } if (K_LINE.available()){ // первый старт байт if (header == 0 && Delay){TIMER_DELAY ; buf[0]=K_LINE.read(); if (buf[0]==0x4F || buf[0]==0x44){header = 1; RESETheader_timer=1; prevRESETheader = curmillis; } else {header = 0; RESETheader_timer=0;} } // длина сообщения if (header == 1 && Delay){TIMER_DELAY ; buf[1]=K_LINE.read(); message_size = buf[1]; if (message_size > bufsize) message_size = bufsize; header = 4;j=2;n=2;checksum = 0;} // пишем тело сообщения if (header == 4 && Delay && j< message_size+n) { buf[j] = K_LINE.read(); if (j<message_size+n-1) checksum^= buf[j]; // подсчёт КС if (j==message_size+n-1) header = 5; TIMER_DELAY ; j++;} } // end of K_LINE.available() // сообщение приняли, действуем if (header == 5) {TIMER_DELAY ; for(byte i = 0; i<n; i++) checksum^=buf[i]; // прибавляем к контрольной сумме старт байты // если контрольная сумма верна: if ( checksum == buf[message_size+n-1]) { if (Heater == EVO){ if (buf[2]==0xD0 && buf[3]==0x30) { // если получили сообщение с текущими данными if (buf[4] ==0x0A) { airfan = (bool)buf[5]; // получаем флаг работы нагнетателя воздуха plug = (buf[5] & 0x02)>>1; // получаем флаг работы штифта накаливания fuelpump = (buf[5] & 0x04)>>2; // получаем флаг работы топливного насоса waterpump = (buf[5] & 0x08)>>3; // получаем флаг работы циркуляционного насоса blowerfan = (buf[6] & 0x10)>>4; // получаем флаг работы вентилятора печки автомобиля } if (buf[6] ==0x0C) HeaterC = buf[7]-50; // получаем температуру антифриза в котле if (buf[8]==0x0E) {Vpit = (float)(buf[9]<<8|buf[10])/1000.0;} // получаем напряжение борт сети if (buf[11]==0x10) {startWebasto_OK = (bool)buf[12]; last_Flame = curmillis;} // проверяем наличие пламени if (needAction>0 && needAction<NEED_DTCCLEAR) {w_bus_init = 12; sendMessage (HEATER_DTC_REQUEST, sizeof(HEATER_DTC_REQUEST));} } if (buf[0]==0x44 && buf[2]==0xC4 && buf[3]==0x00) {w_bus_init = 1; delay (500); K_LINE.flush();} // если получили от котла сбой инита, делаем переинит if (buf[2]==0xD6 && buf[3]==0x01) {if (needAction>0 && needAction<NEED_DTCCLEAR) w_bus_init = 13; for (byte h = 0; h< sizeof(DTC); h++) DTC[h]=0; DTC[0] = buf[4]; for (byte h = 0; h< buf[4]; h++) {DTC[h+1]=buf[h*3+5]; bitWrite (DTC[6], h+1, (buf[h*3+6] & 0x02)>>1);} } if (buf[2]==0xD6 && buf[3]==0x03) {startSMS (KTOzapros); SIM800.println (F("DTCs are erased!")); EndSMS(); needAction=0; w_bus_init = 9; NeedTimer = 0; } if (buf[2]==0xD1 && buf[3]==0x0A) {w_bus_init = 10; }// если получили ответ на сообщение старта коммуникации } if (Heater == VEVO){ if (buf[2]==0xD0 && buf[3]==0x05) {startWebasto_OK = buf[7]; last_Flame = millis();} // проверяем наличие пламени у VEVO } } // если контрольная сумма не совпала: //else K_LINE.println("CRC fail!!!" ); message_size = 0; header=0; RESETheader_timer=0; j=2; checksum = 0; } }// end EVO VEVO else if (Heater == TTC_E){ if (!timerInitflag && w_bus_init==NEED) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = millis(); timerInitflag = 1;} if ( timerInitflag && (millis() - timerInit>299) && w_bus_init==NEED) {timerInit = millis(); digitalWrite(TX, 1); w_bus_init=2; } if ( timerInitflag && (millis() - timerInit>49) && w_bus_init==2) {timerInit = millis(); digitalWrite(TX, 0); w_bus_init=3; } if ( timerInitflag && (millis() - timerInit>24) && w_bus_init==3) {timerInit = millis(); digitalWrite(TX, 1); w_bus_init=4; } if ( timerInitflag && (millis() - timerInit>3024) && w_bus_init==4) {K_LINE.begin (10400); timerInitflag = 0; w_bus_init=9; sendMessage (START_SESSION, sizeof(START_SESSION));} if (K_LINE.available()){ // первый старт байт if (header == 0 && Delay){TIMER_DELAY ; buf[0]=K_LINE.read(); if (!bitRead (buf[0],6) && bitRead (buf[0],7)){header = 1; RESETheader_timer=1; prevRESETheader = curmillis; } } // второй старт байт if (header == 1 && Delay){TIMER_DELAY ; buf[1]=K_LINE.read(); if (buf[1]==0xF1){ header = 2;} else {header = 0; RESETheader_timer=0;}} // третий старт байт if (header == 2 && Delay){ TIMER_DELAY ; buf[2]=K_LINE.read(); if (buf[2]==0x51){ message_size = buf[0]; if (buf[0] !=0x80) {header = 4; message_size&=~0x80; j=3; n=3;} else {header = 3; j=4;n=4;} if (message_size > bufsize) message_size = bufsize; checksum = 0;} else {header = 0; RESETheader_timer=0; } } // если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт: if (header == 3 && Delay){ TIMER_DELAY ; buf[3]=K_LINE.read(); message_size = buf[3]; if (message_size > bufsize) message_size = bufsize; checksum = 0; header = 4; } // пишем тело сообщения if (header == 4 && Delay && j< message_size+n+1) { buf[j] = K_LINE.read(); if (j<message_size+n) checksum+= buf[j]; // подсчёт КС if (j==message_size+n) header = 5; TIMER_DELAY ; j++;} } // end of K_LINE.available() // сообщение приняли, действуем if (header == 5) {TIMER_DELAY ; for(byte i = 0; i<n; i++) checksum+=buf[i]; // прибавляем к контрольной сумме старт байты //for (byte i=0; i<message_size+n+1; i++) {Serial.print (buf[i], HEX); Serial.print(" ");} // если контрольная сумма верна: if (buf[message_size+n] == checksum) { // if (buf[n]== 0xC1) Serial.println ("StartSession OK!!!"); } // если контрольная сумма не совпала: //else Serial.println("CRC fail!!!" ); message_size = 0; header=0; RESETheader_timer=0; j=3; checksum = 0; } } // end TTC_E // таймер ожидания байт (для успевания появления данных в буфере UART) if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; // таймер сброса заголовка если данные оборвались во время приёма заголовка if (RESETheader_timer && curmillis - prevRESETheader > 500) {RESETheader_timer = 0; header = 0;} if (curmillis - last_Flame>20000 && ProtocolSTATUS==STATUSBUS) {startWebasto_OK=0; last_Flame = curmillis;} // делаем статус "нет пламени" через 20 сек, если не получаем сообщения от котла if (Initreset && curmillis - prevInitreset>17000) {Initreset = 0; w_bus_init = 0;} // сброс инита, если прошло более 17 сек после отправки последнего сообщения if (needAction>0 && needAction < NEED_DTCCLEAR && w_bus_init==10) {if (Heater == EVO) sendMessage (HEATER_STATUS_EVO, sizeof(HEATER_STATUS_EVO)); if (Heater == VEVO)sendMessage (HEATER_STATUS_VEVO, sizeof(HEATER_STATUS_VEVO)); w_bus_init=11;} if ((NeedTimer && curmillis - prevNeedTimer>11000) || w_bus_init == 13) {NeedTimer = 0; if (curmillis - prevNeedTimer>11000) noData = 1; if (needAction == NEED_SMSZAPROS) SMSzapros(); else if (needAction == NEED_SERVICEINFO) ServiceINFO(); else if (needAction == NEED_DTCCLEAR) {startSMS(KTOzapros); SIM800.println (F("DTC not cleared. Heater no answer!")); EndSMS();} w_bus_init = 9; noData = 0; needAction = 0; } if (needAction==NEED_DTCCLEAR && w_bus_init==10) { sendMessage (HEATER_DTC_ERASE, sizeof(HEATER_DTC_ERASE)); w_bus_init = 20; } } void Reset_gsm (){ if (millis()-prevReset>(unsigned long)intervalReset*60000UL){ digitalWrite (DTR, LOW); delay (150); SIM800.println (F("AT")); timerenabledWaitOK = 1; timerWaitOK = millis(); gsmOK = false; prevReset = millis(); } if (timerenabledWaitOK && millis()-timerWaitOK>6000) { timerenabledWaitOK = 0; if (!gsmOK) { SIM800.println (F("AT")); timerenabledWaitOK = 1; timerWaitOK = millis(); NoAnswersGSM++; if (NoAnswersGSM>4) NoAnswersGSM = 4; } } if (!gsmOK) { if (SIM800.available()>0){ char currSymb = SIM800.read(); if ('\r' == currSymb) { if (!currStr.compareTo("OK")) { gsmOK = true; timerenabledWaitOK = 0; NoAnswersGSM=0; digitalWrite (DTR, HIGH);} currStr = ""; } else if ('\n' != currSymb && currSymb!=0x13 && currSymb!=0x11) {currStr += String(currSymb);}}} if (NoAnswersGSM>=4) Reset(); } void Reset(){ if (!resettimer) {digitalWrite (ResetGSM, RelayON); resettimer = 1; resetTimer = millis();} else if (millis()- resetTimer>6000 ) { resettimer = 0; NoAnswersGSM=0; ResetNumber++; EEPROM.write (ResetNumber_cell, ResetNumber); digitalWrite (ResetGSM, !RelayON); delay (3500); NastroykaGSM ();} } void sendMessage(const byte *command, const size_t size){ Initreset = 1; prevInitreset = curmillis; // включение таймера сброса инита if (Heater == TTC_E){ const byte siZe = size+4; byte Mes[siZe]; byte Checksum = 0; for(byte i=0; i<siZe; i++) { if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);} if (i==1) Mes[i] = 0x51; if (i==2) Mes[i] = 0xF1; if (i==3) {for (byte t=0; t<size; t++ ) {Mes[i]=command[t]; Checksum+=Mes[i] ;K_LINE.write (Mes[i]); i++;}} if (i!=siZe-1) Checksum+=Mes[i]; else Mes[i] = Checksum; K_LINE.write (Mes[i]); } } else if (Heater == EVO || Heater == VEVO){ const byte siZe = size+3; byte Mes[siZe]; byte Checksum = 0; for(byte i=0; i<siZe; i++) { if (i==0) Mes[i] = 0xF4; if (i==1) Mes[i]=size+1; if (i==2) {for (byte t=0; t<size; t++ ) {Mes[i]=command[t]; Checksum^=Mes[i] ;K_LINE.write (Mes[i]); i++;}} if (i!=siZe-1) Checksum^=Mes[i]; else Mes[i] = Checksum; K_LINE.write (Mes[i]); } } }Спасибо!
Ещё раз благодарю за Ваш труд!
в плате тоже городят изменения ?
Добрый день! Подскажите пожалуйста, с автономкой на БМВ е46 будет работать по к-линии? Что может?
а есть ли жизнь на Марсе? Если вы снимете лог общения диагностики с вашим котлом, то я скажу, будет или нет.
Понял, спасибо. Когда порадуете mqtt версией?)
P.S. Есть кто с Украины готовый продать одну печатку готовую?
Понял, спасибо. Когда порадуете mqtt версией?)
P.S. Есть кто с Украины готовый продать одну печатку готовую?
Я , скоро у китайцев буду заказывать
Постараюсь подправить в ближайшее время плату. Добавив конденсатор и диоды, чтобы развязать питание мк и джсм . После этого можно в заказ
Было бы круто, а то холодно уже))
Я тут немного пробовал поменять все местами( развернул модуль, чтобы можно было sim вставить не разбирая корпуса) и под свой корпус, но теперь не уверен в правильности разводки. Может закину свой проект и библиотеки элементов, а вы сможете глянуть на правильность?
не, это самостоятельно.
Добрый вечер! Наконец-то добрался до сборки платы, скоро зима а я еще не опробовал. Сижу второй вечер, уже мозги кипят, а плата не хочет работать. Не пойму в чем дело. Уже ради пробы просто подключил UNO к сим800 модулю проводами без платы, залил сперва очищающую прошивку потом прошивку v.3.66 и ни как не реагирует на смс запрос номеров ни на добавление номера. Обратных смс нет. Деньги на симке есть. Не чего не трогая перепрошиваю на другой код проверки сим800, все работает и смс отправляет и принимает.
При проверки работы к плате кроме питания не чего не подключал. СМС без подключения котла работать ведь должны?
да, прошивка 3.66 это не для вас. надо 3.65
плата 8.91. и Гербер файлы для отправки на изготовление в Китай рекомендую здесь . Развязал питание сим800 и ардуины через диоды и добавил кондёр по питанию. Теперь на dc-dc нужно будет настроить такое напряжение, чтобы после диода на сим800 было 4В. Думаю это будет около 5В. Проверяйте, лишним не будет. Косяки не исключены.
Да я обе пробовал и 3.66 возвращал на телефон 12 цифр. В принципе на голой плате СИМ800 должен же отвечать.