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

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

Класс .  Интересно какой минемальный заказ .?  

Уже жсм модуль у меня  . ручки чешуться уже  поставить и проверить связь . Хотя и от сигналки толку хватит . 

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

минимально 10 плат. Примерно 800 руб. за все вместе с доставкой получается. 

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

а можно както дополнить скетч #531   чтобы так и остался пин  импульно на массу вк\вкл   , индикатор о вкл котла , и пин на включение помпы  с таймером отключение помпы ? 

К примеру по импульсу вкл вкл можно подключить к сигналке канала 3   ,  так как есть котлы  без одключение помпы  и нужно чтобы после вкл котла помпа еще поработала для остывание пламени .

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

проще другой скетч переделать, в котором все твои хотелки уже есть. надеюсь я найду время и доделаю его. А у тебя разве работает индикация пламени? у тебя ж другая версия протокола w-bus -  3.1 помнится. Там должно по другому пламя определяться

deep_jeet
Offline
Зарегистрирован: 26.12.2018

Hi MaksVV

         Do you have complete list of 98xx/xx series fault codes . I tried to google but couldn't get much info about these codes . There is lack of info about these codes on our country websites but i saw lots of info in your language . I tried to translate those websites to english and found some code . If you have complete list of codes and can list it here will really appriciate .

            when i send  81 51 F1 A1 64   error request command , boiler reply back with fault codes command where index 4 gives 98 and index 5 gives rest of code(00,01,02 etc) . Index 7 gives value after /xx . Following are few codes i found .

No start                                                9800/00

Flame failure                                           9801/01

Operating voltage too low                               9802/01

Flame Was Detected Prior to Combustion                  9803/00

Metering pump interruption                              9820/01

Compustion air fan interruption                        9821/01

Glow plug / flame monitor interruption                 9822/01
 
Circulation pump interruption                         9823/01  
MaksVV
Offline
Зарегистрирован: 06.08.2015

To be honest, nothing is clear. Give an example of the boiler response with at least one error .

deep_jeet
Offline
Зарегистрирован: 26.12.2018

Please check details . Thanks

Error summery from WTT software 

Error:

------

  Fault 1..................................Glow plug / flame monitor interruption           

    Code..................................................................9822/01           

    Counter.....................................................................1           

    Temperature................................................................22 [°C]      

    Operating state................................Flame detector interrogation 1   

 

 

Data collected from Arduino serial : 

 

Error Request Command  

————————

81   

51

F1

A1

64

————————

Response from Webasto ( Fault 1 Detail )

 

88            

F1

51

E1

98  -> First 2 digits of error

22  -> Last 2 digits of error

10

1     -> xxxx/01     value after  \  in error code 

1     -> Fault Counter ( How many times same fault occured )

1     -> Boiler state

B7   -> Temp at time error was recored in memory

2F

-----------------------------------

 Error request reply

84

F1

51

E1

FF

FF

1   -> Number of faults present in controller

A6

—————————————

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

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

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

Dushman7776 пишет:

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

 

Походу #282

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

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

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

Dushman7776 пишет:
Какой скетч самый послдений рабочий , полнофунциональный , или такого еще нет?

ещё толком нет. Вот что есть на данный момент. для платы 8.5 - 8.6. 

перед заливкой основного скетча заливаем этот для подготовки еепром (смотрим коменты и там же выполняем какие настройки будут по умолчанию, чтобы потом это смс_ками не настраивать) . Ждём когда встроенный LED загорится, далее можно заливать основной скетч. 

Ниже скетч подготовки еепром:

#include <EEPROM.h>


enum Cells {
ResetNumber_cell,      //0
TimeWebasto_cell,      //1
ProtocolSTART_cell,    //2
Zapusk_cell,           //3
ProtocolSTATUS_cell,   //4
Heater_cell,           //5
delta_cell,            //6
sizeCells,
TelNumber1_cell =20,  //20
TelNumber2_cell =40   //40
};




// возможные протоколы чтения статуса котла:

enum ProtocolSTATUS_ {
   STATUSBUS,                 // статусы котла читаются по цифровой шине
   ANALOG                     // статусы котла считываются силами ардуино - по датчикам 
};                   


// возможные протоколы запуска котла:

enum ProtocolSTART_  {
   STARTBUS,                  // запуск котла происходит по цифровой шине
   IMPULSE,                   // запуск котла происходит импульсом GND (для подпайки к кнопке пуск на таймере котла)
   POTENCIAL                  // запуск котла происходит подачей потенциала +12В (пока плюс висит - котёл работает)
};        

// тип котла: 

enum Heater_  { TTC_E, VEVO, EVO, HYDRONIC};                 


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

byte ProtocolSTATUS = STATUSBUS;  // в данном случае статусы читаются по цифровой шине                 
byte ProtocolSTART  = STARTBUS;   // в данном случае запуск котла происходит по цифровой шине                 
byte Heater         = TTC_E;      // в данном случае тип котла Termo Top C / E  (будет шина не w-bus, а просто к-лайн, к которой настройки 10400 8N1) 
byte Zapusk         = 0x20;       // в данном случае байт на старт котла 0x20 (для шины w-bus)
byte worktime       = 30;         // в данном случае время цикла работы котла 30 минут 
byte deltaT         = 45;         // разница температур улицы и выхлопа, выше которой считается, что котёл успешно стартанул
///////////////////////////////////////////////


void setup() {
 
  pinMode(13, OUTPUT);
  digitalWrite(13, 0);
  EEPROM.write(TimeWebasto_cell, worktime); 
  EEPROM.write(ProtocolSTART_cell, ProtocolSTART);
  EEPROM.write(ProtocolSTATUS_cell, ProtocolSTATUS);
  EEPROM.write(Heater_cell, Heater);
  EEPROM.write(ResetNumber_cell, 0);
  EEPROM.write(Zapusk_cell, Zapusk);   
  EEPROM.write(delta_cell, deltaT);   
  for (int i = sizeCells ; i < EEPROM.length() ; i++) EEPROM.write(i, '0');  

  
  digitalWrite(13, HIGH);
}

void loop() {}

Ниже основной скетч: 

//#define debugW_bus        // раскоментировать эту строку для отладки, при этом нужно вынуть SIM800 и подключить юсб<->уарт, т.к. отладка идёт в УАРТ, предназначенный для GSM 
//#define debugSIM800

#include <EEPROM.h>
enum Cells {
ResetNumber_cell,      //0
TimeWebasto_cell,      //1
ProtocolSTART_cell,    //2
Zapusk_cell,           //3
ProtocolSTATUS_cell,   //4
Heater_cell,           //5
delta_cell,            //6
TelNumber1_cell =20,  //20
TelNumber2_cell =40   //40
};

#include <Button.h>

Button test;

// для GSM модуля *********************
#include <SoftwareSerial.h>

#ifndef debugW_bus
      SoftwareSerial SIM800 (10, 11);//Rx, Tx   //UART для соединения с GSM модулем
#else 
      SoftwareSerial DEBUG (10, 11); //Rx, Tx   //UART для соединения с отладкой (используется юсб<->УАРТ вместо SIM800)
#endif

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

String currStr = "";
String TelNumber1 =   "000000000000";
String TelNumber2 =   "000000000000";
String BufferNumber = "000000000000";
bool SaveNumber2 = 0;  // флаг когда необходима запись номера#2, он true
byte isStringMessage = 0; 
byte KTOzapros = 0;
byte KTOreport = 1;

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


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



// дефайны входов выходов на соостветствующие пины ************** (плата 8.5 с разъемом)

#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 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, в данном случае включается низким уровнем на пине

*/

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

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

enum TempC {VyhlopC, EngineC, UlicaC, SalonC, size_arrayTemp}; // перечисление нужных температур (в конце размер массива температур)

// ниже соответствие адресов датчиков различным температурам (изначально =20*С)
 byte DS18B20 [size_arrayTemp][10] = {
{0x28, 0xFF, 0xB2, 0xB5, 0xC1, 0x17, 0x05, 0xD1, VyhlopC,  20}, 
{0x28, 0xFF, 0xD3, 0xE2, 0xC1, 0x17, 0x04, 0x0D, EngineC,  20}, 
{0x28, 0xFF, 0xF8, 0xBC, 0xC1, 0x17, 0x04, 0x48, UlicaC,   20},  
{0x28, 0xFF, 0x3F, 0xB7, 0xC1, 0x17, 0x05, 0xF1, SalonC,   20}
};
byte delta = 50;  // разница температур выхлопа и улицы, выше которой считается, что пламя в котле есть. 

// для организации W-BUS и различные таймеры********************

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; // таймер сброса заголовка если в момент приёма сообщения данные оборвались


// ниже строка даже не спрашивайте что это)) это так... кот по клаве прошёл
#define ConstArray(...)  [](void)->size_t{ const byte _[] = { __VA_ARGS__}; return sizeof(_)/sizeof(_[0]); }(),[](void)->const byte *{ const static byte _[] = { __VA_ARGS__}; return _; }()

// команды для котлов ЭВО
byte Zapusk = 0x20;
#define HEATER_START         ConstArray (Zapusk, 0x3B)
#define HEATER_PRESENCE      ConstArray (0x44, Zapusk, 0x00)
#define HEATER_STOP          ConstArray (0x10)
#define HEATER_STATUS_VEVO   ConstArray (0x50, 0x05)
#define HEATER_STATUS_EVO    ConstArray (0x50, 0x30, 0x0A, 0x10)



// команды для котлов ТТС/TTE
#define START_SESSION   ConstArray (0x81)
#define REQUSET_2A10101 ConstArray (0x2A, 0x01, 0x01)
#define REQUSET_2A10102 ConstArray (0x2A, 0x01, 0x02)
#define REQUSET_2A10105 ConstArray (0x2A, 0x01, 0x05)
#define REQUSET_DTC     ConstArray (0xA1)
#define START_TTC       ConstArray (0x31, 0x22, 0xFF)
#define STOP_TTC        ConstArray (0x31, 0x22, 0x00)


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;

byte w_bus_init = 0;                      //флаг проведена или нет инициализация шины w-bus (25мс LOW, 25мс HIGH для  ЭВО
                                          //                                            либо 300ms LOW, 50ms HIGH, 25ms LOW, 3025ms HIGH для TTC 
bool flagStartPresence =  1;              //флаг что отправляем в момент периодического поддержания связи W-Bus status или start
byte StartMessageRepeat = 0;              //количество отправленных сообщений на старт котла
byte StopMessageRepeat =  0;              //количество отправленных сообщений на остановку котла

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;                    //переменная для таймера периодического измерения напряжения АКБ

//для таймера создания импульса 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

//для таймера инита шины W-BUS
uint32_t timerInit = 0; bool timerInitflag = 0;

//для таймера контроля жив или мертв обмен по W-bus 
uint32_t last_W_bus = 0; bool kotel_zhiv = 0;

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

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

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

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


// СТАРТОВЫЙ ЦИКЛ

void setup() 
{
delay (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);  // реле ресет на данный момент делаем "неактивно"

#ifndef debugW_bus
   SIM800.begin(19200);           // сериал соединение для gsm модуля
   delay(100);
   NastroykaGSM ();
#else DEBUG.begin(9600);
#endif

TimeWebasto =    EEPROM.read(TimeWebasto_cell);
ProtocolSTART  = EEPROM.read(ProtocolSTART_cell);
ProtocolSTATUS = EEPROM.read(ProtocolSTATUS_cell);
ResetNumber =    EEPROM.read(ResetNumber_cell);
Zapusk =         EEPROM.read(Zapusk_cell);
Heater =         EEPROM.read(Heater_cell);
delta  =         EEPROM.read(delta_cell);
for (int i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+TelNumber1_cell);
for (int i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+TelNumber2_cell);

#ifndef debugSIM800
        if (Heater == EVO || Heater == VEVO) K_LINE.begin(2400, SERIAL_8E1);
   else if (Heater == TTC_E) K_LINE.begin(10400);
#else 
K_LINE.begin(9600);
#endif


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;

#ifndef debugW_bus
   if (trevoga && !alarmSMS) AlarmSMS ();
   if (gsmOK)readSMS();
   Reset_gsm();
   delSMS();
#endif

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_;
}}}


prevVpit=millis();
}}



int8_t Temper (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();  }} 

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




#ifndef debugW_bus
   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 startNumber1SMS() //__________________Цикл подготовки модуля к отправке СМС-сообщений по первому номеру
{
     digitalWrite (DTR, LOW); // выводим из спячки GSM модуль
         delay (150);
     SIM800.print(F("AT+CMGF=1\r"));
         delay(150);
     SIM800.print(F("AT+CMGS=\"")); SIM800.print(TelNumber1); SIM800.println("\""); 
         delay(150);
}

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

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

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 readSMS() //_____Цикл чтения входящих СМС-сообщений______________     
{
    if (!SIM800.available()) return;
    char currSymb = SIM800.read();
#ifdef debugSIM800 
if (currSymb!=0x13 && currSymb!=0x11) K_LINE.print (currSymb); 
#endif
    if ('\r' == currSymb)
       {
         if (isStringMessage!=0&&isStringMessage!=10) //если текущая строка - SMS-сообщение, отреагируем на него соответствующим образом
                {
if      (!currStr.compareTo("ZAPROS"))      {SMSzapros();}              // Передача параметров по СМС
else if (!currStr.compareTo("ZAPROSTEL"))   {SMSzaprosTEL();}           // Передача номеров телефонов пользователей по СМС
else if (!currStr.compareTo("ServiceINFO")) {ServiceINFO();}            // Передача сервисной информации  по СМС
else if (!currStr.compareTo("Resets0"))   {ResetNumber=0; EEPROM.write (ResetNumber_cell, ResetNumber); ServiceINFO();}     //сброс счетчика ресетов GSM модуля

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

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


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


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


                                                     else                    {if (isStringMessage == 1) startNumber1SMS(); 
                                                                         else if (isStringMessage == 2) startNumber2SMS();
                                                                         SIM800.println(F("dvigatel uzhe ostanovlen")); EndSMS(); }}          
              
               else if (!currStr.compareTo("Impulse"))   {if (!webasto) {ProtocolSTART = IMPULSE;  EEPROM.write(ProtocolSTART_cell,ProtocolSTART);     
                                                                              if (isStringMessage == 1) startNumber1SMS();
                                                                        else  if (isStringMessage == 2) startNumber2SMS(); 
                                                                        SIM800.println(F("zapusk GND_impulse")); EndSMS();}}

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

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

               else if (currStr.endsWith("Status"))   {if (!webasto) {byte st = currStr.toInt(); if (st >= STATUSBUS && st<=ANALOG )ProtocolSTATUS = st; EEPROM.write(ProtocolSTATUS_cell,ProtocolSTATUS);   
                                                                              if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else  if (isStringMessage == 2) startNumber2SMS(); 
                                                                        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);   
                                                                              if (isStringMessage == 1) startNumber1SMS(); 
                                                                        else  if (isStringMessage == 2) startNumber2SMS(); 
                                                                        SIM800.print (F("Heater: "));
                                                                             if (Heater == 0)SIM800.println(F("TTC_E")); 
                                                                        else if (Heater == 1)SIM800.println(F("VEVO"));
                                                                        else if (Heater == 2)SIM800.println(F("EVO"));
                                                                        else if (Heater == 3)SIM800.println(F("HYDRONIC"));
                                                                        EndSMS();}}      
                                                                                                                                              
               else if (currStr.endsWith("Delta"))   {if (!webasto) {delta = currStr.toInt(); //
               EEPROM.write(delta_cell, delta);
                     if (isStringMessage == 1) startNumber1SMS(); 
               else  if (isStringMessage == 2) startNumber2SMS(); 
               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);
                     if (isStringMessage == 1) startNumber1SMS(); 
               else  if (isStringMessage == 2) startNumber2SMS(); 
               SIM800.print(F("Webasto time: ")); SIM800.print(TimeWebasto); SIM800.print(F("min")); EndSMS();}}
               
               else if (currStr.endsWith("zapusk")) {byte Z =currStr.toInt(); if (Z>=0x14 && Z<=0x17) Zapusk= Z+12;
                              if (isStringMessage == 1)startNumber1SMS(); 
                        else  if (isStringMessage == 2) startNumber2SMS(); 
                        SIM800.print(F("Zapusk byte: ")); SIM800.print(Zapusk, HEX); SIM800.print(F("h")); EndSMS();}

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

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

                                                                        

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



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

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



void SMSzaprosTEL(){
       if (isStringMessage == 1)   startNumber1SMS();
  else if (isStringMessage == 2)   startNumber2SMS();
  else if (isStringMessage == 10)  startBufferNumberSMS();
  SIM800.print(F("Tel#1: ")); SIM800.println(TelNumber1);
  SIM800.print(F("Tel#2: ")); SIM800.println(TelNumber2); 
  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() {
 
 startNumber1SMS();
SIM800.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 startNumber2SMS();
SIM800.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
 EndSMS();      
 alarmSMS = true;
}

#endif

void SMSzapros()

{
#ifndef debugW_bus  
  if (isStringMessage == 10){
 startBufferNumberSMS();

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

     if (trevoga)  SIM800.println (F("Vnimanie!!! Trevoga!!! Sirena Vkl!"));
     
  SIM800.print(F("Battery: ")); SIM800.print (Vpit); SIM800.println(F("V"));
  SIM800.print(F("Engine:  ")); SIM800.print (Temper(EngineC)); SIM800.println(F("*C"));
  SIM800.print(F("Vyhlop:  ")); SIM800.print (Temper(VyhlopC)); SIM800.println(F("*C"));
  SIM800.print(F("Ulica:     ")); SIM800.print (Temper(UlicaC));  SIM800.println(F("*C"));
  SIM800.print(F("Salon:    ")); SIM800.print (Temper(SalonC));  SIM800.println(F("*C"));  
  
  
 
  }  
   EndSMS();    
#endif                             
}



void ServiceINFO(){
       if (isStringMessage == 1)   startNumber1SMS();
  else if (isStringMessage == 2)   startNumber2SMS();
  SIM800.print(F("Zapusk:  "));
       if (ProtocolSTART==IMPULSE)   SIM800.println(F("GND Imp"));
  else if (ProtocolSTART==STARTBUS)  {SIM800.println(F("BUS"));
             if (Heater== VEVO || Heater== EVO) {SIM800.print(F("ZapuskByte: 0x")); SIM800.println (Zapusk, HEX);}}
  else if (ProtocolSTART==POTENCIAL) SIM800.println(F("Potencial+12V"));
  
  SIM800.print(F("Status:  "));
       if (ProtocolSTATUS==ANALOG)    SIM800.println(F("ANOLOG"));
  else if (ProtocolSTATUS==STATUSBUS) SIM800.println(F("BUS"));
  
  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"));
  
  if (ProtocolSTART!=IMPULSE) {SIM800.print(F("Webasto Time: ")); SIM800.print (TimeWebasto); SIM800.println(F("min"));}
  SIM800.print(F("SIM800 Resets: ")); SIM800.println (ResetNumber); 

  SIM800.print(F("DeltaT:  ")); SIM800.print(delta);SIM800.println(F("*C"));
  
   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 = 1;
}

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;
   w_bus_init = 0;
   
}



void Heater_BUS (){
  
if      (Heater == EVO || Heater == VEVO){
if (webasto) {
    if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800) && w_bus_init == 10){
  sendMessage (HEATER_START); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    
    if (flagStartPresence) sendMessage (HEATER_PRESENCE);  
    else {if (Heater == EVO) sendMessage (HEATER_STATUS_EVO);
          if (Heater == VEVO)sendMessage (HEATER_STATUS_VEVO);}
flagStartPresence = !flagStartPresence;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





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


if (!timerInitflag && w_bus_init==1) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = millis(); timerInitflag = 1;}
if ( timerInitflag && (millis() - timerInit>24) && w_bus_init==1) {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=10; }


if (K_LINE.available()){
    

 // первый старт байт
 if (header == 0 && Delay){TIMER_DELAY ; buf[0]=K_LINE.read();  
         if (buf[0]==0x4F){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 (buf[2]==0xD0 && buf[3]==0x05 && Heater == VEVO)                  {startWebasto_OK = buf[7]; last_W_bus = millis();}       // проверяем наличие пламени у VEVO 
  if (buf[2]==0xD0 && buf[3]==0x30 && buf[6]==0x10 && Heater == EVO)   {startWebasto_OK = (bool)buf[7]; last_W_bus = millis();} // проверяем наличие пламени у EVO 
  
  
  }   

// если контрольная сумма не совпала: 

//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==1) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = millis(); timerInitflag = 1;}
if ( timerInitflag && (millis() - timerInit>299)  && w_bus_init==1) {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=10;  sendMessage (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 (webasto && millis() - last_W_bus>30000) { startWebasto_OK=0;}



}

#ifndef debugW_bus
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();
      errors++; if (errors>4) errors = 4; 
      
      }
}

  
 if (!gsmOK)  { 
  if (SIM800.available()>0){                                   
    char currSymb = SIM800.read(); 
#ifdef debugSIM800 
    K_LINE.print (currSymb); 
#endif           
    if ('\r' == currSymb) {                                      
                                  
       if (!currStr.compareTo("OK")) {   gsmOK = true;  timerenabledWaitOK = 0; errors=0; digitalWrite (DTR, HIGH);}
       currStr = "";                                           
    }
    
    else if ('\n' != currSymb && currSymb!=0x13 && currSymb!=0x11) {currStr += String(currSymb);}}}
    
    
    if (errors>=4) Reset();
    
    }



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

#endif


void sendMessage(const size_t size, const byte *command){
 
 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){
  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]); 
      }
  
  }
  }

 

vgk_com
Offline
Зарегистрирован: 02.03.2017

MaksVV пишет:

Ниже основной скетч: 

Не подскажете ссылку на библиотеку Button.h, скачал с github , почемуто ардунка ругается. 

"no matching function for call to 'Button::Button()"

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

титановый вел button.h для кнопки от добрейшего дяди Клапы 

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

Уже переделал , не выдержала душа поэта.

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

Pashok3D пишет:
и пин на включение помпы  с таймером отключение помпы ?

добавил транзистор управления помпой с пина 13. Управляет минусом помпы. Как раз в разъеме один пин был неиспользуемый. Но такая плата теперь уже получается двусторонняя (до этого по сути на второй стороне только перемычки были, а сейчас дорожка одна появилась), поэтому вручную тяжело сделать. 

gerber8_7   плата 8_7

 

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

MaksVV пишет:

Pashok3D пишет:
и пин на включение помпы  с таймером отключение помпы ?

добавил транзистор управления помпой с пина 13. Управляет минусом помпы. Как раз в разъеме один пин был неиспользуемый. Но такая плата теперь уже получается двусторонняя (до этого по сути на второй стороне только перемычки были, а сейчас дорожка одна появилась), поэтому вручную тяжело сделать. 

gerber8_7   плата 8_7

 

 

Спасибо большое .  Едет комне еще один котел 

Webasto Thermo Top V  .  Дя експеременотов 

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

MaksVV пишет:
Мерил от БП 7В. на 12В может ещё меньше потребление будет) 

ардуино в стоке                               12,2 мА

с отпаянным LED питания                 10,9 мА

с отпаянным LED и стабом (диодом)  9,4мА

Вот замерил как положено от 12В. Считаю этот вопрос закрыт. 8,5 мА. Даже с 8 мгц ардуиной заморачиваться не стОит - дефицитная она в таком форм факторе. 8,5 мА - отличный показатель. 

 

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

последние изменения 

подготовка еепром 3.5 

#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
sizeCells,
TelNumber1_cell =20,  //20
TelNumber2_cell =40   //40
};




// возможные протоколы чтения статуса котла:

enum ProtocolSTATUS_ {
   STATUSBUS,                 // статусы котла читаются по цифровой шине
   ANALOG                     // статусы котла считываются силами ардуино - по датчикам 
};                   


// возможные протоколы запуска котла:

enum ProtocolSTART_  {
   STARTBUS,                  // запуск котла происходит по цифровой шине
   IMPULSE,                   // запуск котла происходит импульсом GND (для подпайки к кнопке пуск на таймере котла)
   POTENCIAL                  // запуск котла происходит подачей потенциала +12В (пока плюс висит - котёл работает)
};        

// возможные типы котла: 

enum Heater_  { TTC_E, VEVO, EVO, HYDRONIC};                 


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

byte ProtocolSTATUS = STATUSBUS;  // в данном случае статусы читаются по цифровой шине                 
byte ProtocolSTART  = STARTBUS;   // в данном случае запуск котла происходит по цифровой шине                 
byte Heater         = TTC_E;      // в данном случае тип котла Thermo Top C / E  (будет шина не w-bus, а просто к-лайн, у которой настройки 10400 8N1) 
byte StartByte      = 0x20;       // в данном случае байт на старт котла 0x20 (для шины w-bus)
byte worktime       = 30;         // в данном случае время цикла работы котла 30 минут 
byte deltaT         = 45;         // разница температур улицы и выхлопа, выше которой считается, что котёл успешно стартанул
///////////////////////////////////////////////


void setup() {
 
  pinMode(13, OUTPUT);
  digitalWrite(13, 0);
  EEPROM.write(TimeWebasto_cell, worktime); 
  EEPROM.write(ProtocolSTART_cell, ProtocolSTART);
  EEPROM.write(ProtocolSTATUS_cell, ProtocolSTATUS);
  EEPROM.write(Heater_cell, Heater);
  EEPROM.write(ResetNumber_cell, 0);
  EEPROM.write(StartByte_cell, StartByte);   
  EEPROM.write(delta_cell, deltaT);   
  for (int i = sizeCells ; i < EEPROM.length() ; i++) EEPROM.write(i, '0');  

  
  digitalWrite(13, HIGH);
}

void loop() {}

скетч ver 3.5

char ver[] = "Firmware 3.5";

//#define debugW_bus        // раскоментировать эту строку для отладки w-bus, при этом нужно вынуть SIM800 и подключить юсб<->уарт, т.к. отладка идёт в УАРТ, предназначенный для GSM 
//#define debugSIM800

#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
};

#include <Button.h>
Button test;

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

String currStr = "";
String TelNumber[] = {"", "000000000000", "000000000000", "000000000000"};

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

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


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


// дефайны входов выходов на соостветствующие пины ************** (плата весий 8.5-8.7)

#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

/*

#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

*/

#include <SoftwareSerial.h>

#ifndef debugW_bus
      SoftwareSerial SIM800 (GSM_RX, GSM_TX);//Rx, Tx   //UART для соединения с GSM модулем
#else 
      SoftwareSerial DEBUG (GSM_RX, GSM_TX); //Rx, Tx   //UART для соединения с отладкой (используется юсб<->УАРТ вместо SIM800)
#endif



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

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

enum TempC {VyhlopC, EngineC, UlicaC, SalonC, size_arrayTemp}; // перечисление нужных температур (в конце размер массива температур)

// ниже соответствие адресов датчиков различным температурам (изначально 0х14=20*С)
byte DS18B20 [size_arrayTemp][10] = {
{0x28, 0xFF, 0xB2, 0xB5, 0xC1, 0x17, 0x05, 0xD1, VyhlopC,  0x14}, 
{0x28, 0xFF, 0xD3, 0xE2, 0xC1, 0x17, 0x04, 0x0D, EngineC,  0x14}, 
{0x28, 0xFF, 0xF8, 0xBC, 0xC1, 0x17, 0x04, 0x48, UlicaC,   0x14},  
{0x28, 0xFF, 0x3F, 0xB7, 0xC1, 0x17, 0x05, 0xF1, SalonC,   0x14}
};
byte delta = 50;  // разница температур выхлопа и улицы, выше которой считается, что пламя в котле есть. 

// для организации W-BUS и различные таймеры********************

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

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; // таймер сброса заголовка если в момент приёма сообщения данные оборвались


// ниже строка даже не спрашивайте что это)) это так... кот по клаве прошёл
#define ConstArray(...)  [](void)->size_t{ const byte _[] = { __VA_ARGS__}; return sizeof(_)/sizeof(_[0]); }(),[](void)->const byte *{ const static byte _[] = { __VA_ARGS__}; return _; }()

// команды для котлов ЭВО
byte StartByte = 0x20;
#define HEATER_START          ConstArray (StartByte, 0x3B)
#define HEATER_PRESENCE       ConstArray (0x44, StartByte, 0x00)
#define HEATER_STOP           ConstArray (0x10)
#define HEATER_STATUS_VEVO    ConstArray (0x50, 0x05)
#define HEATER_STATUS_EVO     ConstArray (0x50, 0x30, 0x0A, 0x10)

// команды для котлов ТТС/TTE
#define START_SESSION   ConstArray (0x81)
#define REQUEST_2A10101 ConstArray (0x2A, 0x01, 0x01)
#define REQUEST_2A10102 ConstArray (0x2A, 0x01, 0x02)
#define REQUEST_2A10105 ConstArray (0x2A, 0x01, 0x05)
#define REQUEST_DTC     ConstArray (0xA1)
#define START_TTC       ConstArray (0x31, 0x22, 0xFF)
#define STOP_TTC        ConstArray (0x31, 0x22, 0x00)


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;

byte w_bus_init = 0;                      //флаг проведена или нет инициализация шины w-bus (25мс LOW, 25мс HIGH для  ЭВО
                                          //                                            либо 300ms LOW, 50ms HIGH, 25ms LOW, 3025ms HIGH для TTC 
bool flagStartPresence =  1;              //флаг что отправляем в момент периодического поддержания связи W-Bus status или start
byte StartMessageRepeat = 0;              //количество отправленных сообщений на старт котла
byte StopMessageRepeat =  0;              //количество отправленных сообщений на остановку котла

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;                    //переменная для таймера периодического измерения напряжения АКБ

//для таймера создания импульса 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

//для таймера инита шины W-BUS
uint32_t timerInit = 0; bool timerInitflag = 0;

//для таймера контроля жив или мертв обмен по W-bus 
uint32_t last_W_bus = 0; bool kotel_zhiv = 0;

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

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

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

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


// СТАРТОВЫЙ ЦИКЛ

void setup() 
{


delay (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);  // реле ресет на данный момент делаем "неактивно"

#ifndef debugW_bus
   SIM800.begin(19200);           // сериал соединение для gsm модуля
   delay(100);
   NastroykaGSM ();
#else DEBUG.begin(9600);
#endif

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);

#ifndef debugSIM800
        if (Heater == EVO || Heater == VEVO) K_LINE.begin(2400, SERIAL_8E1);
   else if (Heater == TTC_E) K_LINE.begin(10400);
#else 
K_LINE.begin(9600);
#endif


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;

#ifndef debugW_bus
   if (trevoga && !alarmSMS) AlarmSMS ();
   if (gsmOK)readSMS();
   Reset_gsm();
   delSMS();
#endif

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_;
}}}


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();}} 




#ifndef debugW_bus
   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 readSMS() //_____Цикл чтения входящих СМС-сообщений______________     
{
    if (!SIM800.available()) return;
    char currSymb = SIM800.read();
#ifdef debugSIM800 
K_LINE.print (currSymb); 
#endif
    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")) {ServiceINFO();}            // Передача сервисной информации  по СМС
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("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.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")); 
                                                                        else if (Heater == 1)SIM800.println(F("VEVO"));
                                                                        else if (Heater == 2)SIM800.println(F("EVO"));
                                                                        else if (Heater == 3)SIM800.println(F("HYDRONIC"));
                                                                        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] = "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("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<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("ZAPROS"))   { SMSzapros();}   
                                             else if (!currStr.compareTo("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("+CMT:") && !SaveNumber2) { isStringMessage = 3; for (int i =0; i<12; i++) {TelNumber[3][i]=currStr[i+7];}}
                else if    (currStr.startsWith("+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; } 
              
              } 
               
        currStr = "";
      } 
 
    else if ('\n' != currSymb && currSymb!=0x13 && currSymb!=0x11)  currStr += String(currSymb);
}



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;}
 
#endif

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 SMSzapros()

{
#ifndef debugW_bus  
  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: ")); SIM800.print (Vpit); SIM800.println(F("V"));

  SIM800.print(F("Engine:  ")); SIM800.print (Temper(EngineC));  grad ();
  SIM800.print(F("Vyhlop:  ")); SIM800.print (Temper(VyhlopC));  grad ();
  SIM800.print(F("Ulica:     ")); SIM800.print (Temper(UlicaC)); grad ();
  SIM800.print(F("Salon:    ")); SIM800.print (Temper(SalonC));  grad ();  
  
  
 
  }  
   EndSMS();    
#endif                             
}

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("StartByte:  "));
       if (ProtocolSTART==IMPULSE)   SIM800.println(F("GND Imp"));
  else if (ProtocolSTART==STARTBUS)  {SIM800.println(F("BUS"));
             if (Heater== VEVO || Heater== EVO) {SIM800.print(F("StartByte: 0x")); SIM800.println (StartByte, HEX);}}
  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"));
  
  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"));
  
  if (ProtocolSTART!=IMPULSE) {SIM800.print(F("Webasto Time: ")); SIM800.print (TimeWebasto); SIM800.println(F("min"));}
  SIM800.print(F("SIM800 Resets: ")); SIM800.println (ResetNumber); 

  if (ProtocolSTART==IMPULSE) SIM800.print(F("DeltaT:  ")); SIM800.print(delta);SIM800.println(F("*C"));
  
   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 = 1;
}

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;
   w_bus_init = 0;
   
}



void Heater_BUS (){
  
if      (Heater == EVO || Heater == VEVO){
if (webasto) {
    if (StartMessageRepeat<4 && (millis()-Prev_PeriodW_BusStartStop>800) && w_bus_init == 10){
  sendMessage (HEATER_START); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    
    if (flagStartPresence) sendMessage (HEATER_PRESENCE);  
    else {if (Heater == EVO) sendMessage (HEATER_STATUS_EVO);
          if (Heater == VEVO)sendMessage (HEATER_STATUS_VEVO);}
flagStartPresence = !flagStartPresence;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





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


if (!timerInitflag && w_bus_init==1) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = millis(); timerInitflag = 1;}
if ( timerInitflag && (millis() - timerInit>24) && w_bus_init==1) {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=10; }


if (K_LINE.available()){
    

 // первый старт байт
 if (header == 0 && Delay){TIMER_DELAY ; buf[0]=K_LINE.read();  
         if (buf[0]==0x4F){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 (buf[2]==0xD0 && buf[3]==0x05 && Heater == VEVO)                  {startWebasto_OK = buf[7]; last_W_bus = millis();}       // проверяем наличие пламени у VEVO 
  if (buf[2]==0xD0 && buf[3]==0x30 && buf[6]==0x10 && Heater == EVO)   {startWebasto_OK = (bool)buf[7]; last_W_bus = millis();} // проверяем наличие пламени у EVO
  
  
  }   

// если контрольная сумма не совпала: 

//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==1) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = millis(); timerInitflag = 1;}
if ( timerInitflag && (millis() - timerInit>299)  && w_bus_init==1) {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=10;  sendMessage (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 (webasto && millis() - last_W_bus>30000) { startWebasto_OK=0;}



}

#ifndef debugW_bus
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();
      errors++; if (errors>4) errors = 4; 
      
      }
}

  
 if (!gsmOK)  { 
  if (SIM800.available()>0){                                   
    char currSymb = SIM800.read(); 
#ifdef debugSIM800 
    K_LINE.print (currSymb); 
#endif           
    if ('\r' == currSymb) {                                      
                                  
       if (!currStr.compareTo("OK")) {   gsmOK = true;  timerenabledWaitOK = 0; errors=0; digitalWrite (DTR, HIGH);}
       currStr = "";                                           
    }
    
    else if ('\n' != currSymb && currSymb!=0x13 && currSymb!=0x11) {currStr += String(currSymb);}}}
    
    
    if (errors>=4) Reset();
    
    }



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

#endif


void sendMessage(const size_t size, const byte *command){
 
 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]); 
      }
  
  }
  }

инструкция пользователя в последней инстанции  

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

MaksVV пишет:

MaksVV пишет:
Мерил от БП 7В. на 12В может ещё меньше потребление будет) 

ардуино в стоке                               12,2 мА

с отпаянным LED питания                 10,9 мА

с отпаянным LED и стабом (диодом)  9,4мА

Вот замерил как положено от 12В. Считаю этот вопрос закрыт. 8,5 мА. Даже с 8 мгц ардуиной заморачиваться не стОит - дефицитная она в таком форм факторе. 8,5 мА - отличный показатель. 

 

Потребление даже не очем .   Если в машине оборудование тяниться до 250мА  смотря еще как магнитола подключена  и доп  .  

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

Dushman7776 пишет:

Уже переделал , не выдержала душа поэта.

фотку! Как успехи, господа собирающие девайс? 

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

Печатку переделал , собираю на плату , выяснилось что нет у меня лм393 в дип корпусе и реле такого нет , надо покупать, в моем городе нет торгашей радиодеталями , вернее есть небольшие лавки , где всякой хренью торгуют . типо разъемов и пультов, а серьезные с выбором микросхем и транзисторов всяких только в Иркутске , а у нас сейчас морозы под 45 градусов , ехать туда только за одной микросхемой и реле  обламываюсь 90 км до Иркутска. Может кто поедет на днях , закажу им. Еще вопрос , ардуину лучше впаять на плату или на разъемах делать, и если в скетче выствить получать данные от вебасто по W-Bus . то нужно ли городить датчик температуры на выхлоп? И нужно ли в скетче впсывать калибровку на измерение напряжения в борт сети и если нужно то в какую строку?

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

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

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

Приехала комне webasto top v . Теперь думаю она лучше чем старенький Тор с ? . Просто неудержался по цене 100 уе за полный комплект . Сейчас к ТТ тесту подключу гляну чё оно там . Сегодня ещё две помпы ремонтировал , додумались пеной всю плату задули . На вид как монтажная пена , только плотная . Идея появилась как вслед раз ее розрушить , кварцевой лампой . Плату сотрудника попросил вытравить. Так как сам не успиваю и.

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

Получается , если  у меня котел TTEvo  и я буду подключать по шине W-bus . то я могу кучу деталей не впаивать  , те которые нужны для упавлением старыми котлами Е и С , и датчики  температуры в салоне и на выхлопе мне не нужны , оставить только  температуру двигателя и забортную , и получается можно родной овальный пульт не подключать?

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

Dushman7776 пишет:

Получается , если  у меня котел TTEvo  и я буду подключать по шине W-bus . то я могу кучу деталей не впаивать  , те которые нужны для упавлением старыми котлами Е и С , и датчики  температуры в салоне и на выхлопе мне не нужны , оставить только  температуру двигателя и забортную , и получается можно родной овальный пульт не подключать?

У меня сейчас на машине стоит top c , подключен через w-bus и к Ардуино , на ней только микросхема к-лине и 5 в кренка . И идёт один провод в салон на кнопку включает Ардуино и все . Жду пока мне плату вытравят и буду играться с котлом ево , сейчас ремонтируют помпу .

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

Я так понял что у вас другое управление сейчас стоит . не то которое здесь обсуждаем, и нет родного таймера ? Плату можно за час с утюгом и хлорным железом изготвить, я сам вообщето фоторезист предпочитаю , но для этого девайса за час Лутом плату сварганил, правда потом выяснилось что я ее не отзеркалил, но не сложно переделать. Сейчас занят распайкой деталей на плату , реле такого как нужно не нашел, так взял маленокое реле с автосигнализации старой и на спину его на плату приклеел и проводками подпаял. Тут еще идея возникла , если w-bus шина рабоатет , то как бы сделать что бы еще и ошибки по смс можно было считывать, было бы вообще сдорово , и скидывать их тоже можно , команды же известные , только бы памяти в ардуине хватило бы. Правда из меня прогарммер хреновый , еще чужой исходник смогу разобрать  по коментариям. а сам еще не умею прогрммировать даже в ардуино . И еще вопрос по помпе, если вы ее разобрали , что там в нутри, почему она ометром звониться 10 килоом, по ходу там полевик какой стоит , который включает саму помпу , потому что если просто подать на нее 12 вольт .то она тоже работает, я это почему спрашиваю , по тому что оригинальная помпа на вебасто очень не прилично стоит , а аналогичтные подобные помпы , которые просто как элетромотор прозваниваются в несколько раз дешевле , но их вебасто не признает и выдает ошибку , я не думаю что там что то цифровое внутри , думаю что просто полевой транзистор с резистором в затворе, а по резистору вебасто опознает свой чужой.

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

Dushman7776 пишет:

Получается , если  у меня котел TTEvo  и я буду подключать по шине W-bus . то я могу кучу деталей не впаивать  , те которые нужны для упавлением старыми котлами Е и С , и датчики  температуры в салоне и на выхлопе мне не нужны , оставить только  температуру двигателя и забортную , и получается можно родной овальный пульт не подключать?

под TTE/C никаких кучи деталей и нету. Так что лишнего не напаяешь))  датчики температуры все параллельно подключаются. Можно не подключать, которые не нужны.  Температуру ДВС кстати,  по идее , можно приравнять к температуре в котле, а её через в-бус считывать. Так что только забортная нужна. 

Паша про TTC/E  который у тебя это скорее исключение, чем правило, т.к. TTC  у тебя штатный, поэтому имеет шину w-bus.  А универсальные запускаются потенциалом плюс 12В и шина у них не W-bus, а просто K-line. 

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

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

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

Dushman7776 пишет:
И еще вопрос по помпе, если вы ее разобрали , что там в нутри, почему она ометром звониться 10 килоом, по ходу там полевик какой стоит , который включает саму помпу , потому что если просто подать на нее 12 вольт .то она тоже работает, я это почему спрашиваю , по тому что оригинальная помпа на вебасто очень не прилично стоит , а аналогичтные подобные помпы , которые просто как элетромотор прозваниваются в несколько раз дешевле , но их вебасто не признает и выдает ошибку , я не думаю что там что то цифровое внутри , думаю что просто полевой транзистор с резистором в затворе, а по резистору вебасто опознает свой чужой.

там стоит целая плата, которая из постоянного тока создает вращающееся магнитное поле. По сути эл. двигатель переменного тока получается (полость антифриза герметична никаких сальников нет, там ротор просто вал с магнитом). Читайте выше по теме. я выкладывал парт номер помпы bosch. Она как раз такая, и стОит не дорого, до 3 тыс. по-моему. Так стартвольт ещё какая то есть, тоже выше читайте. 

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

Понятно про помпу , я ее не разбирал , и у меня она рабочая , это так на всякий случай. У меня на автомобиле стоит еще дополнительная помпа на печку от бош , и она гоняет антифриз когда двигатель работает и  после выключения еще немного что бы небыло теплового удара. На крайний случай ее можно задействовать, только я не мерял ее сопротивление.  А про лишние детали  для моего котла . это я про оптроны , и их обвязку. и сигнализации старлайн  у меня нет , есть сталкер 600 тый. А что вы думаете про функцию считывания ошибок , вроде не лишней будет, если не запускается котел И . то можно посмотреть причину , или это слишком сложно реализовать? При подключении к сигнализации еще бы не помешала функция автозаводки двигателя для подзарядки аккумулятора , если напряжение опасно просело , например в процессе прогрева котлом напряжение просело до опасного предела . но двигатель уже успел немного прогреться до приемлемого значения , тогда идет автозапуск двигателя и при включенном котле , с подзарядкой аккума. Но думаю что памяти уже не хватит на это .

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

Функцию чтения и сброса ошибок добавить можно. Но нужно оттестировать уже имеющийся функционал, а то если он не работает. Какой смысл добавлять что либо еще. И так в скетче уже трудно становится разбираться из за его размера. Подход то дилетантский у меня. Ниразу не программист.

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

Понятно, я только что допаял плату , собираюсь проверять ,  в какой строке в скетче прописываются адреса датчиков тепмпературы? и какой стартовый байт у котла TTEvo ? Вообще был хорошо расписать поподробней первоначальную настройку ? 

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

Что то не работает , залил подготовителный скетч , залил основной , подал питание, отпраляю смс ZAPROS  приходит уведомление что доставлено , и тишина , пробовал звонить на симку , идут длинные гудки. Светодиод на сим 800 мигает , на адруине горят оба светодиода . Что не так?

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

Ура заработало, просто сначало криво прошился скетч, эта промини такой плахой человек , кое как его уговарил прошиться :) . Может дело в моём адаптере он у меня на СР2102 , но скетч ни как не хотел заливаться в ардуину , пришлось зажимать рессет на ней а потом включать загрузку в плату , и то с 100500 раза прошло. Завтра попробую на машину установить. Еще вопрос, я еще датчики не прописывал в скетче ,  если я потом в скетч пропишу их адреса и залью в ардуину , то  телефон не надо будет заного приписывать , он вроде в епроме сохраняется? Я правильно понимаю?  И как изменить команду на запрос баланса , а то она не работает на мегафоне?

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

Да еепром не нужно больше прописывать. Там в коде старался довольно подробно все комментировать. Датчики даллас смотри вверху самом массив DS18B20 Левые 8 байт это адреса датчиков. На старт команда 20 , реже 21

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

Команда на запрос баланса. Строка 609 скетч#568. Далласы строка 108 и далее.
Две оптопары можно не запаивать и резисторы к ним. Но тот оптрон, который под ардуино, он нужен. Он считывает кнопку включения вебасто.

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

В стоке 609 нужно будет в место #100#\ поставить *100# ? Или обратный слеш тоже нужен? С далласами вроде сам разобрался но у меня их только 3 оставалось и те в виде обычных микросхем, нужно будет их в трубку упаковывать с термопастой.

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

вместо #100# ставишь *100# , оставльное оставляешь как есть. Далласы я тоже поначалу в виде микросхем брал. а сейчас иногда в колбах по 50р./шт. бывают если по одному заказывать . беру их, удобнее. 

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

переделал на *100# , в ответ пришел какой то набор цыфр , что с этим делать ?

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

а #100# не работает чтоли? Набор цифар потому что на русском приходит, а надо на английском чтобы приходило. Узнай у оператора как сделать чтобы баланс на английском приходил

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

С чего бы  сколхозить разъем , тобы был такой же как на родном овальном пульте вебасты, не охота резать или подпаивать , та так воткнул родной провод  в устройство , и ни чего резать не надо , если не заработает  по W-bus то обратно пультик воткнул и  через подпайку управлять,  и еще хочу кнопку на 3.5 джек вывести и на  далласы тоже , что бы меньше соплей было , сигу не буду подцеплять , хотя может на автозапуск двигателя попробую  в 600 сталкере есть вывод состояния для автозапуска.

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

 У меня симка мегафон а у него запрос баланса *100#  , а решетка сто решетка не работает почему то , просто ни  чего не происходит , а на звездочка сто решетка приходит ответ в виде +CUSD: 0, "куча цифр  и букв,

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

скрутками подматайся к проводам разъема вебасто и сделай свой разъем, который найти можно.  И будет два разъема торчать  - один для штатного таймера. второй для сего девайса. 

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

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

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

Долбаный Мегафон  у нас убрал услугу поговорить с девушкой из службы поддержки , посадили робота вместо девченок . надо в офис идти что бы с ними пообщаться. Как я понял нужно ставить кнопку с подсветкой светодиодной , эта подсветка какое нибудь еще занчение имеет кроме как электричестово жечь ? Ну типо статус работы вебасты , может это где и говорилось но я не понял , а так можно что бы блинки ошибок выдавала , есл что не так , типо как чек инжин .

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

лампа показывает включен котёл или нет . Кнопка то без фиксации. Хотел в будущем сделать, что если включили котёл и он НЕ запустился , то лампа будет быстро мигать. Типа незапуск. А ошибки нех по миганию считать, проще в смске их получить. 

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

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

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

да не вопрос сделаем мы ошибки. нужен только лог где идет запрос ошибок и  ответ котла  без ошибок, а также ответ с ошибками (лучше 2 ошибки для анализа). ну и удаление. 

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

в том контексте я имел ввиду не HEX про мигание,  а не х..й )))

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

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