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

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

vectra8 пишет:

Спасибо, за ответ. У меня тоже, к сожалению, получится (надеюсь) реализовать только управление +12в, поэтому в плане w-bus я тоже полезен не буду. Но когда закажу все компоненты и соберу всю схему, обязательно отпишусь о результатах.

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

vectra8
Offline
Зарегистрирован: 30.08.2018

Отлично! Жду! Готов быть подопытным.

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Было бы супер если список окажется в общем доступе)
За номер помпы спасибо, хороший вариант, придется конечно с патрубками помудрить, но альтернатив этой помпе насколько помню нет (в плане компактности и надежности)

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

Класс, спасибо.

Short Circuit
Short Circuit аватар
Offline
Зарегистрирован: 17.05.2015

DIYMan пишет:

PascalSI пишет:

 На GSM модули СИМ800 у нас цены кусаються (закажу с Али), но есть M590e, по идее он тоже подойдет, только нужно изменить АТ команды в скетче, так ли это?

Не жмотись, бери SIM800, он много лучше. M590 капризненькие, от партии к партии бывают не алё. Да и вкусных плюшек у SIM800 гораздо больше, чем у Neoway.

в мусорку эти 590..  там на некоторых операторах даже смс не ходят. прошивки у них старые, а как поменять прошивку в 590 никто не знает.

SyntAcc
Offline
Зарегистрирован: 26.01.2018

На всякий случай выложу описание протокола W-BUS который нашел когда только начал копать тему запуска подогревателя. Документы в формате docx.

Оригинальный текст https://yadi.sk/i/zUZUKTvRQmx4wg

Перевод https://yadi.sk/i/xsCOVrLj_MPiag

За точность перевода не ручаюсь. Если не понимал как правильно перевести то оставлял и кусок оригинального текста

 

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

Супер. Полезная инфа. Теперь можно попробовать сделать опрос успешности запуска котла по цифре.

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

судя по описанию, отправляя запрос F4 03 50 05 A2  , получим ответ от котла об оперативных измерениях :

"    byte0:   Температура со смещением 50 градусов C (20 C is value=70)

     byte1,2: Напряжение в милливольтах, big endian

     byte3:   Датчик пламени (set 0x01, not set 0x00)

     byte4,5: Мощность нагрева в Ваттах, big endian

     byte6,7: Сопротивление датчика пламени в миллиОмах, big endian  "

ответ, как я понимаю,  будет примерно такой  : 4F 09 46 30 F2 01 0D AC 03 7A 1B

SyntAcc
Offline
Зарегистрирован: 26.01.2018

По идее да именно так и должно выглядеть их общение, надо пробовать

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

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

почему не то? , вот в этом   видосе, как раз показаны нужные действия, прога диагностики WTT нужна расширенная, с инженерным режимом. 

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Понял свою ошибку, спасибо за помощь! Завтра попробую

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

Вот если чё расширенная WTT

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Спасибо у меня с инженерной частью, но пригодится

Сегодня снял лог общения догревателя и WTT https://yadi.sk/i/W-6_gMVxnhw--g

В логах зафиксированно начало диагностики, потоковые данные о состоянии котла, запуск котла у которого неисправна помпа (поэтому температура очень резко растет), остановка котла, окончание диагностики

Отправлял вручную команду на остановленный котел F4 03 50 05 A2

Котел ответил 4F 0B D0 05 43 2F 58 00 00 00 00 FC 59

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

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

мне тут тоже сегодня одна вебаста подвернулась. Универсальная Termo top C.   Данный котел запускается потенциалом. Поэтому по W-BUS только диагностика (хотя и пуск тоже с W-BUS можно сделать) . Котёл отвечает даже когда на штатном таймере ничего не включать,т.е в состоянии покоя. Снял лог. Всё соотвествует проделанной тут работе.

SyntAcc
Offline
Зарегистрирован: 26.01.2018

У меня штатный котел-догреватель Webasto TTV, автомобиль VW passat B6

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

465.224 Tx: 81 51 F1 81 44 --- 8(1)-количество команд (51 F1)-направление (81)-команда (44)-контрольная сумма 
465.277 Rx: 83 F1 51 C1 C2 46 8E --- 8(3)-количество команд (F1 51)-направление (C1 C2 46)-команда (8E)-контрольная сумма
MaksVV
Offline
Зарегистрирован: 06.08.2015

Да, у ТТ-С все отличается. И настройки уарт (10400 8N1) и протокол. КС просто сложение - если получается больше байта, оставляем правый байт (две правые цифры в НЕХ)

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

наваял эмулятор вашего котла, чтобы подсунуть его программе WTT. Загружаете скетч. Просто втыкаете ардуино, без всего и открываете в WTT нужный ком порт (на котором дуня висит).  WTT подключается, но спотыкается на команде 50 12. Её нет у вас в логе и я не знаю, что котёл должен отвечать на эту команду. По описанию в команду поставил байты (там счетчики), но количество байт не совпадает. 

Меняя определённые байты в сообщениях команды 50  и разных её индеках, можно смотреть что меняется в текущих данных в WTT, тем самым определив, какой байт за что отвечает. Хотя в вашем протоколе и так всё описано. Это я на будущее для ЭВО каркас сделал. 


byte buf[40]; // буфер приёма сообщений
bool head =0;

byte otv320307[] = {0x4F, 0x05, 0xB2, 0x03, 0x07, 0x00, 0xFC};
byte otv38[] ={0x4F, 0x09, 0xB8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5};

byte otv4421[] = {0x4f, 0x03, 0xc4, 0x00, 0x88};

byte otv5002[]= {0x4F, 0x08, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95};
byte otv5003[]= {0x4F, 0x04, 0xD0, 0x03, 0x00, 0x98};
byte otv5004[]= {0x4F, 0x06, 0xD0, 0x04, 0x1D, 0x3C, 0x3C, 0x80};
byte otv5005[]= {0x4F, 0x0B, 0xD0, 0x05, 0x44, 0x2F, 0x58, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x5E};
byte otv5006[]= {0x4F, 0x0B, 0xD0, 0x06, 0x03, 0xEB, 0x1A, 0x38, 0xF9, 0x02, 0x51, 0x8E, 0x7C};
byte otv5007[]= {0x4F, 0x09, 0xD0, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x95};
byte otv500A[]= {0x4F, 0x1B, 0xD0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5};
byte otv500B[]= {0x4F, 0x09, 0xD0, 0x0B, 0x00, 0x00, 0x00, 0x07, 0xF5, 0x28, 0x47};
byte otv500C[]= {0x4F, 0x09, 0xD0, 0x0C, 0x00, 0x00, 0x27, 0xE2, 0xFF, 0xFF, 0x5F};
byte otv500F[]= {0x4F, 0x08, 0xD0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98};
byte otv5011[]= {0x4F, 0x05, 0xD0, 0x11, 0x8A, 0x78, 0x79};
byte otv5012[]= {0x4F, 0x06, 0xD0, 0x12, 0x00, 0x38, 0x18, 0xAB};
byte otv5013[]= {0x4F, 0x07, 0xD0, 0x13, 0x03, 0x49, 0x00, 0x00, 0xC1};

byte otv5101[]= {0x4F, 0x08, 0xD1, 0x01, 0x09, 0x00, 0x98, 0x39, 0x4E, 0x71};
byte otv5102[]= {0x4F, 0x0F, 0xD1, 0x02, 0x18, 0x05, 0x04, 0x14, 0x06, 0x20, 0x27, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E};
byte otv5103[]= {0x4F, 0x09, 0xD1, 0x03, 0x09, 0x01, 0x60, 0x11, 0x41, 0x00, 0xAC};
byte otv5104[]= {0x4F, 0x06, 0xD1, 0x04, 0x28, 0x06, 0x07, 0xB5};
byte otv5105[]= {0x4F, 0x06, 0xD1, 0x05, 0x06, 0x07, 0x07, 0x9B};
byte otv5107[]= {0x4F, 0x17, 0xD1, 0x07, 0x31, 0x4B, 0x30, 0x38, 0x31, 0x35, 0x30, 0x37, 0x31, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70};
byte otv5109[]= {0x4F, 0x0A, 0xD1, 0x09, 0x07, 0x10, 0x18, 0x45, 0x58, 0x57, 0x41, 0x99};
byte otv510A[] = {0x4F, 0x04, 0xD1, 0x0A, 0x33, 0xA3};
byte otv510B[] = {0x4f, 0x0b ,0xd1, 0x0b, 0x50, 0x51 ,0x33, 0x35 ,0x20, 0x53 ,0x48, 0x20 ,0x82};
byte otv510C[] = {0x4f, 0x0a ,0xd1, 0x0c, 0x51, 0x7c, 0xc4 ,0xe7 ,0x3f ,0x80 ,0x00 ,0x29};
byte otv510D[]= {0x4F, 0x08, 0xD1, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x30, 0xAB};

byte otv5302[]= {0x4F, 0x11, 0xD3, 0x02, 0x2C, 0x24, 0x25, 0x1C, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E};
byte otv5701[]= {0x4F, 0x06, 0xD7, 0x01, 0xA3, 0x64, 0xFF, 0xA7};

byte otv60[]  = {0x4F, 0x04, 0x7F, 0x60, 0x11, 0x45};
byte otv5601[] ={0x4F, 0x04, 0xD6, 0x01, 0x00, 0x9C};


void setup() 
{

Serial.begin (2400, SERIAL_8E1); // сериал соединение протокол W-Bus
//Serial.begin (10400);          // для котлов TT-C,TT-E и им подобных
}

void loop() {


if (Serial.available()) {
delay (51);

while( Serial.available()) {
    byte inByte = Serial.read();

  if      (!head && inByte == 0xF4) {head = 1; buf[0] = inByte;}
  else if (head) {buf[1] = inByte; head = 0;
  for (int i = 2; i<buf[1]+2; i++) buf[i] = Serial.read(); // пишем в буфер принятое сообщение
    
  for (int i=0; i< (buf[1]+2); i++) Serial.write (buf[i]); // делаем эхо принятого сообщения для WTT т.к. проверяем без К-Line адаптера (на нём эхо и так возникнет)
  delay (5);
  
  if      (buf[2]==0x32 && buf[3]==0x03) {for (int i=0; i< sizeof(otv320307); i++) Serial.write (otv320307[i]);}
  else if (buf[2]==0x38)                 {for (int i=0; i< sizeof(otv38); i++)     Serial.write (otv38[i]);}

  else if (buf[2]==0x44&& buf[3]==0x21)  {for (int i=0; i< sizeof(otv4421); i++)   Serial.write (otv4421[i]);}
  
  else if (buf[2]==0x50 && buf[3]==0x02) {for (int i=0; i< sizeof(otv5002); i++) Serial.write (otv5002[i]);}
  else if (buf[2]==0x50 && buf[3]==0x03) {for (int i=0; i< sizeof(otv5003); i++) Serial.write (otv5003[i]);}
  else if (buf[2]==0x50 && buf[3]==0x04) {for (int i=0; i< sizeof(otv5004); i++) Serial.write (otv5004[i]);}
  else if (buf[2]==0x50 && buf[3]==0x05) {for (int i=0; i< sizeof(otv5005); i++) Serial.write (otv5005[i]);}
  else if (buf[2]==0x50 && buf[3]==0x06) {for (int i=0; i< sizeof(otv5006); i++) Serial.write (otv5006[i]);}
  else if (buf[2]==0x50 && buf[3]==0x07) {for (int i=0; i< sizeof(otv5007); i++) Serial.write (otv5007[i]);}
  else if (buf[2]==0x50 && buf[3]==0x0A) {for (int i=0; i< sizeof(otv500A); i++) Serial.write (otv500A[i]);}
  else if (buf[2]==0x50 && buf[3]==0x0B) {for (int i=0; i< sizeof(otv500B); i++) Serial.write (otv500B[i]);}
  else if (buf[2]==0x50 && buf[3]==0x0C) {for (int i=0; i< sizeof(otv500C); i++) Serial.write (otv500C[i]);}
  else if (buf[2]==0x50 && buf[3]==0x0F) {for (int i=0; i< sizeof(otv500F); i++) Serial.write (otv500F[i]);}
  else if (buf[2]==0x50 && buf[3]==0x11) {for (int i=0; i< sizeof(otv5011); i++) Serial.write (otv5011[i]);}
  else if (buf[2]==0x50 && buf[3]==0x12) {for (int i=0; i< sizeof(otv5012); i++) Serial.write (otv5012[i]);}  
  else if (buf[2]==0x50 && buf[3]==0x13) {for (int i=0; i< sizeof(otv5013); i++) Serial.write (otv5013[i]);}
  
  else if (buf[2]==0x51 && buf[3]==0x01) {for (int i=0; i< sizeof(otv5101); i++) Serial.write (otv5101[i]);}
  else if (buf[2]==0x51 && buf[3]==0x02) {for (int i=0; i< sizeof(otv5102); i++) Serial.write (otv5102[i]);}
  else if (buf[2]==0x51 && buf[3]==0x03) {for (int i=0; i< sizeof(otv5103); i++) Serial.write (otv5103[i]);}
  else if (buf[2]==0x51 && buf[3]==0x04) {for (int i=0; i< sizeof(otv5104); i++) Serial.write (otv5104[i]);}
  else if (buf[2]==0x51 && buf[3]==0x05) {for (int i=0; i< sizeof(otv5105); i++) Serial.write (otv5105[i]);}
  else if (buf[2]==0x51 && buf[3]==0x07) {for (int i=0; i< sizeof(otv5107); i++) Serial.write (otv5107[i]);}
  else if (buf[2]==0x51 && buf[3]==0x09) {for (int i=0; i< sizeof(otv5109); i++) Serial.write (otv5109[i]);}
  else if (buf[2]==0x51 && buf[3]==0x0A) {for (int i=0; i< sizeof(otv510A); i++) Serial.write (otv510A[i]);}
  else if (buf[2]==0x51 && buf[3]==0x0B) {for (int i=0; i< sizeof(otv510B); i++) Serial.write (otv510B[i]);}
  else if (buf[2]==0x51 && buf[3]==0x0C) {for (int i=0; i< sizeof(otv510C); i++) Serial.write (otv510C[i]);}
  else if (buf[2]==0x51 && buf[3]==0x0D) {for (int i=0; i< sizeof(otv510D); i++) Serial.write (otv510D[i]);}

  else if (buf[2]==0x53 && buf[3]==0x02) {for (int i=0; i< sizeof(otv5302); i++) Serial.write (otv5302[i]);}
  else if (buf[2]==0x56 && buf[3]==0x01) {for (int i=0; i< sizeof(otv5601); i++) Serial.write (otv5601[i]);}
  else if (buf[2]==0x57 && buf[3]==0x01) {for (int i=0; i< sizeof(otv5701); i++) Serial.write (otv5701[i]);}
  
  else if (buf[2]==0x60) {for (int i=0; i< sizeof(otv60); i++) Serial.write (otv60[i]);}
  
                 }
  }
  }
  }
  

 

SyntAcc
Offline
Зарегистрирован: 26.01.2018

 

Залил скетч, только закоментил все что связано с LCD, у меня нет нужной библиотеки (и экрана). На 50 12 спотыкается так как это что то связанное или с количеством запусков или со временем запуска. А в моем логе этого нет потому что котел не запустился полноценно из-за неработающей помпы. Надо будет вручную послать эту команду котлу, в понедельник попробую.

12: Start counters

  byte0,1 PH start counter - Parking Heater - предпусковой нагреватель

  byte2,3 SH start counter - Supplemental Heater - дополнительный нагреватель (подогреватель как у меня)

  byte4,5 TRS counter (Territories and Regional Support ? Thermal Reed Switch ?)

P.S.: Кстати, можно и на ты)

 

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

поправил скетч , уже убрал lcd.  Эти счетчики я поставил от балды, но WTT не нравится количество байт в сообщении. Ок узнаешь чем ответит котел, сделаем эмуль до конца, потом можно много интересного узнать, что за что отвечает.  

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Есть предположение почему WTT спотыкается на команде 50 12. Индекс 12 в команде 50 надо отправлять в 16-ричной системе, в описании протокола все индексы команды 50 записаны в 10-ричной системе (непонятно только почему так)

То есть команда должна выглядеть не так F4 03 50 12 B5, а вот так F4 03 50 0C AB

В логе есть эта команда:

576.903 Tx: F4 03 50 0C AB 
576.994 Rx: 4F D0 0C 00 00 27 E2 FF FF 5F
То есть
00 00 - 0 запусков как parking heater
27 E2 - 10210 запусков как supplemental heater (я так предпологаю)
 
Далее в логе (скорее всего после попытки пуска):
677.295 Tx: F4 03 50 0C AB
677.387 Rx: 4F D0 0C 00 00 27 E3 FF FF 5E
То есть:
27 E3 - 10211 запусков как supplemental heater
 
Завтра попробую команду вручную, отпишусь

 

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

нет, я смотрел в логе программы WTT  - там именно F4 03 50 12 B5 посылается на дуню, 50 0С нормально проходит

Хотя ты прав, просто наоборот. 50 12 в  DEC индекс будет 18. Точно, там ведь в DEC расписаны индексы. 18 - время работы вентиляции. Щас подставлю, проверю. 

Update: подставил по описанию 18 , всё, заработало. Эмулятор работает! Поправил скетч #268

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

второй вариант эмулятора. Выполнил отправку через циклы фор. Теперь при добавлении сообщений только массив править . Подсчет КС скетч выполняет.

byte buf[40]; // буфер приёма сообщений
bool head =0;
#define sizeMes 29
byte answ_message[][sizeMes] = {
//      Это команда и индекс  (только из команды нужно мысленно)) убрать старший бит, т.е. если было 0xD0, то это команда 0x50)
//            \/    \/
//            \/    \/
{0x4F, 0x02, 0x90, 0xDD, 0xD4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x03, 0xA0, 0x3B, 0xD4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x03, 0xA1, 0x3B, 0xD4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x03, 0xA2, 0x3B, 0xD4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x03, 0xA1, 0x00, 0xD4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x03, 0xA3, 0x3B, 0xD4, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x05, 0xB2, 0x03, 0x07, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xB8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x03, 0xC4, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x08, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x04, 0xD0, 0x03, 0x00, 0x98, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD0, 0x04, 0x1D, 0x3C, 0x3C, 0x80, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0B, 0xD0, 0x05, 0x44, 0x2F, 0x58, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x5E, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0B, 0xD0, 0x06, 0x03, 0xEB, 0x1A, 0x38, 0xF9, 0x02, 0x51, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xD0, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x95, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x1B, 0xD0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},///
{0x4F, 0x09, 0xD0, 0x0B, 0x00, 0x00, 0x00, 0x07, 0xF5, 0x28, 0x47, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xD0, 0x0C, 0x00, 0x00, 0x27, 0xE2, 0xFF, 0xFF, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x08, 0xD0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x05, 0xD0, 0x11, 0x8A, 0x78, 0x79, 0x00, 0x00, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD0, 0x12, 0x00, 0x38, 0x18, 0xAB, 0x00, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x07, 0xD0, 0x13, 0x03, 0x49, 0x00, 0x00, 0xC1, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x08, 0xD1, 0x01, 0x09, 0x00, 0x98, 0x39, 0x4E, 0x71, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0F, 0xD1, 0x02, 0x18, 0x05, 0x04, 0x14, 0x06, 0x20, 0x27, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xD1, 0x03, 0x09, 0x01, 0x60, 0x11, 0x41, 0x00, 0xAC, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD1, 0x04, 0x28, 0x06, 0x07, 0xB5, 0x41, 0x00, 0xAC, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD1, 0x05, 0x06, 0x07, 0x07, 0x9B, 0x41, 0x00, 0xAC, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x17, 0xD1, 0x07, 0x31, 0x4B, 0x30, 0x38, 0x31, 0x35, 0x30, 0x37, 0x31, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0A, 0xD1, 0x09, 0x07, 0x10, 0x18, 0x45, 0x58, 0x57, 0x41, 0x99, 0x31, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x04, 0xD1, 0x0A, 0x33, 0xA3, 0x18, 0x45, 0x58, 0x57, 0x41, 0x99, 0x31, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0b ,0xd1, 0x0b, 0x50, 0x51 ,0x33, 0x35 ,0x20, 0x53 ,0x48, 0x20, 0x82, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0a ,0xd1, 0x0c, 0x51, 0x7c, 0xc4 ,0xe7 ,0x3f ,0x80 ,0x00 ,0x29, 0x82, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x08, 0xD1, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x30, 0xAB ,0x00 ,0x29, 0x82, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x11, 0xD3, 0x02, 0x2C, 0x24, 0x25, 0x1C, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x04, 0xD6, 0x01, 0x00, 0x9C, 0x25, 0x1C, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD7, 0x01, 0xA3, 0x64, 0xFF, 0xA7, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x04, 0x7F, 0x60, 0x11, 0x45, 0xFF, 0xA7, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5}

};
void setup() 
{

Serial.begin (2400, SERIAL_8E1); // сериал соединение протокол W-Bus
//Serial.begin (10400);          // для котлов TT-C,TT-E и им подобных
}

void loop() {


if (Serial.available()) {
delay (51);

while( Serial.available()) {
    byte inByte = Serial.read();

  if      (!head && inByte == 0xF4) {head = 1; buf[0] = inByte;}
  else if (head) {buf[1] = inByte; head = 0;
if ((buf[1]+2)<40){  for (int i = 2; i<buf[1]+2; i++) buf[i] = Serial.read(); }// пишем в буфер принятое сообщение, если оно в него влазит. 
    
 // for (int i=0; i< (buf[1]+2); i++) Serial.write (buf[i]); // делаем эхо принятого сообщения для WTT т.к. проверяем без К-Line адаптера (на нём эхо и так возникнет)
  delay (3);
 
 
   for (byte j = 0; j < sizeof(answ_message)/sizeMes; j++)      {// перебираем весь список сообщений в нашем массиве и выбираем нужное для данного запроса
    if (
        ((answ_message[j][2]&~0x80)==buf[2] && answ_message[j][3] == buf[3] && buf[1]==3 && buf[2]!=0x60) || 
        ((answ_message[j][2]&~0x80)==buf[2] && buf[1]==2 && buf[2]!=0x60) || 
        (buf[2]== answ_message[j][3]) ||
        (buf[1]==4 && (answ_message[j][2]&~0x80)==buf[2])
        ) 
       {
        byte crc; 
        for (int i=0; i<answ_message[j][1]+2 ; i++) {  if (i!=(answ_message[j][1]+1)) crc^=answ_message[j][i];
                                                      else                          {answ_message[j][i]= crc;}  
                                                      Serial.write (answ_message[j][i]);
                                                    }
       }
    
                                                          }


  
  

                 }
  }
  }
  }
  

 

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Отлично, теперь можно с WTT общаться без котла

Отправил вручную на котел команды 50 12 и 50 18

Tx: F4 03 50 12 B5
Rx: 4F 06 D0 12 00 00 8B
 
Tx: F4 03 50 18 BF
Rx: 4F 04 7F 50 11 75
 
Кстати про вентиляцию, полезная функция на лето, проветрить салон если авто стоит на солнце

 

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Кстати, на этих выходных будет доступ к TTC или TTE, не знаю точно модель, могу снять лог если есть необходимость для коллекции

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

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

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

кто хочет поисследовать протокол TT-C TT-E вот тоже сделал рабочий эмулятор


byte buf[40]; // буфер приёма сообщений
byte head =0;
#define sizeMes 19
byte answ_message[][sizeMes] = {

{0x83, 0xF1, 0x51, 0xC1, 0xC2, 0x46, 0x8E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, // 81 51 F1 81 44
{0x8F, 0xF1, 0x51, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1B, 0x00, 0x12, 0x07, 0x04, 0x26, 0x99, 0x22, 0x66}, // 82 51 F1 3C 00 00

{0x87, 0xF1, 0x51, 0x6A, 0x01, 0xAF, 0x00, 0xB9, 0x00, 0x50, 0xFC, 0x00, 0x12, 0x07, 0x04, 0x26, 0x99, 0x22, 0x66}, // 83 51 F1 2A 01 01 F1
{0x88, 0xF1, 0x51, 0x6A, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x38, 0x12, 0x07, 0x04, 0x26, 0x99, 0x22, 0x66}, // 83 51 F1 2A 01 02 F2 
{0x84, 0xF1, 0x51, 0x6A, 0x05, 0x70, 0xC3, 0x68, 0x00, 0x00, 0x02, 0x38, 0x12, 0x07, 0x04, 0x26, 0x99, 0x22, 0x66}, // 83 51 F1 2A 01 05 F5
{0x84, 0xF1, 0x51, 0xE1, 0xFF, 0xFF, 0x00, 0xA5, 0x00, 0x50, 0xFC, 0x00, 0x12, 0x07, 0x04, 0x26, 0x99, 0x22, 0x66}, // 81 51 F1 A1 64

};

byte answ_unknown_command[] {0x83, 0xF1, 0x51, 0x7F, 0x31, 0x23, 0x98};  // 82 51 F1 31 03 F8 

#define sizetabl 37
byte tabl[][sizetabl] = {
{0x17, 0x20, 0x22, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF, 0xE0, 0xE1, 0xE2, 0xE8, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE},
{0x00, 0x3F, 0x8F, 0x5F, 0x88, 0x00, 0xAB, 0x80, 0x10 ,0x01, 0x17, 0x01, 0x08, 0x01, 0x20, 0x01, 0xCE, 0x00, 0x00, 0x00, 0x00, 0x2E, 0x41, 0x17, 0x98, 0x01, 0x15, 0x00, 0x60, 0xA4, 0x07, 0x24, 0x26, 0x41, 0x06, 0x98, 0x45}
};

void setup() 
{

//Serial.begin (2400, SERIAL_8E1); // сериал соединение протокол W-Bus
Serial.begin (10400);          // для котлов TT-C,TT-E и им подобных

}

void loop() {


if (Serial.available()) {
delay (51);

while( Serial.available()) {
    byte inByte = Serial.read();
byte header = (inByte&0xF0)>>4;
       if      (head==0 && header == 8) {head = 1; buf[0] = inByte;}
  else if      (head==0 && inByte == 3) {head = 2; buf[0] = inByte;}
  if (head==1) { head = 0;
  
  for (int i = 1; i<((buf[0]&0xF)+4); i++) buf[i] = Serial.read(); // пишем в буфер принятое сообщение
    
  for (int i=0; i< ((buf[0]&0xF)+4); i++) Serial.write (buf[i]); // делаем эхо принятого сообщения для WTT т.к. проверяем без К-Line адаптера (на нём эхо и так возникнет)
  delay (3);
 
 bool message_found = 0;
 byte crc;
   for (byte j = 0; j < sizeof(answ_message)/sizeMes; j++)      {
    if (
        ((answ_message[j][3]&~0x40)==buf[3] && answ_message[j][4] == buf[5] && (buf[0]&0xF)==3) || 
        ((answ_message[j][3]&~0x40)==buf[3] && (buf[0]&0xF)==1) || 
        ((answ_message[j][3]&~0x40)==buf[3] && answ_message[j][4] == buf[4] && (buf[0]&0xF)==2)
        ) 
    
       {
         
        for (byte i=0; i<(answ_message[j][0]&0xF)+4 ; i++) {  if (i!=((answ_message[j][0]&0xF)+3)) crc+=answ_message[j][i];
                                                      else                          {answ_message[j][i]= crc;}  
                                                      Serial.write (answ_message[j][i]);
                                                    }
       message_found = 1;                                             
       }
     
                                                          }
    if (!message_found){ 
   
        answ_unknown_command[4] = buf[3]; 
        for (byte i = 0; i < ((answ_unknown_command[0]&0xF)+4);  i++) {  if (i!=((answ_unknown_command[0]&0xF)+3)) crc+=answ_unknown_command[i];  // если неизвестное сообщение 
                                                                   else  {answ_unknown_command[i]= crc;}  Serial.write (answ_unknown_command[i]);
                                                    }
                                                    
                       }


  
  

                 }
else if (head==2) { head = 0;
     for (int i = 1; i<3; i++) buf[i] = Serial.read(); // пишем в буфер принятое сообщение (инит по три байта от диагностики)
     for (int i=0; i< 3; i++) Serial.write (buf[i]); // делаем эхо принятого сообщения для WTT т.к. проверяем без К-Line адаптера (на нём эхо и так возникнет)
     for (byte j = 0; j < sizetabl; j++)   {if  (buf[1] == tabl[0][j]) Serial.write (tabl[1][j]);}
                  
                  }
  }
  }
  }
  

 

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Правильно ли я понимаю что для теста запуска TTV по шине достаточно к ардуино подключить LN393 и две тактовые кнопки для подачи земли на 5 и 4 пин?

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

Какой скетч используешь? тактовая одна нужна - на пин А2 (нормально разомкнутая, при нажатии замыкает пин А2 на GND). Кроме LM 393 нужны 8 резисторов, которые прилегают к ней. 4 по 10К, 2 по 2К, 2 по 3,9К. 

предварительно загрузить этот скетч для подготовки еепром

#include <EEPROM.h>

void setup() {
 
  pinMode(13, OUTPUT);
  digitalWrite(13, 0);
  
  EEPROM.write(1, 30);
  EEPROM.write(2, 2);
  EEPROM.write(0, 0);
  EEPROM.write(3, 0x23);
  for (int i = 5 ; i < EEPROM.length() ; i++) EEPROM.write(i, '0');  

  
  digitalWrite(13, HIGH);
}

void loop() {}

пробовать на этом скетче

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

Button test;

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

String TelNumber1 = "000000000000";

String TelNumber2 = "000000000000";

String BufferNumber = "000000000000";

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

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


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

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

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

#define Ohrana  6      // Сюда состояние охраны сигналки
#define Trevoga  7      // Сюда состояние тревоги
#define StartEng 18   // (A4) это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
#define IGN 8       // Сюда состояние зажигания
#define Eng 14       // (А0) Сюда состояние работы ДВС
#define ResetGSM 12       // пин ресета GSM подключен к реле, разрывающее питание модуля. 
#define StartButton 0       // программный номер тактовой кнопки вкл/выкл котла 
#define StatusWebastoLED 15  //(А1) пин LED  индикация включенности котла
#define DTR 17  // пин (А3), управляющий энергосберегающим режимом GSM модуля





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

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

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

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

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

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

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


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


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



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

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

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


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

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





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

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

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

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


    delay(2000);

  NastroykaGSM ();

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

}


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

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

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

if (Protocol==2) W_Bus();

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

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

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

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


}

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

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






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




                    


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

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

  report = true; EndReportMillis = millis();
}

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

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




void WebastoOprosImpulse (){

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


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

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





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

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

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

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

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

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

  prevdelSMS = millis();}
}


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



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

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


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


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


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

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

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

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

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

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

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

                                                                        

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



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

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


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

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

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

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

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

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

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


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


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

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

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





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

}



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

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

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

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

 

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Думал использовать версию v3.0, но опираться буду на твои рекомендации
Завтра заеду за рассыпухой и макетной платой, соберу, если успею то вечером протестирую, если не успею то в четверг утром попробую. В любом случае подключу WTT для прослушивания шины, сниму лог.
Котел при запущенном моторе в перегрев не уходит, так что не работающая помпа отчасти не помеха.
Вопрос по питанию, 5в думал через LM317 брать, в обвязке только резисторы, требуются ли конденсаторы для фильтрации помех из бортовой сети или ардуино к этому спокойно относится?

Сейчас попробовал в ардуино залить скетч для эмуляции TTC, TTE, почему то WTT не хочет соединяться с ардуино.
Из побочного, WTT для связи с котлом EVO PSA отправляет команду 81 01 F1 81 F4

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

по эмулю - может ты не ту TT-C выбрал. Ты, похоже, штатные ТТ-С выбираешь, а надо универсальную:

 

кондёры в стабе 5В конечно поставь - стоят копейки. Я обычно беру стаб 7805 и два электролита (по 5в линии и по 12В линии), там не нужно резисторов, сразу 5В ровно выдает и всё, для проверки самое то. 

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

вот такой ещё скетч попробуй, добавил чтобы  встроенный светодиод 13 показывал наличие пламени в котле (успешный старт котла). Проверил на эмуляторе - работает. но соединял без к-лайн, tx rx на прямую двух ардуин. Не забывай перед проверкой еепром подготовить, залив скетч выше. 

Update: проверил через К-лайн - тоже работает, только лучше убрать в скетче эмулятора Эхо (К-лайн сама эхо дает)

#define TX 1    
#include <EEPROM.h>
#include <Button.h>

Button test;

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

String TelNumber1 = "000000000000";

String TelNumber2 = "000000000000";

String BufferNumber = "000000000000";

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

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


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

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

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

#define Ohrana  6      // Сюда состояние охраны сигналки
#define Trevoga  7      // Сюда состояние тревоги
#define StartEng 18   // (A4) это импульсный минусовой выход вкл/выкл ДВС. подключать на вход событий сиги.
#define IGN 8       // Сюда состояние зажигания
#define Eng 14       // (А0) Сюда состояние работы ДВС
#define ResetGSM 12       // пин ресета GSM подключен к реле, разрывающее питание модуля. 
#define StartButton 0       // программный номер тактовой кнопки вкл/выкл котла 
#define StatusWebastoLED 15  //(А1) пин LED  индикация включенности котла
#define DTR 17  // пин (А3), управляющий энергосберегающим режимом GSM модуля





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

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

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

// для организации W-BUS и различные таймеры********************
byte buf[40]; // буфер приёма сообщений
bool head =0;
byte Zapusk[] =       {0xF4, 0x03, 0x23, 0x3B, 0xEF} ;
byte Presence[] =     {0xF4, 0x04, 0x44, 0x23, 0x00, 0x97};
byte Stop[] =         {0xF4, 0x02, 0x10, 0xE6} ;
byte StateMessage[] = {0xF4, 0x03, 0x50, 0x05, 0xA2};

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

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

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


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


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

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

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

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

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

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


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

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





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

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

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

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


    delay(2000);

  NastroykaGSM ();

TimeWebasto = EEPROM.read(1)*60000UL;
Protocol = EEPROM.read(2);
ResetNumber = EEPROM.read(0);
Zapusk[2] = 0x23;    //EEPROM.read(3);
{byte crc = 0; for (byte i=0; i < sizeof(Zapusk); i++) {if (i!=sizeof(Zapusk)-1)crc^=Zapusk[i]; else Zapusk[i] = crc;}}
Presence [3]=Zapusk[2];
{byte crc = 0; for (byte i=0; i < sizeof(Presence); i++) {if (i!=sizeof(Presence)-1)crc^=Presence[i]; else Presence[i] = crc;}}
for (int i=0; i<12; i++) TelNumber1[i] = EEPROM.read (i+10);
for (int i=0; i<12; i++) TelNumber2[i] = EEPROM.read (i+30);

}


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

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

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

if (Protocol==2) W_Bus();

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

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

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

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


}

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

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






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




                    


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

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

  report = true; EndReportMillis = millis();
  w_bus_init = 1;
}

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

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




void WebastoOprosImpulse (){

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


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

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





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

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

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

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

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

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

  prevdelSMS = millis();}
}


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



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

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


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


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


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

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

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

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

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

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

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

                                                                        

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



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

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


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

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

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

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

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

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

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


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


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

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

 Serial.write (Zapusk, sizeof(Zapusk)); 
  StartMessageRepeat++; 
  Prev_PeriodW_BusStartStop = millis();
  
    }
  if (StartMessageRepeat>=4){ if (millis()-Prev_PeriodW_BusMessage>5000)  {
    //делаем периодическое поддержание связи W-BUS
    // наверное сканает отправка сообщения о состоянии котла
    // т.е. ,например, отправляем периодически запрос на показания датчиков
    // состоянием работы котла будет наличие или отсутствие пламени
if (flagStartPresence) Serial.write (Presence,sizeof(Presence)); 
else Serial.write (StateMessage, sizeof (StateMessage));
flagStartPresence = !flagStartPresence;
StopMessageRepeat = 0;
    
    Prev_PeriodW_BusMessage = millis();
    }}}





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

if (w_bus_init==1 && !timerInitflag) {Serial.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) {Serial.begin (2400,SERIAL_8E1 );timerInitflag = 0; w_bus_init=3; }
if (webasto && millis() - last_W_bus>30000) { startWebasto_OK=0;}
if (Serial.available()) {
delay (61);

while( Serial.available()) {
   byte inByte = Serial.read();

  if      (!head && inByte == 0x4F) {head = 1; buf[0] = inByte;}
  else if (head) {buf[1] = inByte; head = 0;
  for (int i = 2; i<buf[1]+2; i++) { buf[i] = Serial.read();} // пишем в буфер принятое сообщение
    
 // for (int i=0; i< (buf[1]+2); i++) Serial.write (buf[i]); // делаем эхо принятого сообщения для WTT т.к. проверяем без К-Line адаптера (на нём эхо и так возникнет)

 if (buf[2]==0xD0 && buf[3]==05) {startWebasto_OK = buf[7]; last_W_bus = millis();}
 
  

                 }
                           }
                         }



}



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

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

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

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


 

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

Кстати совсем забыли про инициализацию шины. Вполне вероятно что если просто начать посылать на W-BUS команды запуска, то ничего не произойдет, так как котёл может "дрыхнуть". в том описании указано что для инита нужно дать импульс low и high по 25 мс. Также там говорится что может нужно по 50 мс. Я сделал по 25 мс, поправил это в скетче #282. Пеперь перед отправкой первой команды на запуск делается инит, ну типа будим котел, нефиг спать. Проверил осциллографом, выгладит так, надеюсь так и должно быть:

SyntAcc
Offline
Зарегистрирован: 26.01.2018

По эмулятору: выбирал именно этот пункт и пробовал автоматический поиск, не хочет работать, ХЗ, может что упустил

Вчера вечером пробовал залить скетч на упавление котлом, подготовил EEPROM первым скетчем, при заливке основного скетча компиляция спотыкается на строке 004 Button test;, может у меня не та библиотека Button.h в ардуино подгружена? Можешь свою выложить?

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

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

MaksVV пишет:

Проверил осциллографом, выгладит так, надеюсь так и должно быть:

 

блин, а че надеяться то? я же могу проверить как должно быть. У меня же есть программа WTT и осцил. Уж WTT то точно должна давать инит, такой какой нужно. Проверил и ,точно, угадал я - импульсы по 25 мс, в точности как я и сделал в своём скетче. Так что должно работать. Вот как WTT шлет  инит, найдите 5 отличий называется : 

PS кстати скетч проверочный выполнен для NANO.  для PRO MINI нужно пару цифер поменять. (tx и rx на разных пинах у ниx)

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

SyntAcc пишет:
Можешь свою выложить?

https://yadi.sk/d/O3Mjgv2J3RGXcV

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Будешь смеяться я понял почему эмуль вчера не хотел работать) прошил ардуину и не переключая на к-лайн от usb ttl пробовал подключиться к WTT, надо больше отдыхать видимо))

Специфический осцил, это же мотор тестер?

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

да ,фуфлыжный самый, disco 2, но так как нахаляву то...

Также если по к-лайну эмуль цеплять, нужно коментировать строку эхо . Ну че как сборка?

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Да даже на халяву))

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

Адаптер на LN393 собрал, скетч залил, править ничего не стал, посмотрел что вроде у Pro Mini и Nano по rx tx одинаковые пины. Завтра с утра попробую запустить котел и смотреть что происходит в шине через WTT.
С эмулятором эксперименты на потом оставил, что то мне подсказывает что я туплю в каком то месте))

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

SyntAcc пишет:
посмотрел что вроде у Pro Mini и Nano по rx tx одинаковые пины.

у нано Tx - 1  Rx -0, у про мини наоборот Tx - 0 Rx - 1. Вот такая петрушка.   Исправил скетч #282. Теперь в самом верху скетча можно выбрать нано или промини. 

UPDATE:    Sorry друзья! сказанное мной неправда! Действительно "у Pro Mini и Nano по rx tx одинаковые пины". Меня сбили с толку надписи на китайских промини TXO  RXI   буквы O и I воспринял как 0 и 1, что неверно. Посмотрел пинмаппинг на обе платы , у обеих RX это 0 пин,  TX это 1 пин . Обратно исправил скетч  #282

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Испытал, что-то не работает (или опять же я туплю)

Адаптер на LN393 работает (WTT нормально подключается), но котел почему то команды ардуино игнорит, лог позже выложу

Причем что любопытно, после попытки запуска через ардуино, WTT цепляется к котлу не с первой попытки

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

проверить твой новоиспеченный адаптер можно залив эмулятор, и подцепив через к-лайн к WTT.  В WTT естетвенно выбрать порт НЕ ардуиновского к-лайн.Строку эха закоментировать

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Пока что не было времени на попытки запуска, но есть хорошая новость, сегодня вечером сниму лог общения WTT и TT Evo

SyntAcc
Offline
Зарегистрирован: 26.01.2018

Webasto Termo Top Evo - запуск и прогрев до 50 градусов https://yadi.sk/i/QV84qEOnuXAJTg

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

Пасиб, будем разбираться. Сообщение старт, да это оно. После всяких инитов остаются две команды 50 30 и 56 01

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

Опаздываем немного от всего мира. С прошлого сезона пошли новые модели. Эво старт и эво комфорт. Судя по жалобам установщиков сигнализаций ( не работет у них включение по w-bus) протокол опять отличается. 

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

Выражаю благодарность коллеге SyntAcc! Снятый им лог TT Evo в значительной степени продвинет проект ,  в плане  шины W-Bus.

У EVO версия W-BUS 4.0 (у TTV было 3.3).

Первый раз реверс инжениринг прошёл так легко)) В программе WTT все PIDы прописаны, что за что отвечает. Осталось только эмулятором это проверить:

После всяких инитов от программы диагностики раз в 2 секунды на котёл прилетает две команды 50 30 (запрос параметров) и 56 01 (запрос ошибок). 

Интересно, что, добавляя в WTT вон те  ^ галочки,  в команде 50 30 также добавляется к запросу этот PID, на котором галку поставили. Собственно поэтому команда 50 30 такая длинная, и ответ от котла с этими параметрами ещё длиннее. Но зная это, мы можем запрашивать у котла только то, что нам нужно. 

 Рабочий эмулятор  для TT EVO. 


//byte buf[70]; // буфер приёма сообщений
bool head =0;
#define sizeMes 20
byte answ_message[][sizeMes] = {

////////////////////////////// ниже сообщения от котла на диагностику W-Bus 4.0. Webasto Termo Top Evo

{0x4F, 0x03, 0xA0, 0x3B, 0xD7, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x03, 0x30, 0x69, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},

{0x4F, 0x02, 0x90, 0xDD, 0x00, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x03, 0x30, 0x69, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},


{0x4F, 0x0B, 0xB8, 0x0B, 0x00, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x03, 0x30, 0x69, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},

{0x4F, 0x03, 0xC4, 0x00, 0x88, 0x00, 0x02, 0xAF, 0x00, 0x00, 0x03, 0x30, 0x69, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},


{0x4F, 0x0A, 0xD1, 0x30, 0x03, 0x05, 0x17, 0x11, 0x04, 0x08, 0x01, 0xFF, 0x69, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},

//{0x4F, 0x12, 0xD1, 0x31, 0x01, 0x0F, 0x17, 0x06, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},

{0x4F, 0x05, 0xD1, 0x31, 0x03, 0x04, 0x17, 0x06, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},


{0x4F, 0x0A, 0xD1, 0x09, 0x12, 0x18, 0x30, 0x08, 0x89, 0x43, 0x42, 0x27, 0x08, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},
{0x4F, 0x04, 0xD1, 0x0A, 0x40, 0xD0, 0x17, 0x06, 0x03, 0x04, 0x05, 0x07, 0x08, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},
{0x4F, 0x0A, 0xD1, 0x0C, 0x79, 0x7C, 0xE4, 0x23, 0x04, 0x00, 0x00, 0x5E, 0x08, 0x0B, 0x0C, 0x0D, 0x0E, 0x10, 0x12, 0xA9},

{0x4F, 0x11, 0xD3, 0x02, 0x2A, 0xF8, 0x00, 0x00, 0xFF, 0xFE, 0x14, 0x3E, 0x80, 0x00, 0x00, 0xFF, 0xFE, 0x05, 0xF2, 0x00}, 
{0x4F, 0x0A, 0xD6, 0x01, 0x02, 0x99, 0x01, 0x01, 0xA9, 0x01, 0x01, 0xA0, 0x80, 0x00, 0x00, 0xFF, 0xFE, 0x05, 0xF2, 0x00}, 
{0x4F, 0x03, 0xD6, 0x03, 0x02, 0x99, 0x01, 0x01, 0xA9, 0x01, 0x01, 0xA0, 0x80, 0x00, 0x00, 0xFF, 0xFE, 0x05, 0xF2, 0x00}, 
{0x4F, 0x06, 0xD7, 0x01, 0x8F, 0x01, 0xFF, 0xEE, 0xFF, 0xFE, 0x14, 0x3E, 0x80, 0x00, 0x00, 0xFF, 0xFE, 0x05, 0xF2, 0x00} 
};
/*
////////////////////////////// ниже сообщения от котла на диагностику W-Bus 3.3. Webasto Termo Top V

//    Это команда и индекс  (только из команды нужно убрать старший бит, т.е. если было 0xD0, то это команда 0x50)
//            \/    \/
//            \/    \/
{0x4F, 0x05, 0xB2, 0x03, 0x07, 0x00, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xB8, 0x0B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x03, 0xC4, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x08, 0xD0, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x04, 0xD0, 0x03, 0x00, 0x98, 0x00, 0x00, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD0, 0x04, 0x1D, 0x3C, 0x3C, 0x80, 0x00, 0x95, 0xF5, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0B, 0xD0, 0x05, 0x44, 0x2F, 0x58, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x5E, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0B, 0xD0, 0x06, 0x03, 0xEB, 0x1A, 0x38, 0xF9, 0x02, 0x51, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xD0, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00 ,0x00, 0x95, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x1B, 0xD0, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},///
{0x4F, 0x09, 0xD0, 0x0B, 0x00, 0x00, 0x00, 0x07, 0xF5, 0x28, 0x47, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xD0, 0x0C, 0x00, 0x00, 0x27, 0xE2, 0xFF, 0xFF, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x08, 0xD0, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x05, 0xD0, 0x11, 0x8A, 0x78, 0x79, 0x00, 0x00, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD0, 0x12, 0x00, 0x38, 0x18, 0xAB, 0x00, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x07, 0xD0, 0x13, 0x03, 0x49, 0x00, 0x00, 0xC1, 0x98, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x08, 0xD1, 0x01, 0x09, 0x00, 0x98, 0x39, 0x4E, 0x71, 0x5F, 0x8E, 0x7C, 0x00, 0x00, 0x00, 0x01, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0F, 0xD1, 0x02, 0x18, 0x05, 0x04, 0x14, 0x06, 0x20, 0x27, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x09, 0xD1, 0x03, 0x09, 0x01, 0x60, 0x11, 0x41, 0x00, 0xAC, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD1, 0x04, 0x28, 0x06, 0x07, 0xB5, 0x41, 0x00, 0xAC, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD1, 0x05, 0x06, 0x07, 0x07, 0x9B, 0x41, 0x00, 0xAC, 0x04, 0x14, 0x06, 0x20, 0x27, 0x8E, 0xFC, 0x2C, 0x00, 0x00, 0x00, 0x01, 0x9E, 0x25, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x17, 0xD1, 0x07, 0x31, 0x4B, 0x30, 0x38, 0x31, 0x35, 0x30, 0x37, 0x31, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0A, 0xD1, 0x09, 0x07, 0x10, 0x18, 0x45, 0x58, 0x57, 0x41, 0x99, 0x31, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x04, 0xD1, 0x0A, 0x33, 0xA3, 0x18, 0x45, 0x58, 0x57, 0x41, 0x99, 0x31, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0b ,0xd1, 0x0b, 0x50, 0x51 ,0x33, 0x35 ,0x20, 0x53 ,0x48, 0x20, 0x82, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x0a ,0xd1, 0x0c, 0x51, 0x7c, 0xc4 ,0xe7 ,0x3f ,0x80 ,0x00 ,0x29, 0x82, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x08, 0xD1, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x30, 0xAB ,0x00 ,0x29, 0x82, 0x30, 0x20, 0x32, 0x35, 0x30, 0x34, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},

{0x4F, 0x11, 0xD3, 0x02, 0x2C, 0x24, 0x25, 0x1C, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x04, 0xD6, 0x01, 0x00, 0x9C, 0x25, 0x1C, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5},
{0x4F, 0x06, 0xD7, 0x01, 0xA3, 0x64, 0xFF, 0xA7, 0x30, 0xD4, 0xFA, 0x40, 0x74, 0x00, 0x00, 0x63, 0x9C, 0x05, 0x6E, 0x00, 0x13, 0x22, 0x9C, 0x00, 0x70, 0x00, 0x00, 0x00, 0xE5}
};
*/
byte answ_unknown_command[] {0x4F, 0x04, 0x7F, 0x60, 0x11, 0x45};

//этим сообщением котёл отвечает какие PIDы он поддерживает, эти PIDы и становятся доступны для выбора в WTT 
byte answ_5031[] {0x4F, 0x44, 0xD0, 0x31, 0x01, 0x02, 0x03, 0x04, 0x05, 0x0A, 0x0C, 0x0E, 0x10, 0x12, 0x13, 0x14,
0x15, 0x16, 0x19, 0x1A, 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x28, 0x2A, 0x2B, 0x2C, 0x2F, 0x32,
0x33, 0x34, 0x50, 0x51, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F, 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66,
0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F, 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x97};

//это ответ котла на запрошенные PIDы 
byte answ_5030[] {0x4F, 0x46, 0xD0, 0x30, 0x01, 0x01, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x0A, 0x00, 0x0C, 0x92, 0x0E, 0x45, 0x88,
0x10, 0x00, 0x12, 0x00, 0x13, 0x01, 0x0E, 0x1E, 0x00, 0x00, 0x1F, 0x00, 0x23, 0x00, 0x24, 0x00, 0x28, 0x71, 0x2A, 0x00, 0x2C, 0x00,
0x32, 0x00, 0x34, 0x04, 0x88, 0x51, 0x00, 0x00, 0x00, 0x58, 0x00, 0x4B, 0x34, 0x59, 0x00, 0x00, 0x00, 0x5A, 0x00, 0x48, 0x07, 0x5F,
0x00, 0xED, 0x60, 0x00, 0xED, 0x61, 0x00, 0x00, 0x72};


void setup() 
{

Serial.begin (2400, SERIAL_8E1); // сериал соединение протокол W-Bus
//Serial.begin (10400);          // для котлов TT-C,TT-E и им подобных
}

void loop() {





if( Serial.available()) {
    byte inByte = Serial.read();
delay(6);
  if      (!head && inByte == 0xF4) head = 1; 
  else if (head) {const byte sizeBUF = inByte; head = 0; byte buf[sizeBUF]; buf[1] = inByte; buf[0] = 0xF4;
  if (buf[1] <100) {  for (int i = 2; i<buf[1]+2; i++) {buf[i] = Serial.read(); delay (6);}}// пишем в буфер принятое сообщение
   buf[1];  
  for (int i=0; i< (buf[1]+2); i++) Serial.write (buf[i]); // делаем эхо принятого сообщения для WTT т.к. проверяем без К-Line адаптера (на нём эхо и так возникнет)
 delay(3);
 
 bool message_found = 0;
 byte crc=0;

       if (buf[2]==0x50 &&  buf[3]==0x31){
       
    for (byte i = 0; i < (answ_5031[1]+2);  i++) {  if (i!=(answ_5031[1]+1)) crc^=answ_5031[i];  // если неизвестное сообщение 
                                                               else  {answ_5031[i]= crc;}  Serial.write (answ_5031[i]);}
                                         }
                                         
 else if  (buf[2]==0x50 &&  buf[3]==0x30){
  
    for (byte i = 0; i < (answ_5030[1]+2);  i++) {  if (i!=(answ_5030[1]+1)) crc^=answ_5030[i];  // если неизвестное сообщение 
                                                               else  {answ_5030[i]= crc;}  Serial.write (answ_5030[i]);}
  
                                         }

 
  else {for (byte j = 0; j < sizeof(answ_message)/sizeMes; j++)      {
    if (
        ((answ_message[j][2]&~0x80)==buf[2] && answ_message[j][3] == buf[3] && !(buf[1]==2||buf[1]==4) && buf[2]!=0x60) || 
        ((answ_message[j][2]&~0x80)==buf[2] && (buf[1]==2||buf[1]==4) && buf[2]!=0x60)
        
        ) 
    
       {
         
        for (byte i=0; i<answ_message[j][1]+2 ; i++) {  if (i!=(answ_message[j][1]+1)) crc^=answ_message[j][i];
                                                      else                          {answ_message[j][i]= crc;}  
                                                      Serial.write (answ_message[j][i]);
                                                    }
       message_found = 1;                                             
       }
     
                                                          }
    if (!message_found){ 
        answ_unknown_command[3] = buf[2];
        for (byte i = 0; i < (answ_unknown_command[1]+2);  i++) {  if (i!=(answ_unknown_command[1]+1)) crc^=answ_unknown_command[i];  // если неизвестное сообщение 
                                                                   else  {answ_unknown_command[i]= crc;}  Serial.write (answ_unknown_command[i]);
                                                    }
                                                    
                       }
                                                    
                       } 
  

                 }// конец действий по принятому сообщению от WTT.  
        //         for (byte i=0 ; i< sizeof(buf); i++) buf[i]=0;
  }
  
  }
  

 

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

интересная информация по котлу Eber. У меня универсальный для доп установки. D5W S  25 2217. Сделал сниф своего котла. получил такое повторяющееся сообщение от котла раз в 500мс (полсекунды) . Шина на 1200 бод 8N1

55 40 04 00 00 00 05 5A 48 45 00 00 0E 43 91 90 43 00 58 00 AA 00 0B 0B 80 02 85 09 00 1C 00 04 C1 00 BA 52 01 01 90 02 41

Причём тут нет диалога - котел просто дает данные на диагностику (прога Edith). Щас буду менять данные и подсовывать их едиту, посмотрим что будет меняться. Написал эмулятор - едит захавал!, интересненьско -  щас хакнем и эбера.

#include <SoftwareSerial.h>

SoftwareSerial mySerial(7, 8); // RX, TX
byte answer[] = {0x8F, 0x43, 0x00, 0x57, 0x00, 0xAC, 0x00, 0x0B, 0x0B, 0x80, 0x02, 0x85, 0x09, 0x00, 0x1C, 0x00, 0x04, 0xC1, 0x00, 0xBA, 0x52, 0x01, 0x01, 0x90, 0x02, 0x41};
uint32_t prev = 0;
int bytenumber = 6;



bool f=0 ;
void setup() {
Serial.begin (115200);
mySerial.begin (1200);

}

void loop() {


if (Serial.available()) {
     
  byte inbyte=0;
     
          inbyte = Serial.read(); delay(2);
  if (inbyte == '-')  {bytenumber  --; Serial.print ("        bytenumber: "); Serial.println (bytenumber);} 
  if (inbyte == '+')  {bytenumber  ++;  Serial.print ("        bytenumber: "); Serial.println (bytenumber);} 
  
  if (inbyte == '.') {answer[bytenumber]++;Serial.print ("byte value: "); Serial.println (answer[bytenumber]); }
  if (inbyte == 'm') {if (f)answer[bytenumber]=255;else answer[bytenumber]=0; f=!f; Serial.print ("byte value: "); Serial.println (answer[bytenumber]);
  
  }
  if (inbyte == ',') {answer[bytenumber]--;Serial.print ("byte value: "); Serial.println (answer[bytenumber]); }
  if (inbyte == '0') {bitWrite (answer[bytenumber], 0 , !bitRead(answer[bytenumber],0)) ;  }   // меняем згачение байта по битам
  if (inbyte == '1') {bitWrite (answer[bytenumber], 1 , !bitRead(answer[bytenumber],1)) ;  }   // меняем згачение байта по битам
  if (inbyte == '2') {bitWrite (answer[bytenumber], 2 , !bitRead(answer[bytenumber],2)) ;  }   // меняем згачение байта по битам
  if (inbyte == '3') {bitWrite (answer[bytenumber], 3 , !bitRead(answer[bytenumber],3)) ;  }   // меняем згачение байта по битам
  if (inbyte == '4') {bitWrite (answer[bytenumber], 4 , !bitRead(answer[bytenumber],4)) ;  }   // меняем згачение байта по битам
  if (inbyte == '5') {bitWrite (answer[bytenumber], 5 , !bitRead(answer[bytenumber],5)) ;  }   // меняем згачение байта по битам
  if (inbyte == '6') {bitWrite (answer[bytenumber], 6 , !bitRead(answer[bytenumber],6)) ;  }   // меняем згачение байта по битам
  if (inbyte == '7') {bitWrite (answer[bytenumber], 7 , !bitRead(answer[bytenumber],7)) ;  }   // меняем згачение байта по битам
  
  
  
Serial.flush();
  return;}

  
if (millis() - prev > 125) {
  for (byte i = 0; i < sizeof(answer); i++) { mySerial.write (answer[i]);}
  
  prev = millis();
  }
}

Работает через К-лайн 

 

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

вот что удалось выяснить - почти всё, что нужно. Осталось формулы подобрать с помощью эмуля, выяснив закономерность изменения параметров и значения байта. Эмуль выше поправил, для возможности оперативного изменения байтов ответного сообщения через Serial 

13 байт:  датчик горения      t*C, при увеличении байта температура увеличивается
14 байт: датчик перегрева     t*C, при увеличении байта температура уменьшается
15 байт: датчик регулирования t*C, при увеличении байта температура уменьшается
20 байт: напряжение питания 
21 байт: безопасное время, с
23 байт:  булевые переменные (биты) начиная с нулевого бита - работа устройств:      
          
	  0 бит - неизвестно 
          1 бит - помпа, 
          2 бит - неизвестно,
          3 бит - свеча накала,
          4 бит - неизвестно,
	  5 бит - дозировочный топливный насос,
	  6 бит - неизвестно,
	  7 бит - нагнетатель воздуха. 


24 байт:  булевые переменные (биты) начиная с нулевого бита - работа устройств:      

          0 бит - рабочий режим  - холодный обдув
          1 бит - неизвестно,
          2 бит - степень регулирования высокая
          3 бит - степень регулирования низкая
          4 бит - неизвестно,
	  5 бит - рабочий режим  - информационный выбег 
	  6 бит - неизвестно,
	  7 бит - неизвестно

25 байт:  булевые переменные (биты) начиная с нулевого бита - работа устройств:      
	   
          0 бит - неизвестно,
          1 бит - тип эксплуатации - автономный обогрев
          2 бит - неизвестно,
          3 бит - неизвестно,
          4 бит - наличие пламени!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
	  5 бит - степень регулирования : выкл
	  6 бит - неизвестно,
	  7 бит - неизвестно

27 байт:  сигналы включения элементы управления
          
          0 бит - автономный подогрев
          1 бит - подогрев K/L 15
          2 бит - неизвестно,
          3 бит - неизвестно,
          4 бит - неизвестно,
	  5 бит - неизвестно,
	  6 бит - неизвестно,
	  7 бит - неизвестно

28 байт: напряжения эл. двигателя нагнетателя
 
32 байт: булевые переменные (биты) начиная с нулевого бита - работа устройств:      
         
          0 бит - стартовый режим - первное включение 
          1 бит - стартовый режим - запуск регулирования
          2 бит - стартовый режим - повтор запуска
          3 бит - неизвестно,
          4 бит - тип режима - автономная вентиляция
	  5 бит - неизвестно,
	  6 бит - неизвестно,
	  7 бит - вентилятор печки автомобиля!!!!!!!!!!

33 , 34 и 35  байт: время наработки

36 37 38 39 40 байты - номер отопителя 






 

dethdron
Offline
Зарегистрирован: 10.08.2016

Проект действительно замечательный! Подскажите а как осуществлять контроль охраны по двум каналам?, В моей сигналке есть два доп канала один включается при постановке в охрану на 30 сек, другой включаетсся при снятии с охраны на 30сек

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


void setup()
{
  Serial.begin(9600);
  pinMode(ohranaON, INPUT_PULLUP);  
  pinMode(ohranaOFF, INPUT_PULLUP);  
}

void loop()
{
  if (digitalRead(ohranaON) == LOW)
  {
    Serial.println("ohranaON");
  }
  if (digitalRead(ohranaOFF) == LOW)
  {
   Serial.println("ohranaOFF");
  }
  delay(500);
}