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