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

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

Молодец что разобрался. Теперь нужно выяснить почему у тебя метрики на русском мкютт не работают раз у тебя засада с cloudmqtt. А мошешь вопрос оператору задать че за нах. Метрики понятное дело удобнее с компа забивать, но у тебя костыль это понятно, почему со смарта делал.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Многие в России пользуют cloudmqtt поэтому с Россией он работает. Не знаю может в вашем регионе какая то странная политика по этому поводу

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Не знаю пробовал с домашнего интернета Ростелеком, и с Мегафоновский мобильный интернет, не работают , при чем с компа через фригейт подмена ip не работает, только на смартфоне работает.

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Так как метрики у меня уже есть я  изменил в настройках mqtt dash  данные с cloudmqtt.com  на настройки https://mqtt.4api.ru  ну и в скетче тоже , теперь устройство ведет себя так на ардуино горит только один светодиод , а модем щелкнет реле и потом через какое то время начинает довольно часто мигать , я так понимаю это вроде подключение по жпрс , но вот на экране смартфона ни чего не меняется, и не реагирует на нажатие кнопок. Как должно быть ?

MaksVV
Offline
Зарегистрирован: 06.08.2015

да часто мигает значит подключен по gprs. При нажатии на кнопку управления лед13 должен включиться. А при нажатии кнопки «обновить» , данные обновляются. Смотри , появляются ли топики в вебсокете после нажатия кнопок. 

Dushman7776
Offline
Зарегистрирован: 13.01.2019

По ходу сам брокер этот русский кривой, в вебсокете ни чего не приходит, хотя в mqtt dash и в в вебсокете написано что подключено, хотя может я не правильно этим вебсокетом пользуюсь , ни хрена не могу понять как в нем топики смотреть , там немного по другому. Может ты глянешь этот сайт и носом ткнешь меня как надо . А то совсем тупик какой-то.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Позже

MaksVV
Offline
Зарегистрирован: 06.08.2015

В русском есть служба поддержки, напиши туда

MaksVV
Offline
Зарегистрирован: 06.08.2015

Dushman7776, я разобрался с этим твоим брокером. Вместо вебсокета там просто подключается веб клиент mqtt в браузере и там всё смотрится. И также метрики заработали. Просто все топики в этом брокере должны начинаться с текста логина, т.е. user..../блабла  тогда всё будет работать. Ну и в клиенте чтобы все видеть нужно подписаться сначала на все  топики так: user..../#  кнопка Subscriptions.  Cоответственно нужно и скетч подправить и метрики в mqtt dash чтобы все работало

MaksVV
Offline
Зарегистрирован: 06.08.2015

вот нашел у коллеги по поводу cloudmqtt . Смотрим внимательно

 

MaksVV
Offline
Зарегистрирован: 06.08.2015

скетч #875 подправил. Были недочёты

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Мне только 2 дата центра выпадают в америке и в Ирландии. Пробовал создавать новые Instance , так всегда одни и те же сервера выпадают заблокированные.

MaksVV
Offline
Зарегистрирован: 06.08.2015

короче 4api коряво работает. Тот же скетч нормально не хочет данные отправлять, костылить опять надо. Пробуй новую регистрацию на cloud пока не даст нормальный сервер. По местунахождения у меня тоже только два - ирландия и северная вирджиния, так и должно быть

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Попробую ,  импортозамещение в России так и работает через жопу.

MaksVV
Offline
Зарегистрирован: 06.08.2015

у меня кстати на tailor.cloudmqtt.com работает,    а на farmer.cloudmqtt.com  - нет.

Dushman7776
Offline
Зарегистрирован: 13.01.2019

не ни хрена он другие сервера не дает, надо другой броккер рабочий искать.

MaksVV
Offline
Зарегистрирован: 06.08.2015

я буквально только что создал на вирджинии.  мне выдал tailor - все работает. 

Dushman7776
Offline
Зарегистрирован: 13.01.2019

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

MaksVV
Offline
Зарегистрирован: 06.08.2015

Екатеринбург

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Странно , я из Иркутской области , может это какие то местные провайдерские настройки , хотя я пробовал с разных компов , с разных операторов связи , и везде блокировка.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Возможно на свежих аккаунтах такая фигня. Я сейчас новую почту сделал, тоже не дает рабочий сервер

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Я в поддержку cloudmqqtt написал может ответят.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Нужно по гугл акку заходить который уже давно зареган. Может прокатит. Новые аккаунты не робят

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Да моему аккаунту на гугле уже сто лет в обед, и все равно рабочие сервера не дает, может нужные нам забиты под завязку работой ? А может тех обслуживание како нибудь, у них в новостях о работе брокера что то такое написано только что прочитал https://status.cloudmqtt.com/

Dushman7776
Offline
Зарегистрирован: 13.01.2019

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

Zakhnnm
Offline
Зарегистрирован: 10.02.2016

Всем Здравствуйте!

А ведь можно еще использовать готовые библиотеки для работы с MQTT

Секешфехервар
Секешфехервар аватар
Offline
Зарегистрирован: 06.09.2018

Эти библиотеки места добре много занимают.

Zakhnnm
Offline
Зарегистрирован: 10.02.2016

Вот тут - https://www.drive2.ru/c/538609790713070187/

очень похожее решение.

Секешфехервар
Секешфехервар аватар
Offline
Зарегистрирован: 06.09.2018

Мартинхол не использует в скетче библиотеки, ими пользуется иван борщ с драйва...

MaksVV
Offline
Зарегистрирован: 06.08.2015

Dushman7776 пишет:
Ура товарищи Ура

отпишись потом, как тестовый скетч mqtt работает.

MaksVV
Offline
Зарегистрирован: 06.08.2015

ночью, когда создал несколько аккаунтов на cloudmqtt ничего не работало, как у Dushman. А сейчас днём проверил - всё гуд. Видать всё поправили. Dushman, проверь все свои акки и  instans ы на cloud, должны работать. 

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Я уже в поддержку им написал , и они буквально через 5 минут ответили , что поменяли ай пи этих серверов . Хорошо работают, оперативно. Проверить скетч не получилось сегодня, завтра проверю. Аккаунт проверил, работает.Приехал на работу , достал коробку с платой , воткнул ардуино с прошивкой mqtt , вроде все подключилось даже обновились данные ,но на включение отреагировал только светодиод с 13 порта  на ардуино ,а котел не включился ,  и еще данные по температуре обновились , но почему то температуру котла показало минис 100 градусов а остальные датчики по 20 градусов , хотя у меня установлен только один 18b20 на салон , но в салоне было по любому холоднее, поставил я обратно старую плату с смс прошивкой , и пошел работать . вечером включил прогрев смс кой , прихожу к машине лампа на кнопке ручного включения горит а котел не горит, ну думаю пиздец , что то сгорело, домой принес и обнаружил что провод с выхода WBus  отвалился , завтра проверю по новой. А можно функционал от смс прошивки перенести на mqtt  ну там ошибки читать удалять и напряжение в сети и уровень приема сигнала сети что бы это было в режиме реального времени ,ну  т.е. чтобы можно было все эти данные параллельно видеть ?

MaksVV
Offline
Зарегистрирован: 06.08.2015

Дак я ж еще прошивки не соединил, конечно у тебя ниче не работает, ни котел ни температуры. Это ж тестовый скетч для проверки работы модема по mqtt. По слиянию прошивок я пока работаю

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Тогда нет смысла пока в авто проверять ? Ну светодиод загорается при нажатии кнопки .

MaksVV
Offline
Зарегистрирован: 06.08.2015

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

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Конкретно что нужно проверить, по пунктам.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Ну например это. Заехать в зону где нет сети gsm на полчаса, потом вернуться. Связь с мкютт должна восстановиться если не сразу то максимум через час

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Завтра попробую, только у нас нет уже мест где нет связи. Может поместить в какую нибудь экранированную металлическую коробку?

MaksVV
Offline
Зарегистрирован: 06.08.2015

Cвершилось. Запилил  MQTT в основной скетч. v3.80. Не забываем почистить еепром,  если другие скетчи заливали, которые используют еепром. метрики для программы MQTT dash в инструкции #875

const char ver[] = "Firmware 3.80";    // версия прошивки

//---------------------------Настройки MQTT-----------------------------------------------------------------------------

const char ACCESSPOINT[]= "\"internet.mts.by\""; // точка доступа оператора связи симкарты
const char PROTOCOLIUS[] =  "MQIsdp";               // это и оставляем
const char MQTTNAME[]    =  "M    V";               // это смотрим на сервере MQTT
const char MQTTUSER[]    =  "g     r";              // это смотрим на сервере MQTT
const char MQTTPASSWORD[] = "3     f";              // это смотрим на сервере MQTT
const char SERVERNAME_PORT[] = "\"m16.cloudmqtt.com\", \"14685\"";       // это смотрим на сервере MQTT
#define TIMEBROKER 80   // продолжительность сессии с брокером , мин (пока такое и оставляем)

//----------------------------------название ячеек еепром----------------------------------------------------------------
#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
};


//------------------- распиновка ног ардуино (плата весий 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  // программный номер тактовой кнопки вкл/выкл котла 
#define DopOnButton         1  // программный номер тактовой кнопки (допканала) вкл котла 
#define DopOffButton        2  // программный номер тактовой кнопки (допканала) выкл котла 
const bool RelayON =        1; // логика управления реле ресета GSM, в данном случае включается высоким уровнем на пине
#define GSM_RX             10  // пин софт RX Arduino для соединения с TX модуля SIM800
#define GSM_TX             11  // пин софт TX Arduino для соединения с RX модуля SIM800

//------------------------------------для GSM модуля----------------------------------------------------------------------

#include <SoftwareSerial.h>
      SoftwareSerial SIM800 (GSM_RX, GSM_TX);//Rx, Tx   //UART для соединения с GSM модулем

String currStr = "";
String TelNumber[] = {"", "000000000000", "000000000000", "000000000000"};
byte isStringMessage = 0; 
byte KTOreport = 1;     // флаг кто запросил отчет о запуске котла или ДВС
byte KTOzapros = 0;     // флаг кто запросил баланс или запрос параметров 

byte ResetNumber = 0;            // количество ресетов GSM модуля для статистики (хранится в еепром)



int16_t Refresh_time = 1200; //сек 
uint32_t prev_refreshMQTT = 0;
uint32_t prevGSMnastr = 0;
uint32_t interval_doprosGSM = 123000UL; 
uint16_t delayATcommand = 5000;
byte fails = 0;
byte failresets = 0;

bool settingGSM = 1;

enum gsmstatus_  {WaitGSM, echoOFF, EnergySave, Head, setText, setProgctrl, closeIncoming, newMessage, delSMS, setGPRS, setAccPoint,
                  setGPRSconnect, setBrokerconnect, setAuthPack, setSubPack, setPubPack
                 };

byte gsmstatus = WaitGSM;




//------------------- для шины 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 = -50;
//---------------------------для организации W-BUS и различные таймеры-----------------------------------------------------------

#include <Button.h>
Button test;

#define K_LINE Serial      //UART для соединения с шиной котла
#define TX 1    
#define NEED 1
#define READY 10



// команды для котлов ЭВО
byte StartByte = 0x20;
const byte HEATER_BEGIN[]         {0x51, 0x0A};
      byte HEATER_START[]         {StartByte, 0x3B};
      byte HEATER_PRESENCE[]      {0x44, StartByte, 0x00};
const byte HEATER_STOP[]          {0x10};
const byte HEATER_STATUS_VEVO[]   {0x50, 0x05};
const byte HEATER_STATUS_EVO[]    {0x50, 0x30, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x1E, 0x32};
const byte HEATER_DTC_REQUEST[]   {0x56, 0x01};
const byte HEATER_DTC_ERASE[]     {0x56, 0x03};

// команды для котлов ТТС/TTE
const byte START_SESSION[]        {0x81};
const byte REQUEST_2A10101[]      {0x2A, 0x01, 0x01};
const byte REQUEST_2A10102[]      {0x2A, 0x01, 0x02};
const byte REQUEST_2A10105[]      {0x2A, 0x01, 0x05};
const byte REQUEST_DTC[]          {0xA1};
const byte START_TTC[]            {0x31, 0x22, 0xFF};
const 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 currmillis = 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 prevReportEngine = 0; bool reportEngine = false;    //таймер задержки на отправку отчёта о запуске двигателя
uint32_t prevReport = 0;bool report = false;                 //таймер задержки на отправку отчёта о запуске котла
uint32_t last_Flame = 0;                                     //для таймера сброса флага пламени, если нет ответов от котла
uint32_t prevGND_impulse = 0; bool GND_impulse_timer = 0;    //для таймера создания импульса GND - для протокола запуска котла импульсом GND 
uint32_t prevStartEng=0; bool StartEng_timer=0;              //для таймера  - старт двигателя: минусовой импульс 1.5 сек на вход событий сигналки для запуска ДВС
uint32_t prevWorkCycleHeater; bool WorkCycleHeater_timer=0;  //для таймера отсчёта цикла работы котла




//---------------------------------Основные переменные--------------------------------------------------------------------------------  

bool webasto = 0;             // флаг команды на работу Webasto. 0 - котел выключен, 1 - котел включен
bool startWebasto_OK = 0;     // флаг успешного запуска котла

float Vpit = 0.0;             // Измеряемое напряжение на выходе ИБП
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 (4500);


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, DopOn, DopOff);
 
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,                 LOW );  // делаем низкий для вывода GSM из "спячки"
pinMode (ResetGSM,           OUTPUT);  digitalWrite (ResetGSM,        !RelayON);  // реле ресет на данный момент делаем "неактивно"


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

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<12; i++) TelNumber[1][i] = EEPROM.read (i+TelNumber1_cell);
for (int i=0; i<12; 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);
fails = 3;
}



//------------------------------------------ЛУП-----------------------------------------------------------------------------------


void loop() {
currmillis = millis();
test.read();

digitalWrite (StatusWebastoLED, webasto);
//digitalWrite (13, startWebasto_OK);
//digitalWrite (13, webasto);

if   (settingGSM) NastroykaGSM ();
else if (fails >= 3) settingGSM = 1;

//если MQTT активен 
  if (failresets < 5) 
    {
    static bool last_MQTTwebasto = 0;
    static bool last_startwebasto_OK = 0;
    if (last_MQTTwebasto != webasto || last_startwebasto_OK != startWebasto_OK){ MQTTsendDatastream(); last_MQTTwebasto = webasto; last_startwebasto_OK = startWebasto_OK;}
    refreshDataMQTT (); 
    }
if (!webasto)
    {
      static uint32_t prevTestModem = 0;
      if (!settingGSM && currmillis - prevTestModem > interval_doprosGSM)
      {
         digitalWrite (DTR, LOW);
         delay (150);
         SIM800.println (F("AT"));
         prevTestModem = currmillis;
         fails++;
         interval_doprosGSM = 10000;
      }
    
    }  




if (ProtocolSTATUS==ANALOG) {if (Temper(VyhlopC) - Temper(UlicaC) > delta) startWebasto_OK = 1;
                             else startWebasto_OK = 0;}

if (ProtocolSTART==IMPULSE) {
    webasto = !digitalRead (Sost);
    static bool previos_webasto = 0;
    if (previos_webasto!=webasto)
         {
          if  (!previos_webasto && webasto) Refresh_time = 60;
          if  (previos_webasto && !webasto) Refresh_time = 1200;
          previos_webasto=webasto;
         }
                            }

   if (!ohrana) alarmSMS = false;
   if (trevoga && !alarmSMS) AlarmSMS ();



readModem();   
DelSMS();
Heater_BUS();
timers_and_buttons ();
izmereniya();

}


//-----------------------------------------------------------конец луп-------------------------------------------------------------



void izmereniya() { 

 engine =  !digitalRead (Eng);
 ignition= !digitalRead (IGN); 
 ohrana=   !digitalRead (Ohrana);  
 trevoga=  !digitalRead (Trevoga);


if (currmillis-prevVpit>7000){

//измерение напряжения борт сети
if (ProtocolSTATUS==ANALOG)
{
   Vpit = (analogRead(Voltmeter_pin) * 4.13) / 1024;             
   Vpit = Vpit / (9700.0/(98930.0+9700.0));  // По формуле Vpit = vout / (R2/(R1+R2)) 
   if (Vpit<0.09)  Vpit=0.0;                  // Округление до нуля 
}  

// ниже измерение датчиков даллас
static bool y=0;        // флаг работы: запрос температуры или её чтение
y=!y;
if (y) {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=currmillis;
}}



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 timers_and_buttons (){

// опрос допканалов от сигнализации включения/выключение котла и таймер импульса старт/стоп котла 
 
  if (GND_impulse_timer && currmillis - prevGND_impulse > 800) {digitalWrite (OutWebasto_GndImp, HIGH); GND_impulse_timer=false;}
  
//ниже для таймера создания импульса на старт ДВС 
if (StartEng_timer && currmillis - prevStartEng > 1500) {digitalWrite (StartEng, LOW); StartEng_timer=false;}

//ниже для таймера старта котла по шине и аналогу 
if (WorkCycleHeater_timer && currmillis - prevWorkCycleHeater > (uint32_t)TimeWebasto * 60000UL) {StopWebasto();}

// таймер отправки отчета об успешности запуска котла (отчёт через 6 мин после старта)
   if(webasto && report && currmillis - prevReport > 360000UL) 
   { report = false; Queue(NEED_SMSZAPROS);  }

// таймер отправки отчета об успешности запуска ДВС  (отчёт через 90сек после старта)                       
   if(reportEngine && currmillis - prevReportEngine > 90000ul) 
   {reportEngine = false; Queue(NEED_SMSZAPROS);}

//если нажали на допканал - делаем соответствующее состояние котла 
if (test.event_click_Dn (DopOnButton) && !webasto) {StartWebasto(); KTOreport = 1;}  
if (test.event_click_Dn (DopOffButton) && webasto) {StopWebasto();}

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


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(3500);
   digitalWrite (DTR, HIGH); // вводим в спячку SIM800 модуль 
   
}

void NastroykaGSM () {

  if (fails >= 3) Reset();

  else if (currmillis - prevGSMnastr > delayATcommand)
  {

    fails ++;

    if (gsmstatus == WaitGSM)               SIM800.println (F("AT"));
    else if (gsmstatus == EnergySave)       SIM800.println (F("AT+CSCLK=1"));
    else if (gsmstatus == Head)             SIM800.println (F("AT+CIPHEAD=1"));
    else if (gsmstatus == echoOFF)          SIM800.println (F("ATE0"));
    else if (gsmstatus == setText)          SIM800.println (F("AT+CMGF=1"));
    else if (gsmstatus == setProgctrl)      SIM800.println (F("AT+IFC=0, 0"));
    else if (gsmstatus == closeIncoming)    SIM800.println (F("AT+GSMBUSY=1"));
    else if (gsmstatus == newMessage)       SIM800.println (F("AT+CNMI=1,2,2,1,0"));
    else if (gsmstatus == delSMS)           SIM800.println (F("AT+CMGDA=\"DEL ALL\""));

    else if (gsmstatus == setGPRS)          SIM800.println (F("AT+SAPBR=3,1, \"Contype\",\"GPRS\""));
    else if (gsmstatus == setAccPoint)      SIM800.print (F("AT+SAPBR=3,1, \"APN\",")), SIM800.println (ACCESSPOINT);
    else if (gsmstatus == setGPRSconnect)   SIM800.println (F("AT+SAPBR=1,1"));
    else if (gsmstatus == setBrokerconnect) SIM800.print (F("AT+CIPSTART=\"TCP\",")),  SIM800.println (SERVERNAME_PORT);
    else if (gsmstatus == setAuthPack)      AUTHsend ();
    else if (gsmstatus == setSubPack)       SUBsend("h/#");
    else if (gsmstatus == setPubPack)       MQTTsendDatastream();
    delayATcommand = 5000;
    prevGSMnastr = currmillis;
  }
}



void DelSMS ()
{
if (currmillis - 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 = currmillis;}
}


//void SMSzapros_ () {if (webasto)SMSzapros(); else {NeedTimer = 1; prevNeedTimer = currmillis; needAction = NEED_SMSZAPROS; w_bus_init = 1;}}

void Queue (const byte &actioN) {NeedTimer = 1; prevNeedTimer = currmillis; needAction = actioN; if (!webasto) w_bus_init = 1; } 

void readModem() //_____Цикл чтения входящих СМС-сообщений______________     
{

  static uint32_t timerMQTTreconnect = 0;
  static bool TimerMQTTreconnect = 0;

// если было неудачное подключение к MQTT, ждём час и снова пробуем
if (TimerMQTTreconnect && currmillis - timerMQTTreconnect > 3600000UL) 
    {
      TimerMQTTreconnect = 0; 
      fails = 3;
      settingGSM = 1;
    }





    if (!SIM800.available()) return;
    static bool SaveNumber2 = 0;      // флаг когда необходима запись номера#2, он true
    char currSymb = SIM800.read();

    if ('\r' == currSymb || '&' == currSymb)
       {
         if (isStringMessage!=0&&isStringMessage!=3) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
                {
if      (!currStr.compareTo(F("ZAPROS")))       {Queue(NEED_SMSZAPROS);}             // Передача параметров по СМС
else if (!currStr.compareTo(F("Service-info"))) {Queue(NEED_SERVICEINFO);}           // Передача сервисной информации  по СМС
else if (!currStr.compareTo(F("Erase DTC")))    {Queue(NEED_DTCCLEAR);}              // Запрос на стриание ошибок
else if (!currStr.compareTo(F("ZAPROSTEL")))    {SMSzaprosTEL();}                    // Передача номеров телефонов пользователей по СМС
else if (!currStr.compareTo(F("GSMResets-0")))  {ResetNumber=0; EEPROM.write (ResetNumber_cell, ResetNumber); Queue(NEED_SERVICEINFO);}     //сброс счетчика ресетов GSM модуля
else if (!currStr.compareTo(F("Version")))      {startSMS(isStringMessage);  SIM800.println (ver); EndSMS ();}               //запрос версии ПО


else if (!currStr.compareTo(F("Signal-level"))) {digitalWrite (DTR, LOW);  delay (150); SIM800.println(F("AT+CSQ")); digitalWrite (DTR, HIGH);}                // запрос уровня сигнала GSM
              
else if (!currStr.compareTo(F("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(F("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(F("Engine-ON")))  {startSMS(isStringMessage); SIM800.println(F("Dvigatel "));  
           if (!engine)  { digitalWrite (StartEng, HIGH);  prevStartEng=currmillis; StartEng_timer=true; reportEngine = true; prevReportEngine = currmillis; KTOreport = isStringMessage;} 
           else SIM800.println(F("uzhe ")); SIM800.println(F("start")); EndSMS();}
                                                                                 
else if (!currStr.compareTo(F("Engine-OFF")))   {startSMS(isStringMessage); SIM800.println(F("Dvigatel "));  
           if (engine){ digitalWrite (StartEng, HIGH);  prevStartEng=currmillis; StartEng_timer=true; reportEngine = false;} // если получили команду на выключение ДВС и он в настоящий момент работает - выключаем
           else SIM800.println(F("uzhe ")); SIM800.println(F("ostanovlen")); EndSMS();}          
              
else if (!currStr.compareTo(F("Impulse")))   {if (!webasto) {ProtocolSTART = IMPULSE;  EEPROM.write(ProtocolSTART_cell,ProtocolSTART);     
                                            startSMS(isStringMessage); SIM800.println(F("zapusk GND_impulse")); EndSMS();}}

else if (!currStr.compareTo(F("Startbus")))  {if (!webasto) {ProtocolSTART = STARTBUS; EEPROM.write(ProtocolSTART_cell,ProtocolSTART);  webasto = 0;  
                                            startSMS(isStringMessage); SIM800.println(F("zapusk BUS")); EndSMS();}}

else if (!currStr.compareTo(F("Potencial"))) {if (!webasto) {ProtocolSTART = POTENCIAL; EEPROM.write(ProtocolSTART_cell,ProtocolSTART);   
                                            startSMS(isStringMessage); SIM800.println(F("zapusk +12V Potencial")); EndSMS();}}

else if (!currStr.compareTo(F("DallasAddr"))) {startSMS(isStringMessage); SMSDallasAddr(); EndSMS();}

else if (currStr.endsWith(F("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(F("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(F("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(F("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(F("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(F("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(F("ResetNumbers")))   {if (isStringMessage == 1) {startSMS(isStringMessage); SIM800.println(F("Phone numbers are erased")); EndSMS(); 
                                                                     
             TelNumber[1] = "000000000000"; TelNumber[2] = "000000000000"; for (int i=0; i<12; i++) {EEPROM.write (i+TelNumber1_cell,  TelNumber[1][i]); EEPROM.write (i+TelNumber2_cell,  TelNumber[2][i]); }}}

else if (!currStr.compareTo(F("WriteNumber2"))&& isStringMessage == 1)   { 
                SaveNumber2 = 1; startSMS(isStringMessage); SIM800.println(F("Otpravte lyuboye SMS s nomera#2 dlya sohraneniya nomera")); EndSMS();} 

                                                                        

                                                     
else if (!currStr.compareTo(F("Balance")))    SMSbalance();
            isStringMessage = 0;
                }
              
              
else if (isStringMessage==3){ if (!currStr.compareTo(F("WriteNumber1")))   { TelNumber[1] = TelNumber[3]; for (int i=0; i<12; 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(F("ZAPROS")))   { SMSzapros();}   
                                             else if (!currStr.compareTo(F("ZAPROSTEL")))   { SMSzaprosTEL();}               // Передача номеров телефонов пользователей по СМС            
               isStringMessage = 0;
              
              }           



                
else if (isStringMessage==0) {  if (TelNumber[1]!="000000000000" && !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(F("+CSQ:"))) //если текущая строка начинается с "+CSQ",то значит был запрос на уровень сигнала GSM, отправим ответ запрашивающему
                  {
                  startSMS(KTOzapros);
                  SIM800.print (currStr);
                  EndSMS();
                  }
                                                }

                else if    (currStr.startsWith(F("+CMT:")) && !SaveNumber2) { isStringMessage = 3; for (int i =0; i<12; i++) {TelNumber[3][i]=currStr[i+7];}}
                else if    (currStr.startsWith(F("+CMT:")) && SaveNumber2) { for (int i =0; i<12; i++) {TelNumber[3][i]=currStr[i+7];} TelNumber[2] = TelNumber[3]; for (int i=0; i<12; 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; } 

// ----------------------------данные для MQTT

if (currStr.indexOf(F("CLOSED")) > -1 || currStr.indexOf(F("ERROR")) > -1)  {
        fails = 3;
        settingGSM = 1;
      }
      if (currStr.indexOf(F("OK")) > -1) {
        if (!settingGSM){ if (failresets > 4 || (failresets <= 4 && gsmstatus >= setPubPack)) {fails = 0; digitalWrite (DTR, HIGH); interval_doprosGSM = 123000UL;}}
        if (settingGSM && gsmstatus > WaitGSM && gsmstatus < setBrokerconnect) {
             // если подключиться к MQTT серверу не удалось, оставляем настройки только для СМС
             // и запускаем таймер на час, чтобы через час ещё раз пробовать:
             if (gsmstatus == delSMS && failresets > 4) 
                  {settingGSM = 0; 
                   digitalWrite (DTR, HIGH);
                   timerMQTTreconnect = currmillis;
                   TimerMQTTreconnect = 1;
                   }  
             gsmstatus++; if (gsmstatus>16)gsmstatus=16;
             fails = 0;
             delayATcommand = 400;
                                                                                }
      }
      if (currStr.indexOf(F("CONNECT")) > -1) if (gsmstatus == setBrokerconnect) {
          gsmstatus++; if (gsmstatus>16)gsmstatus=16;
          fails = 0;
          delayATcommand = 300;
        }
      if (currStr.indexOf(F("SMS Ready")) > -1) if (gsmstatus == WaitGSM) {
          gsmstatus++; if (gsmstatus>16)gsmstatus=16;
          fails = 0;
          delayATcommand = 300;
        }
      if (currStr.indexOf(F("SEND OK")) > -1) {
        fails = 0;
        if (settingGSM && gsmstatus >= setAuthPack && gsmstatus <= setPubPack) {
          if (gsmstatus == setPubPack) {
            settingGSM = 0;
            failresets = 0;
          } delayATcommand = 300;
          gsmstatus++; if (gsmstatus>16)gsmstatus=16;
        }
      }


//-------------------------топики MQTT, принимаемые от брокера
     
      if (currStr.indexOf(F("h/ctrl")) > -1) 
      {
        bool comanda = currStr.substring(currStr.indexOf(F("h/ctrl")) + 6).toInt();
        if (comanda) {StartWebasto(); report = false;} 
        else {StopWebasto();}
      }
      if (currStr.indexOf(F("h/time/ctrl")) > -1) {
        String TimeW = currStr.substring(currStr.indexOf(F("h/time/ctrl")) + 11);
        TimeWebasto = TimeW.toInt();
        EEPROM.write(TimeWebasto_cell,TimeWebasto);
        PUBsend("h/time/stat",  TimeW, 0);
        remTime(0) ;
      }
      if (currStr.indexOf(F("h/refr0")) > -1)  MQTTsendDatastream();



// ------------------------конец данных для MQTT

              
              } 


               
        currStr = "";
      } 
 
    else if ('\n' != currSymb && '$' != currSymb)  currStr += String(currSymb);
    if (currStr.length()>100) currStr = "";
}




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("Modem 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); 
     GND_impulse_timer = 1;
     prevGND_impulse = currmillis;
  }

 else 
  {
     StartMessageRepeat = 0;
     webasto = 1; digitalWrite (OutWebasto_12V, HIGH);
     prevWorkCycleHeater=currmillis;
     WorkCycleHeater_timer = true;
  }
report = true; prevReport = currmillis;
w_bus_init = NEED;
Refresh_time = 60;
}

void StopWebasto()
{
 if (ProtocolSTART==IMPULSE)
   { 
      digitalWrite (OutWebasto_GndImp, LOW); 
      GND_impulse_timer = 1;
      prevGND_impulse = currmillis;
   }
 else 
   {
      StopMessageRepeat = 0;
      webasto = 0; digitalWrite (OutWebasto_12V, LOW);
      WorkCycleHeater_timer = false;
   }
   report = false;
   Refresh_time = 1200;
}



void Heater_BUS (){


static byte header = 0;           // состояние заголовка 
static byte message_size = 0;     // размер тела принимаемого сообщения, кол-во байт
static byte j = 2;                // инкремент
static byte n = 2;
const byte bufsize = 140;  // размер буфера принятого сообщения
static byte buf [bufsize] = {0};  // буфер принятого сообщения
static byte checksum = 0;         // контрольная сумма входящего сообщения
static uint32_t prevRESETheader=0; // таймер сброса заголовка если в момент приёма сообщения данные оборвались
static bool RESETheader_timer = 0; // таймер сброса заголовка если в момент приёма сообщения данные оборвались



  
if      (Heater == EVO || Heater == VEVO){
if (webasto) {
    if (StartMessageRepeat<4 && (currmillis-Prev_PeriodW_BusStartStop>800) && w_bus_init >= 9){
  sendMessage (HEATER_START, sizeof(HEATER_START)); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = currmillis;
  
    }
  if (StartMessageRepeat>=4){ if (currmillis-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 = currmillis;
    }}}





else if (StopMessageRepeat<4 && (currmillis-Prev_PeriodW_BusStartStop>800)){
  sendMessage (HEATER_STOP, sizeof(HEATER_STOP));
StopMessageRepeat++; 
StartMessageRepeat = 0;
   Prev_PeriodW_BusStartStop = currmillis;
  
  
  }


if (!timerInitflag && w_bus_init==NEED) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = currmillis; timerInitflag = 1;}
if ( timerInitflag && (currmillis - timerInit>24) && w_bus_init==NEED) {timerInit = currmillis; digitalWrite(TX, 1); w_bus_init=2; }
if ( timerInitflag && (currmillis - 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){buf[0]=K_LINE.read();  
         if (buf[0]==0x4F || buf[0]==0x44){header = 1; RESETheader_timer=1; prevRESETheader = currmillis; }
         else {header = 0; RESETheader_timer=0;}
         }                  

 // длина сообщения
 else if (header == 1 ){buf[1]=K_LINE.read(); message_size = buf[1]; if (message_size > bufsize) message_size = bufsize;  header = 4;j=2;n=2;checksum = 0;} 

 // пишем тело сообщения 
 else if (header == 4 && 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; 
  j++;} 

 } // end of K_LINE.available()

 // сообщение приняли, действуем
 if (header == 5) {  
   
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 = currmillis;} // проверяем наличие пламени                                                
                 
                 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 = currmillis;}       // проверяем наличие пламени у 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 = currmillis; timerInitflag = 1;}
if ( timerInitflag && (currmillis - timerInit>299)  && w_bus_init==NEED) {timerInit = currmillis; digitalWrite(TX, 1); w_bus_init=2; }
if ( timerInitflag && (currmillis - timerInit>49)   && w_bus_init==2) {timerInit = currmillis; digitalWrite(TX, 0); w_bus_init=3; }
if ( timerInitflag && (currmillis - timerInit>24)   && w_bus_init==3) {timerInit = currmillis; digitalWrite(TX, 1); w_bus_init=4; }
if ( timerInitflag && (currmillis - 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){buf[0]=K_LINE.read();  
         if (!bitRead (buf[0],6) && bitRead (buf[0],7)){header = 1; RESETheader_timer=1; prevRESETheader = currmillis; }
         
         }                  

 // второй старт байт
 else if (header == 1){buf[1]=K_LINE.read(); if (buf[1]==0xF1){ header = 2;} else {header = 0; RESETheader_timer=0;}} 

 // третий старт байт
 else if (header == 2){ 
  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) читаем этот дополнительный байт:
else if (header == 3){
  buf[3]=K_LINE.read(); 
  message_size = buf[3]; 
  if (message_size > bufsize) message_size = bufsize;  
  checksum = 0; header = 4;  
                         }

  // пишем тело сообщения 
 else if (header == 4 && 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; 
  j++;} 

 } // end of K_LINE.available()

 // сообщение приняли, действуем
 if (header == 5) {  

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



// таймер сброса заголовка если данные оборвались во время приёма заголовка
if (RESETheader_timer && currmillis - prevRESETheader > 500) {RESETheader_timer = 0; header = 0;}   

if (currmillis - last_Flame>20000 && ProtocolSTATUS==STATUSBUS) {startWebasto_OK=0; last_Flame = currmillis;}  // делаем статус "нет пламени" через 20 сек, если не получаем сообщения от котла

if (Initreset && currmillis - 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 && currmillis - prevNeedTimer>11000) || w_bus_init == 13)  {NeedTimer = 0; 
             if (currmillis - 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() {

static bool resettimer = 0;             // для таймера удерживания реле в режиме сброс питания
static uint32_t  resetTimer = 0;        // для таймера удерживания реле в режиме сброс питания
  
  if (!resettimer) {
    digitalWrite (ResetGSM, RelayON);
    resettimer = 1;
    resetTimer = currmillis;
  }
  else if (currmillis - resetTimer > 5000 ) {
    resettimer = 0;

    digitalWrite (ResetGSM, !RelayON);
    digitalWrite (DTR, LOW);
    delay (150);

    prevGSMnastr = currmillis;
    delayATcommand = 150;
    fails = 0;
    failresets ++; if (failresets > 4) failresets = 5;
    gsmstatus = WaitGSM;
    settingGSM = 1;
    interval_doprosGSM = 123000UL;
    ResetNumber++;  EEPROM.write (ResetNumber_cell, ResetNumber);
  }
}




void sendMessage(const byte *command, const size_t size){

 Initreset = 1;  prevInitreset = currmillis;  // включение таймера сброса инита
 
 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]); 
      }
  
  }
  }



void AUTHsend () 
{
 cipsend_begin ();
 uint16_t timeBroker       = TIMEBROKER;   
  
  SIM800.write (0x10);
  SIM800.write (strlen(PROTOCOLIUS) + strlen(MQTTNAME) + strlen(MQTTUSER) +  strlen(MQTTPASSWORD) + 12);
  SIM800.write ((byte)0);
  SIM800.write (strlen(PROTOCOLIUS));
  SIM800.write (PROTOCOLIUS);
  SIM800.write (0x03);
  SIM800.write (0xC2);
  
  timeBroker *=60;
  byte * timeBr = (byte*)&timeBroker;
  SIM800.write(*(timeBr+=1)); // время сеанса связи с брокером, сек (ст. байт)
  SIM800.write(*(--timeBr));  // время сеанса связи с брокером, сек (мл. байт)

//SIM800.write (0x04);    // время сеанса связи с брокером, сек (ст. байт)
//SIM800.write (0xB0);    // время сеанса связи с брокером, сек (мл. байт)

  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTNAME));
  SIM800.write (MQTTNAME);
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTUSER));
  SIM800.write (MQTTUSER);
  SIM800.write ((byte)0);
  SIM800.write (strlen(MQTTPASSWORD));
  SIM800.write (MQTTPASSWORD);
  SIM800.write (0x1A);
}

void PUBsend  (char topPub[30], const String Command, const bool &multidata) {

  if (!multidata) {cipsend_begin ();}
  SIM800.write (0x30);
  SIM800.write (strlen (topPub) + Command.length() + 2);
  SIM800.write ((byte)0x00);
  SIM800.write (strlen (topPub));
  SIM800.write (topPub);
  for (byte i = 0; i < Command.length(); i++) SIM800.write (Command[i]);
  if (!multidata) {SIM800.write(0x1A);  digitalWrite (DTR, HIGH);}
}


void SUBsend (char topSub[20]) {
  cipsend_begin ();
  SIM800.write (0x82);
  SIM800.write (strlen(topSub) + 5);
  SIM800.write ((byte)0);
  SIM800.write (0x01);
  SIM800.write ((byte)0);
  SIM800.write (strlen(topSub));
  SIM800.write (topSub);
  SIM800.write ((byte)0x00);
  SIM800.write (0x1A);
}





void  MQTTsendDatastream() 
{
  cipsend_begin ();
  PUBsend ("h/time/stat",  String(TimeWebasto), 1);
  remTime(true);
  PUBsend ("h/stat",       String(webasto) + "&$", 1);
  PUBsend ("h/flame",      String(startWebasto_OK), 1);
  PUBsend ("h/temp/dvs",   String(Temper(EngineC)), 1);
  PUBsend ("h/temp/heat",  String(HeaterC), 1);
  PUBsend ("h/temp/ul",    String(Temper(UlicaC)), 1);
  PUBsend ("h/temp/sal",   String(Temper(SalonC)), 1);
  SIM800.write (0x1A);
  prev_refreshMQTT = currmillis;
  digitalWrite (DTR, HIGH);
 }

void remTime   ( bool s) {
  int rem = TimeWebasto - ((currmillis - prevWorkCycleHeater) / 60000ul);
  PUBsend ("h/remtime",    webasto ? String(rem) : "выкл", s);
}

void cipsend_begin () 
{
  digitalWrite (DTR, LOW); delay (150);
  SIM800.println (F("AT+CIPSEND"));
  delay (250);
}


void refreshDataMQTT ()
{
  if (currmillis - prev_refreshMQTT > (uint32_t)Refresh_time * 1000) 
  {
     MQTTsendDatastream();
     prev_refreshMQTT = currmillis;
     fails++;
  }
}

 

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Залил этот скетч, не работает, котел не запускается, если нажать кнопку ручного запуска то в смартфоне кнопка загорается зелёным , но котел тоже не запускается, на СМС не отвечает, хотя смс доставляются . Температура тоже не правильно отображается котел -50 градусов, салонную тоже не видит , у меня только один датчик на салон установлен. Светодиод на 13 порте тоже не загорается. Пробовал смс отправлять Gsm trinker , чтобы номер телефона в память записать , тоже не получилось.

MaksVV
Offline
Зарегистрирован: 06.08.2015

Светодиод на 13 там отключен. -50котел это по умолчанию стоит. Салонную не видит и проблемы с смс это скорее всего надо еепром почистить и там же настроить адрес салонного датчика. Потом после заливки основного скетча записать номер тел в память. А вот почему не запускается надо както выяснить. Я проверял - на шине w-bus сообщения идут норм. Может с импульсами инита косяк какой. Осцил у меня сдох. Как щас проверить хз

UPD. И смотри, может байт запуска у тебя не 0х20, а 0х21. тоже настраивается в скетче чистки еепром

UPD2. Проверил полностью протокол обмена на шине w-bus на эмуляторе. Всё работает. И даже импульсы инита (25мс LOW 25мс HIGH) скорее всего нормально подаются, потому что в отладке этот момент байтом 00 показывался как и на предыдущих версиях скетча.

Рекомендую для диагностики неисправности подключить на w-bus отладку (юсб-клайн адаптер + WTT в режиме монитор W-шины), чтобы посмотреть что там происходит, а то вдруг опять какой-нибудь проводок отпал, а мы тут... 

Dushman7776
Offline
Зарегистрирован: 13.01.2019

Почистил епром , залил заново скетч , вроде смс заработали , правда,  после записи первого номера в память, почему то ответная смска не пришла , но номер записался . Завтра на авто проверю  , на столе вроде работает , пробовал через mqtt  отправить команду на включение котла , а потом смской статус проверить , смска говорит что котел ОН а СТАРТ Вебасто Файл, вроде так и должно , правда датчик салона в машине остался , думаю что тоже заработает. 

MaksVV
Offline
Зарегистрирован: 06.08.2015

Думаю изза еепрома и не работало. Забыл, там же еще хранится байт запуска котла, а раз еепром был не в поряде, то и байт запуска был корявый, поэтому не работало

Pashok3D
Offline
Зарегистрирован: 20.01.2019

ВОт и пладки приусплели .. Кто там в Украине хотел ? 

MaksVV
Offline
Зарегистрирован: 06.08.2015

оо фигасе, это уже новая ревизия. Надеюсь я там нигде не накосячил. Круть. А чёрные ведь дороже вроде, не? 

MaksVV
Offline
Зарегистрирован: 06.08.2015

седня скидки на али. SIM800L по 100 рублей)) спешите делать заказы. 

Pashok3D
Offline
Зарегистрирован: 20.01.2019

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

Pashok3D
Offline
Зарегистрирован: 20.01.2019

чето на алике не видел скидки .  как  покупка оптом  на 10к получишь скидку в 500р

MaksVV
Offline
Зарегистрирован: 06.08.2015

11 ноября день распродаж. ну вот например sim800L

Pashok3D пишет:

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

посмотрел, нет, сейчас от цвета цена не зависит, можно любой выбрать.  5 штук с доставкой в Екатеринбург сейчас стоит 400 рублей. Вообще норм цена, учитывая идеальное качество. 

Baron8
Offline
Зарегистрирован: 12.11.2019

Залил новый скетч с mqtt заработал( включал глушилку, сеть пропадала, отключил , зарегилась и всё работает) повесил два датчика -салона и двигла, всё ок. Температуру котла не читает((( висит -50. СМС-ки не работают ( я их не смог получать и раньше при разных прошивках, не знаю прописался мой номер или нет) Но с mqtt - супер, наверное можно не огорчаться за смс. ( заметил , что после отправки смс через 10-20 сек. перегружается sim800- релюха клацает( по идее номер прописался), мне смс не приходит... дальше пытаюсь запустить по смс - котёл молчит... как-то так. наверное сумбурно написал, но думаю понятно. А может в скетче нужно сделать для 13-значного номера... может нужно место под "+ " с которого начинается номер и потом 12 цифр ?)))