Бортовой компьютер для Опель Зафира.

lev2606
Offline
Зарегистрирован: 19.06.2019

я понял, PIDы- это стандартизированные коды, а запросы 21 01, 21 02 и 21 03 возвращают только такие данные и по той таблице, которую создал данный производитель авто!

lev2606
Offline
Зарегистрирован: 19.06.2019

MaksVV пишет:

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

ок, спасибо!

viki13viki
Offline
Зарегистрирован: 14.11.2016

Макс почти все проблемы решил. Перекинул датчики температур на другие пины и все полетело. Остались две проблемы, 1) Почемуто TempAir температура входящего воздуха показывает -270. Может байт сбился...... и             2) обновление данных идет очень медленно и мигание цифр при обновлении постоянно, раздражает. Будешь иметь время, просмотри скетч, может делейки заодно уберешь. Спасибо зараннее.

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 bool InitGauge = 0;
 bool dataMessageOK=0;
 bool dataMessageEND = 0;
 bool MessageParse = 0;
 bool byte0 = 0;
 bool byte1 = 0;
 bool byte2 = 0; 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   mySerial.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
   currentPage = '0';       
   drawHomeScreen();  

   //подсчет среднеарифметического усредненного расхода
   for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
   for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
   L100SR_TFT = (float)L100SR_TFT/110.0;
   if (L100SR_TFT<0) L100SR_TFT = 0;
   if (L100SR_TFT>99) L100SR_TFT = 99;
   
   // строка ниже используется для настройки даты и времени часов 
   // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
   // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
   // (год, месяц, день, часы, минуты, секунды)
   //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

   Temperature ();
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
   else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else { if (currentPage != '3'){ // если открыта страница 0,1 или 2 шлем запрос пид2101, если страница 3 -  шлем запрос присутствия 
   if (millis() - prevPID > PIDTime) { PIDs();  prevPID = millis(); }}
   else if (millis() - prevpres > PresTime) {present(); prevpres = millis();}}  
      
if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   mySerial_gauge.begin(9600);}

   receive ();
   if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); Trip ();}
   if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
   if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
   Menu();
   LCDDataPrint();}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (millis() - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = millis(); }}
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDs//отправка запроса пид 2101/////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  mySerial_gauge.write (0x02);    delay (1);
  mySerial_gauge.write (0x11);    delay (1);
  mySerial_gauge.write(byte(0));  delay (1);
  mySerial_gauge.write (0x13); }
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса присутствия/////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void present() {
  Serial.println ("Otpravil zapros Present");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messagePresent[i]);
   delay (waitbyte); }}
 
 /////////////////////////////////////////////////////////////////////////////////////////////
 //получение данных от ЭБУ, разборка входящих сообщений
 /////////////////////////////////////////////////////////////////////////////////////////////
  void receive () {
  ///////////////////////////////////////////////////////////////////////
  ////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД)
  ///////////////////////////////////////////////////////////////////////
  while(!InitGauge){
   if (mySerial_gauge.available()) {
   byte inByte = mySerial_gauge.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    mySerial_gauge.write (0x02);  delay (1);
    mySerial_gauge.write (0x11);  delay (1);
    mySerial_gauge.write (0x00);  delay (1);
    mySerial_gauge.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (mySerial_gauge.available()>0)  { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 if (ZamerNumber==9) {
 Fuel = 0 ;
 for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 Fuel = (float)Fuel/10.0;}
 ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
*/

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 

   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //отправка запроса на диагностическое соединение
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация 7 пина ОБД
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 //запрос чтения и стирания ошибок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void Read() {
   Serial.println ("Zapros error;  ");
   for (int i = 0; i < length8; i++) {
   mySerial.write(messageREAD[i]);
   delay (waitbyte); }}
   
 void Erase() {
   Serial.println ("Zapros erase;  ");
   for (int i = 0; i < length7; i++) {
   mySerial.write(messageERASE[i]);
   delay (waitbyte); }}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("INTER  C", 300, 145);
    myGLCD.print("EXTER  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';           
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        Read();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        Erase();
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }

 

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

вот скетч , смотри что будет в мониторе Serial.  На экран данные выводиться не будут, не делал ещё .

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define GAUGE_K_LINE Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial PCM_K_LINE   (12, 13); //RХ,TХ

#define PCM_address  0x11
#define DIAG_address 0xF1
 
 
 //-------------------------- Переменные для бортовика
  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;            //мгновенный расход топлива литров в час
 float L100SR = 0;          //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;      // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 

//-------------------------- Переменные для обмена к-лайн приборки 
 
 bool InitGauge = 0;

 
 
 
 byte EndSession []= {0x02, 0xB2, 0x00, 0xB4};
 byte PIDGauge []=   {0x02, 0x11, 0x00, 0x13};
byte head_count = 0;
byte head[4] = {0};


//-------------------------- Переменные для обмена к-лайн PCM 

uint32_t curmillis = 0;      // снимок текущего времени 
 
 uint32_t prevRequest = 0;   // таймер периодических запросов
 int RequestPeriod = 50;    // периодичность запросов , мс
 
 uint32_t prevRESETheader=0; // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 bool RESETheader_timer;     // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 
 uint32_t prev_NOanswer=0;   // таймер контроля неответов от ЭБУ после запросов
 bool NOanswer_timer = 0;    // таймер контроля неответов от ЭБУ после запросов
 byte noanswers = 0;         // количество подряд неответов от ЭБУ 
 
 uint32_t timerdelay = 0;    // таймер ожидания байт (для успевания появления данных в буфере UART)
 bool Delay = 0;             // таймер ожидания байт (для успевания появления данных в буфере UART)
 byte waitbyte_RX = 1;       // задержка, мс для успевания появления данных в буфере RX 
                             // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) 
 #define TIMER_DELAY Delay = 0; timerdelay = curmillis  // включение этого таймера
  
 byte delaybyte_TX  = 1;     // задержка между отправкой байт в запросах, мс
byte inits = 0;              // количество инитов посланных на PCM
byte header = 0;          // состояние заголовка
byte message_size = 0;    // размер тела сообщения
byte j = 3;               // инкремент
byte n = 3;               // количество старт байт
const byte bufsize = 110; // размер буфера принятого сообщения
byte buf [bufsize] = {0}; // буфер принятого сообщения
byte crc =0;              // байт контрольной суммы 


// возможные варианты запросов на ЭБУ:
enum REQUEST {
 INIT,    
 PID,     
 DTCERASE,
 DTCREAD,
 PRESENT,
 INIT_bus};
 
 byte PCM_Message_TX[][5] = {
 {1,  0x81,           0,0,0},      // запрос инициализации
 {2,  0x21,0x01,        0,0},      // запрос пид 2101
 {3,  0x14,0xFF,0x00,     0},      // запрос на стирание ошибок
 {4,  0x18,0x00,0xFF,0x00  },      // запрос на чтение ошибок
 {1,  0x3E,           0,0,0},      // запрос присутствия 
                            };

byte request = INIT;      // переменная, показывающая какой запрос будем делать
 


 

 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 

 

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   PCM_K_LINE.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   //sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
   currentPage = '0';  
      
   drawHomeScreen();  

   //подсчет среднеарифметического усредненного расхода
   for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
   for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
   L100SR_TFT = (float)L100SR_TFT/110.0;
   if (L100SR_TFT<0) L100SR_TFT = 0;
   if (L100SR_TFT>99) L100SR_TFT = 99;
   
   // строка ниже используется для настройки даты и времени часов 
   // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
   // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
   // (год, месяц, день, часы, минуты, секунды)
   //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

   Temperature ();
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
   
   curmillis = millis ();
   
      
// ниже шлём периодически запросы на PCM
if (curmillis - prevRequest > RequestPeriod && header == 0) {
  NOanswer_timer = 1; prev_NOanswer = curmillis;           //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов 
  if (request == INIT_bus) {PCM_K_LINE.end(); delay (450); fastinit();} 
  else                     {sendMessagePCM(request); if (request == INIT) {inits++; if(inits>5) request = INIT_bus, inits=0;}} // отправляем на PCM текущий запрос
  TX_otladka();    
  prevRequest = curmillis;
                                                             }


if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   GAUGE_K_LINE.begin(9600);}

   receive ();
   if (curmillis - prevWatch > 3000)  { Watch (); prevWatch = curmillis; Trip ();}
   //if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
   if (curmillis - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = curmillis; Dvoet=!Dvoet;}
   Menu();
   LCDDataPrint();}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (curmillis - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = curmillis; }}
 

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  GAUGE_K_LINE.write (0x02);    delay (1);
  GAUGE_K_LINE.write (0x11);    delay (1);
  GAUGE_K_LINE.write(byte(0));  delay (1);
  GAUGE_K_LINE.write (0x13); }
 
 
 
 
  void receive () {
 
  // работа с К-Line софт сериал 16-17 (12 контакт ОБД)


while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {delay (10); GAUGE_K_LINE.write (0x7F); }                                                  
  if (inByte==0xF0) {delay (10);                                                                                                   
    for (byte i=0; i< sizeof(PIDGauge); i++) {GAUGE_K_LINE.write (PIDGauge[i]);  delay (delaybyte_TX);}
    
    InitGauge=1; Serial.println("   Ura! Panel init proshla uspeshno!"); }}}
 
 
 if (InitGauge && GAUGE_K_LINE.available()) {
  
  
  
  
  // ниже ищем шапку кадра 
     
     byte inbyte = GAUGE_K_LINE.read();
     delay (7);
         if (inbyte == 0x21 && head_count == 0) {head_count = 1; head[0] = inbyte; } 
    else if (inbyte == 0xA1 && head_count == 1) {head_count = 2; head[1] = inbyte; } 
    else if (inbyte == 0x04 && head_count == 2) {head_count = 3; head[2] = inbyte; } 
    else {head_count = 0; for (byte i=0; i<sizeof(head); i++) head[i] = 0;} 

    // нашли шапку: 
  
  if (head_count == 3){
    
    head_count = 0; // очищаем переменную поиска шапки 
    
     byte Length = head[0];
     if (Length>100)Length=100;
    
    const byte sizeMes = Length+2;
    
    byte MessageRx_GAUGE [sizeMes] = {0};
    uint16_t cRc = 0; 
    for (byte i=0; i<3; i++){MessageRx_GAUGE[i]= head[i]; cRc += MessageRx_GAUGE[i]; head[i] = 0; Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" ");}  // очищаем переменные поиска шапки 
    
    bool CRC_OK = 0;

    // ниже пишем сообщение в буфер и считаем КС
    for (byte i = 3; i < sizeMes; i++) { MessageRx_GAUGE[i] = GAUGE_K_LINE.read();  if (i<=sizeMes-3) cRc += MessageRx_GAUGE[i]; delay (7); Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" "); }
//   Serial.println();
int CrC =  ( ( unsigned int )MessageRx_GAUGE [sizeMes-2] << 8 ) | MessageRx_GAUGE [sizeMes-1];
if (CrC==cRc) CRC_OK = 1;

     if (CRC_OK){Serial.println (" OK!!!");} // конец ифа с правильной CRC  

   else  Serial.println("  CRC FAIL!!!");

  
  }   

}



  /*
  while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {GAUGE_K_LINE.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    GAUGE_K_LINE.write (0x02);  delay (1);
    GAUGE_K_LINE.write (0x11);  delay (1);
    GAUGE_K_LINE.write (0x00);  delay (1);
    GAUGE_K_LINE.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (GAUGE_K_LINE.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (GAUGE_K_LINE.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (GAUGE_K_LINE.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (GAUGE_K_LINE.available()>0)  { MessageRxGauge[numberbyte] = GAUGE_K_LINE.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 //else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 //if (ZamerNumber==9) {
 //Fuel = 0 ;
 //for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 //Fuel = (float)Fuel/10.0;}
 //ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
//

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //GAUGE_K_LINE.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 
*/
   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
  
   
   if (PCM_K_LINE.available() ){
    
 // первый старт байт
 if (header == 0 && Delay){TIMER_DELAY ; buf[0]=PCM_K_LINE.read();  
         if (buf[0]!=0xFF && bitRead (buf[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; 
         Serial.print (buf[0], HEX);  Serial.print (" "); }}                  

 // второй старт байт
 if (header == 1 && Delay){TIMER_DELAY ; buf[1]=PCM_K_LINE.read(); Serial.print (buf[1], HEX);  Serial.print (" ");if (buf[1]==DIAG_address){ header = 2;} else {Serial.println("Message fail"); header = 0; RESETheader_timer = 0;}} 

 // третий старт байт
 if (header == 2 && Delay){ 
  TIMER_DELAY ;
  buf[2]=PCM_K_LINE.read(); Serial.print (buf[2], HEX);  Serial.print (" ");
  if (buf[2]==PCM_address){ message_size = buf[0]; 
  if (buf[0] !=0x80) {header = 4;  bitWrite (message_size, 7 , 0);j=3;n=3;}
  else {header = 3; j=4;n=4;}
  if (message_size > bufsize) message_size = bufsize;  crc = 0;} else {header = 0; Serial.println("Message fail"); RESETheader_timer = 0;}
  
                          }  
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay){
  TIMER_DELAY ;
  buf[3]=PCM_K_LINE.read(); Serial.print (buf[3], HEX);  Serial.print (" ");
  message_size = buf[3]; 
  if (message_size > bufsize) message_size = bufsize;  
  crc = 0; header = 4;  
                         }

  // пишем тело сообщения 
 if (header == 4 && Delay && j< message_size+n+1) {
 buf[j] = PCM_K_LINE.read(); 
 if (j<message_size+n) crc+= buf[j]; // подсчёт КС
 
 if (j==message_size+n) header = 5; 
 TIMER_DELAY ; Serial.print (buf[j], HEX);  Serial.print (" ");  j++;} 
 }

 // сообщение приняли, действуем
 if (header == 5) {TIMER_DELAY ;  
 Serial.println();  
 NOanswer_timer = 0; noanswers = 0;    // сбрасываем таймер контроля неответов 

for(byte i = 0; i<n; i++) crc+=buf[i]; // прибавляем к контрольной сумме старт байты

 // если контрольная сумма верна: 
if ( crc == buf[message_size+n]) 
{  
  Serial.println("Received message is OK! Checksum is correct!" );  // Если КС совпала, тут чёнибудь нужное делаем
    
          if (buf[n]==0xC1 && buf[n+1]==0x6B && buf[n+2]==0x8F) {if (currentPage!=3) pids(); else request = DTCREAD, RequestPeriod = 5000; Serial.println ("     Initialization OK!!!!:  "); }
 else if (buf[n]==0x58 && buf[n+1]==0x00) {Serial.println ("     NO DTC  ");}
 else if (buf[n]==0x58 && buf[n+1] >0x00) {Serial.println ("     DTC is found!");} 
 else if (buf[n]==0x54 && buf[n+1]==0xFF && buf[n+2]==0x00){ Serial.println ("     DTC CLEARED  "); request = DTCREAD; RequestPeriod = 5000;}
 else if (buf[n]==0x61 && buf[n+1]==0x01) {Serial.println ("     Receive DATA");}
  
 }   

// если контрольная сумма не совпала: 
else Serial.println("CRC fail!!!" );
message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0;
}

// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; 

// таймер сброса заголовка если данные оборвались во время приёма заголовка
if (RESETheader_timer && curmillis - prevRESETheader > 500) {Serial.println("Message fail timeout"); RESETheader_timer = 0; header = 0;}   
 
// если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит.  
if (NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/8) {NOanswer_timer = 0; noanswers++; 
     if (noanswers>=6) { noanswers = 0; request = INIT_bus;}         }
 
   
   
   
   
   
   /*
   
   if (PCM_K_LINE.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( PCM_K_LINE.available() && k < 110) {
   inbyte = PCM_K_LINE.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }// очистка байтов массива
     
*/     
     
     } // конец receive 
     
   

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация PCM на 7 пине ОБД (fast init - 25ms LOW 25ms HIGH)
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   PCM_K_LINE.begin(10400); // baud rate of the OBD
   request = INIT; RequestPeriod = 500;
   
   } 



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("INTER  C", 300, 145);
    myGLCD.print("EXTER  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';    
        pids(); // на PCM в этом окне посылается запрос текущих параметров       
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров      
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';  
       request = DTCREAD; RequestPeriod = 5000;  // на PCM в этом окне посылается запрос чтения ошибок  
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        request = DTCREAD; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок  
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
       request = DTCERASE; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок 
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }




void sendMessagePCM(const byte &command)
{
 
  byte size =  PCM_Message_TX[command][0];
  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] = PCM_address;
    if (i==2) Mes[i] = DIAG_address;    
    if (i==3) {for (byte t=1; t<size+1; t++ ) {
           Mes[i]=PCM_Message_TX [command][t]; 
           Checksum+=Mes[i] ; 
           PCM_K_LINE.write (Mes[i]); 
           delay (delaybyte_TX);  
           PCM_K_LINE.read(); 
           i++;}}
    if (i!=siZe-1) Checksum+=Mes[i];
    else Mes[i] = Checksum;    
    PCM_K_LINE.write (Mes[i]);
    delay (delaybyte_TX);
    PCM_K_LINE.read();
                             }
                     
}


 void TX_otladka(){
    
      if (request == INIT_bus) Serial.println ("Bus_INIT"); 
 else if (request == INIT)     Serial.println ("Otpravil zapros Init");
 else if (request == DTCREAD)  Serial.println ("Otpravil zapros DTC read");
 else if (request == DTCERASE) Serial.println ("Otpravil zapros DTC clear");
                   }

void pids(){request = PID; RequestPeriod = 50;}
 

 

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

у меня тормозит процесс функция LCDDataPrint(). Возможно это из-за неподключенного экрана, если у тебя и с подлюченным LCD будет тормозить (будет затруднен прием байт от PCM), то нужно ковырять эту функцию, или закоментить пока. 

viki13viki
Offline
Зарегистрирован: 14.11.2016

выдало в потру вот это

Otpravil zapros Init
Otpravil zapros adress Gauge
 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0   Ura! Panel init proshla uspeshno!
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
 
я так понимаю это хорошо (-: 
 
 
MaksVV
Offline
Зарегистрирован: 06.08.2015

Ну вообще-то не очень. Нет соединения с PCM. И не идут данные с приборки после запроса пид. 

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

Нужен лог с твоего рабочего скетча 1403

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

Вместо этого в строке 0408

 if (InitGauge && GAUGE_K_LINE.available()) {

Вставить так 

 if (InitGauge) {

       if (GAUGE_K_LINE.available()) {

Ну и конечно закрывающую скобку } добавить в строке 0454

viki13viki
Offline
Зарегистрирован: 14.11.2016

вот рабочий скетч

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 bool InitGauge = 0;
 bool dataMessageOK=0;
 bool dataMessageEND = 0;
 bool MessageParse = 0;
 bool byte0 = 0;
 bool byte1 = 0;
 bool byte2 = 0; 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x1581; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   mySerial.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b);  
   
   //загрузка стартовой страницы
   currentPage = '0';       
   drawHomeScreen();  

   //подсчет среднеарифметического усредненного расхода
   for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
   for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
   L100SR_TFT = (float)L100SR_TFT/110.0;
   if (L100SR_TFT<0) L100SR_TFT = 0;
   if (L100SR_TFT>99) L100SR_TFT = 99;
   
   // строка ниже используется для настройки даты и времени часов 
   // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
   // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
   // (год, месяц, день, часы, минуты, секунды)
   //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

   Temperature ();
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
   else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else { if (currentPage != '3'){ // если открыта страница 0,1 или 2 шлем запрос пид2101, если страница 3 -  шлем запрос присутствия 
   if (millis() - prevPID > PIDTime) { PIDs();  prevPID = millis(); }}
   else if (millis() - prevpres > PresTime) {present(); prevpres = millis();}}  
      
if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   mySerial_gauge.begin(9600);}

   receive ();
   if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); Trip ();}
   if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
   if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
   Menu();
   LCDDataPrint();}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (millis() - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     //myGLCD.setBackColor(0,0,0);   //затирание текста
     //myGLCD.setTextColor(0xFFFF, 0x0000); 
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = millis(); }}
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDs//отправка запроса пид 2101/////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  mySerial_gauge.write (0x02);    delay (1);
  mySerial_gauge.write (0x11);    delay (1);
  mySerial_gauge.write(byte(0));  delay (1);
  mySerial_gauge.write (0x13); }
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса присутствия/////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void present() {
  Serial.println ("Otpravil zapros Present");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messagePresent[i]);
   delay (waitbyte); }}
 
 /////////////////////////////////////////////////////////////////////////////////////////////
 //получение данных от ЭБУ, разборка входящих сообщений
 /////////////////////////////////////////////////////////////////////////////////////////////
  void receive () {
  ///////////////////////////////////////////////////////////////////////
  ////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД)
  ///////////////////////////////////////////////////////////////////////
  while(!InitGauge){
   if (mySerial_gauge.available()) {
   byte inByte = mySerial_gauge.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    mySerial_gauge.write (0x02);  delay (1);
    mySerial_gauge.write (0x11);  delay (1);
    mySerial_gauge.write (0x00);  delay (1);
    mySerial_gauge.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (mySerial_gauge.available()>0)  { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 if (ZamerNumber==9) {
 Fuel = 0 ;
 for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 Fuel = (float)Fuel/10.0;}
 ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
*/

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 

   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //отправка запроса на диагностическое соединение
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация 7 пина ОБД
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 //запрос чтения и стирания ошибок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void Read() {
   Serial.println ("Zapros error;  ");
   for (int i = 0; i < length8; i++) {
   mySerial.write(messageREAD[i]);
   delay (waitbyte); }}
   
 void Erase() {
   Serial.println ("Zapros erase;  ");
   for (int i = 0; i < length7; i++) {
   mySerial.write(messageERASE[i]);
   delay (waitbyte); }}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGIN RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("DENTR  C", 300, 145);
    myGLCD.print("FUERA  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';           
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        Read();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        Erase();
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }

вот его лог

Otpravil zapros Init
Otpravil zapros adress Gauge
 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BB 0 FF 4C 55 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B0     OK!!!
Receive:   0 FF FF 83 F1 11 C1 6B 8F 40 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B3     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BB 0 FF 4C 56 55 38 4F 0 0 0 A1 0 0 0 0 0 0 0 0 4 10     ERROR!!!
Receive:   FF FF 83 F1 11 C1 6B 8F 40 
     Initialization OK!!!!:  
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B3     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 2B 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A8 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 39 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B4     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BB 0 FF 4C 56 55 38 4F 0 0 0 55 4F 0 22 4 B7 76 4 29 1D 0     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 2B 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 38 4F 55 4F 0 22 4 B7 76 4 29 1D 0 0 5 B3     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 2B 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BC 0 FF 4C 56 55 38 4F 0 0 0 4 10 BD 0 FF 4C 56 55 38 4F 0     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 2B 0 0 2 6B 0 0 0 0 4 36 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4B 56 55 39 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B3     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 2B 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 4D 56 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B1     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 29 0 0 2 6B 0 0 0 0 4 3A 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4B 55 55 38 4F 0 0 0 10 0 4B 55 38 4F 0 0 0 22 4     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 4D 55 4F 0 0 22 4 B7 76 4 29 1D 0 0 5 B1 23 A1 4 0     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 2C 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 4D 55 55 39 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B1     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BC 0 FF 4B 56 55 39 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B2     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 4D 56 55 38 4F 0 0 0 4 76 29 0 0 5 B1 23 A1 4 0     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 4D 56 55 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 2B 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 39 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B4     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 2B 0 0 2 6B 0 0 0 0 4 38 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 55 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B2     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 55 55 38 4F 0 0 0 0 4C 55 4F 0 0 0 22 4 B7 76     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 2B 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A8 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 4C 56 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 28 0 0 2 6B 0 0 0 0 4 3A 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BC 0 FF 4B 56 55 39 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B2     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B2 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 4D 56 55 38 4F BA 0 FF 4C 56 55 38 4F 0 0 0 22 4 B7     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 29 0 0 2 6B 0 0 0 0 4 3A 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B3 23     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B6 0 0 D 28 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 39 4F 0 0 0 22 4 29 1D 0 0 5 B3 23 A1 4     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 29 0 0 2 6B 0 0 0 0 4 36 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A6 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BD 0 FF 4C 56 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B3     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 29 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A3 0 0 0 0 8 D8 0 0 D 56 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 BA 0 FF 4C 56 55 38 4F 0 0 0 22 4 B7 76 4 29 1D 0 0 5 B0     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 0 0 0 0 0 0 0 0 D B4 0 0 D 28 0 0 2 6B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9F 4 29 3 20 E5 62 0 0 0 0 C A5 0 0 0 0 8 D8 0 0 D 56 

вот твой скетч с подправкой о которой ты говорил выше

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define GAUGE_K_LINE Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial PCM_K_LINE   (12, 13); //RХ,TХ
 #define PCM_address  0x11
 #define DIAG_address 0xF1
 
 //-------------------------- Переменные для бортовика
  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;            //мгновенный расход топлива литров в час
 float L100SR = 0;          //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;      // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 

//-------------------------- Переменные для обмена к-лайн приборки 
 
 bool InitGauge = 0;
 
 byte EndSession []= {0x02, 0xB2, 0x00, 0xB4};
 byte PIDGauge []=   {0x02, 0x11, 0x00, 0x13};
 byte head_count = 0;
 byte head[4] = {0};


//-------------------------- Переменные для обмена к-лайн PCM 

uint32_t curmillis = 0;      // снимок текущего времени 
 
 uint32_t prevRequest = 0;   // таймер периодических запросов
 int RequestPeriod = 50;    // периодичность запросов , мс
 
 uint32_t prevRESETheader=0; // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 bool RESETheader_timer;     // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 
 uint32_t prev_NOanswer=0;   // таймер контроля неответов от ЭБУ после запросов
 bool NOanswer_timer = 0;    // таймер контроля неответов от ЭБУ после запросов
 byte noanswers = 0;         // количество подряд неответов от ЭБУ 
 
 uint32_t timerdelay = 0;    // таймер ожидания байт (для успевания появления данных в буфере UART)
 bool Delay = 0;             // таймер ожидания байт (для успевания появления данных в буфере UART)
 byte waitbyte_RX = 1;       // задержка, мс для успевания появления данных в буфере RX 
                             // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) 
 #define TIMER_DELAY Delay = 0; timerdelay = curmillis  // включение этого таймера
  
 byte delaybyte_TX  = 1;     // задержка между отправкой байт в запросах, мс
byte inits = 0;              // количество инитов посланных на PCM
byte header = 0;          // состояние заголовка
byte message_size = 0;    // размер тела сообщения
byte j = 3;               // инкремент
byte n = 3;               // количество старт байт
const byte bufsize = 110; // размер буфера принятого сообщения
byte buf [bufsize] = {0}; // буфер принятого сообщения
byte crc =0;              // байт контрольной суммы 


// возможные варианты запросов на ЭБУ:
enum REQUEST {
 INIT,    
 PID,     
 DTCERASE,
 DTCREAD,
 PRESENT,
 INIT_bus};
 
 byte PCM_Message_TX[][5] = {
 {1,  0x81,           0,0,0},      // запрос инициализации
 {2,  0x21,0x01,        0,0},      // запрос пид 2101
 {3,  0x14,0xFF,0x00,     0},      // запрос на стирание ошибок
 {4,  0x18,0x00,0xFF,0x00  },      // запрос на чтение ошибок
 {1,  0x3E,           0,0,0},      // запрос присутствия 
                            };

 byte request = INIT;      // переменная, показывающая какой запрос будем делать
 
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   PCM_K_LINE.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
   currentPage = '0';     
   drawHomeScreen();  

   //подсчет среднеарифметического усредненного расхода
   for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
   for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
   L100SR_TFT = (float)L100SR_TFT/110.0;
   if (L100SR_TFT<0) L100SR_TFT = 0;
   if (L100SR_TFT>99) L100SR_TFT = 99;
   
   // строка ниже используется для настройки даты и времени часов 
   // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
   // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
   // (год, месяц, день, часы, минуты, секунды)
   //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

   Temperature ();
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
   
   curmillis = millis ();
   
      
// ниже шлём периодически запросы на PCM
if (curmillis - prevRequest > RequestPeriod && header == 0) {
  NOanswer_timer = 1; prev_NOanswer = curmillis;           //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов 
  if (request == INIT_bus) {PCM_K_LINE.end(); delay (450); fastinit();} 
  else                     {sendMessagePCM(request); if (request == INIT) {inits++; if(inits>5) request = INIT_bus, inits=0;}} // отправляем на PCM текущий запрос
  TX_otladka();    
  prevRequest = curmillis;
                                                             }


if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   GAUGE_K_LINE.begin(9600);}

   receive ();
   if (curmillis - prevWatch > 3000)  { Watch (); prevWatch = curmillis; Trip ();}
   //if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
   if (curmillis - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = curmillis; Dvoet=!Dvoet;}
   Menu();
   LCDDataPrint();}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (curmillis - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = curmillis; }}
 

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  GAUGE_K_LINE.write (0x02);    delay (1);
  GAUGE_K_LINE.write (0x11);    delay (1);
  GAUGE_K_LINE.write(byte(0));  delay (1);
  GAUGE_K_LINE.write (0x13); }
 
 
 
 
  void receive () {
 
  // работа с К-Line софт сериал 16-17 (12 контакт ОБД)


while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {delay (10); GAUGE_K_LINE.write (0x7F); }                                                  
  if (inByte==0xF0) {delay (10);                                                                                                   
    for (byte i=0; i< sizeof(PIDGauge); i++) {GAUGE_K_LINE.write (PIDGauge[i]);  delay (delaybyte_TX);}
    
    InitGauge=1; Serial.println("   Ura! Panel init proshla uspeshno!"); }}}
  
  if (InitGauge) {
  if (GAUGE_K_LINE.available()) {
  
  // ниже ищем шапку кадра 
     
     byte inbyte = GAUGE_K_LINE.read();
     delay (7);
         if (inbyte == 0x21 && head_count == 0) {head_count = 1; head[0] = inbyte; } 
    else if (inbyte == 0xA1 && head_count == 1) {head_count = 2; head[1] = inbyte; } 
    else if (inbyte == 0x04 && head_count == 2) {head_count = 3; head[2] = inbyte; } 
    else {head_count = 0; for (byte i=0; i<sizeof(head); i++) head[i] = 0;} 

    // нашли шапку: 
  
  if (head_count == 3){
    
    head_count = 0; // очищаем переменную поиска шапки 
    
     byte Length = head[0];
     if (Length>100)Length=100;
    
    const byte sizeMes = Length+2;
    
    byte MessageRx_GAUGE [sizeMes] = {0};
    uint16_t cRc = 0; 
    for (byte i=0; i<3; i++){MessageRx_GAUGE[i]= head[i]; cRc += MessageRx_GAUGE[i]; head[i] = 0; Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" ");}  // очищаем переменные поиска шапки 
    
    bool CRC_OK = 0;

    // ниже пишем сообщение в буфер и считаем КС
    for (byte i = 3; i < sizeMes; i++) { MessageRx_GAUGE[i] = GAUGE_K_LINE.read();  if (i<=sizeMes-3) cRc += MessageRx_GAUGE[i]; delay (7); Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" "); }
//   Serial.println();
    int CrC =  ( ( unsigned int )MessageRx_GAUGE [sizeMes-2] << 8 ) | MessageRx_GAUGE [sizeMes-1];
    if (CrC==cRc) CRC_OK = 1;

    if (CRC_OK){Serial.println (" OK!!!");} // конец ифа с правильной CRC  

    else  Serial.println("  CRC FAIL!!!");
  }   
 }
}


  /*
  while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {GAUGE_K_LINE.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    GAUGE_K_LINE.write (0x02);  delay (1);
    GAUGE_K_LINE.write (0x11);  delay (1);
    GAUGE_K_LINE.write (0x00);  delay (1);
    GAUGE_K_LINE.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (GAUGE_K_LINE.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (GAUGE_K_LINE.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (GAUGE_K_LINE.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (GAUGE_K_LINE.available()>0)  { MessageRxGauge[numberbyte] = GAUGE_K_LINE.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 //else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 //if (ZamerNumber==9) {
 //Fuel = 0 ;
 //for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 //Fuel = (float)Fuel/10.0;}
 //ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
//

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //GAUGE_K_LINE.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 
*/
   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
  
   
   if (PCM_K_LINE.available() ){
    
 // первый старт байт
 if (header == 0 && Delay){TIMER_DELAY ; buf[0]=PCM_K_LINE.read();  
         if (buf[0]!=0xFF && bitRead (buf[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; 
         Serial.print (buf[0], HEX);  Serial.print (" "); }}                  

 // второй старт байт
 if (header == 1 && Delay){TIMER_DELAY ; buf[1]=PCM_K_LINE.read(); Serial.print (buf[1], HEX);  Serial.print (" ");if (buf[1]==DIAG_address){ header = 2;} else {Serial.println("Message fail"); header = 0; RESETheader_timer = 0;}} 

 // третий старт байт
 if (header == 2 && Delay){ 
  TIMER_DELAY ;
  buf[2]=PCM_K_LINE.read(); Serial.print (buf[2], HEX);  Serial.print (" ");
  if (buf[2]==PCM_address){ message_size = buf[0]; 
  if (buf[0] !=0x80) {header = 4;  bitWrite (message_size, 7 , 0);j=3;n=3;}
  else {header = 3; j=4;n=4;}
  if (message_size > bufsize) message_size = bufsize;  crc = 0;} else {header = 0; Serial.println("Message fail"); RESETheader_timer = 0;}
  
                          }  
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay){
  TIMER_DELAY ;
  buf[3]=PCM_K_LINE.read(); Serial.print (buf[3], HEX);  Serial.print (" ");
  message_size = buf[3]; 
  if (message_size > bufsize) message_size = bufsize;  
  crc = 0; header = 4;  
                         }

  // пишем тело сообщения 
 if (header == 4 && Delay && j< message_size+n+1) {
 buf[j] = PCM_K_LINE.read(); 
 if (j<message_size+n) crc+= buf[j]; // подсчёт КС
 
 if (j==message_size+n) header = 5; 
 TIMER_DELAY ; Serial.print (buf[j], HEX);  Serial.print (" ");  j++;} 
 }

 // сообщение приняли, действуем
 if (header == 5) {TIMER_DELAY ;  
 Serial.println();  
 NOanswer_timer = 0; noanswers = 0;    // сбрасываем таймер контроля неответов 

for(byte i = 0; i<n; i++) crc+=buf[i]; // прибавляем к контрольной сумме старт байты

 // если контрольная сумма верна: 
if ( crc == buf[message_size+n]) 
{  
  Serial.println("Received message is OK! Checksum is correct!" );  // Если КС совпала, тут чёнибудь нужное делаем
    
          if (buf[n]==0xC1 && buf[n+1]==0x6B && buf[n+2]==0x8F) {if (currentPage!=3) pids(); else request = DTCREAD, RequestPeriod = 5000; Serial.println ("     Initialization OK!!!!:  "); }
 else if (buf[n]==0x58 && buf[n+1]==0x00) {Serial.println ("     NO DTC  ");}
 else if (buf[n]==0x58 && buf[n+1] >0x00) {Serial.println ("     DTC is found!");} 
 else if (buf[n]==0x54 && buf[n+1]==0xFF && buf[n+2]==0x00){ Serial.println ("     DTC CLEARED  "); request = DTCREAD; RequestPeriod = 5000;}
 else if (buf[n]==0x61 && buf[n+1]==0x01) {Serial.println ("     Receive DATA");}
  
 }   

// если контрольная сумма не совпала: 
else Serial.println("CRC fail!!!" );
message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0;
}

// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; 

// таймер сброса заголовка если данные оборвались во время приёма заголовка
if (RESETheader_timer && curmillis - prevRESETheader > 500) {Serial.println("Message fail timeout"); RESETheader_timer = 0; header = 0;}   
 
// если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит.  
if (NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/8) {NOanswer_timer = 0; noanswers++; 
     if (noanswers>=6) { noanswers = 0; request = INIT_bus;}         }
 
   
   
   
   
   
   /*
   
   if (PCM_K_LINE.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( PCM_K_LINE.available() && k < 110) {
   inbyte = PCM_K_LINE.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }// очистка байтов массива
     
*/     
     
     } // конец receive 
     
   

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация PCM на 7 пине ОБД (fast init - 25ms LOW 25ms HIGH)
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   PCM_K_LINE.begin(10400); // baud rate of the OBD
   request = INIT; RequestPeriod = 500;
   
   } 



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("INTER  C", 300, 145);
    myGLCD.print("EXTER  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';    
        pids(); // на PCM в этом окне посылается запрос текущих параметров       
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров      
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';  
       request = DTCREAD; RequestPeriod = 5000;  // на PCM в этом окне посылается запрос чтения ошибок  
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        request = DTCREAD; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок  
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
       request = DTCERASE; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок 
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }




void sendMessagePCM(const byte &command)
{
 
  byte size =  PCM_Message_TX[command][0];
  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] = PCM_address;
    if (i==2) Mes[i] = DIAG_address;    
    if (i==3) {for (byte t=1; t<size+1; t++ ) {
           Mes[i]=PCM_Message_TX [command][t]; 
           Checksum+=Mes[i] ; 
           PCM_K_LINE.write (Mes[i]); 
           delay (delaybyte_TX);  
           PCM_K_LINE.read(); 
           i++;}}
    if (i!=siZe-1) Checksum+=Mes[i];
    else Mes[i] = Checksum;    
    PCM_K_LINE.write (Mes[i]);
    delay (delaybyte_TX);
    PCM_K_LINE.read();
                             }
                     
}


 void TX_otladka(){
    
      if (request == INIT_bus) Serial.println ("Bus_INIT"); 
 else if (request == INIT)     Serial.println ("Otpravil zapros Init");
 else if (request == DTCREAD)  Serial.println ("Otpravil zapros DTC read");
 else if (request == DTCERASE) Serial.println ("Otpravil zapros DTC clear");
                   }

void pids(){request = PID; RequestPeriod = 50;}
 

вот лог тотже что и вчера

Otpravil zapros Init
Otpravil zapros adress Gauge
 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0   Ura! Panel init proshla uspeshno!
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init

 

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

строка 401 там я лоханулся с одной циферкой . нужно так: 

if (inbyte == 0x23 && head_count == 0) {head_count = 1; head[0] = inbyte; }

вместо строк 1043 и 1049 (они одинаковые ) вставить это : 

if (request == INIT) delay (5); else delay (delaybyte_TX);  

в строку 758 вставить это 

sendMessagePCM(request); prevRequest = curmillis;

 

viki13viki
Offline
Зарегистрирован: 14.11.2016

с 401й строкой понятно 21 на 23 исправил, а остальные строки вообще не в той степи. соорентируй по этому скетчку

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define GAUGE_K_LINE Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial PCM_K_LINE   (12, 13); //RХ,TХ
 #define PCM_address  0x11
 #define DIAG_address 0xF1
 
 //-------------------------- Переменные для бортовика
  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;            //мгновенный расход топлива литров в час
 float L100SR = 0;          //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;      // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 

//-------------------------- Переменные для обмена к-лайн приборки 
 
 bool InitGauge = 0;
 
 byte EndSession []= {0x02, 0xB2, 0x00, 0xB4};
 byte PIDGauge []=   {0x02, 0x11, 0x00, 0x13};
 byte head_count = 0;
 byte head[4] = {0};


//-------------------------- Переменные для обмена к-лайн PCM 

uint32_t curmillis = 0;      // снимок текущего времени 
 
 uint32_t prevRequest = 0;   // таймер периодических запросов
 int RequestPeriod = 50;    // периодичность запросов , мс
 
 uint32_t prevRESETheader=0; // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 bool RESETheader_timer;     // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 
 uint32_t prev_NOanswer=0;   // таймер контроля неответов от ЭБУ после запросов
 bool NOanswer_timer = 0;    // таймер контроля неответов от ЭБУ после запросов
 byte noanswers = 0;         // количество подряд неответов от ЭБУ 
 
 uint32_t timerdelay = 0;    // таймер ожидания байт (для успевания появления данных в буфере UART)
 bool Delay = 0;             // таймер ожидания байт (для успевания появления данных в буфере UART)
 byte waitbyte_RX = 1;       // задержка, мс для успевания появления данных в буфере RX 
                             // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) 
 #define TIMER_DELAY Delay = 0; timerdelay = curmillis  // включение этого таймера
  
 byte delaybyte_TX  = 1;     // задержка между отправкой байт в запросах, мс
byte inits = 0;              // количество инитов посланных на PCM
byte header = 0;          // состояние заголовка
byte message_size = 0;    // размер тела сообщения
byte j = 3;               // инкремент
byte n = 3;               // количество старт байт
const byte bufsize = 110; // размер буфера принятого сообщения
byte buf [bufsize] = {0}; // буфер принятого сообщения
byte crc =0;              // байт контрольной суммы 


// возможные варианты запросов на ЭБУ:
enum REQUEST {
 INIT,    
 PID,     
 DTCERASE,
 DTCREAD,
 PRESENT,
 INIT_bus};
 
 byte PCM_Message_TX[][5] = {
 {1,  0x81,           0,0,0},      // запрос инициализации
 {2,  0x21,0x01,        0,0},      // запрос пид 2101
 {3,  0x14,0xFF,0x00,     0},      // запрос на стирание ошибок
 {4,  0x18,0x00,0xFF,0x00  },      // запрос на чтение ошибок
 {1,  0x3E,           0,0,0},      // запрос присутствия 
                            };

 byte request = INIT;      // переменная, показывающая какой запрос будем делать
 
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   PCM_K_LINE.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
   currentPage = '0';     
   drawHomeScreen();  

   //подсчет среднеарифметического усредненного расхода
   for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
   for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
   L100SR_TFT = (float)L100SR_TFT/110.0;
   if (L100SR_TFT<0) L100SR_TFT = 0;
   if (L100SR_TFT>99) L100SR_TFT = 99;
   
   // строка ниже используется для настройки даты и времени часов 
   // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
   // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
   // (год, месяц, день, часы, минуты, секунды)
   //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

   Temperature ();
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
   
   curmillis = millis ();
   
      
// ниже шлём периодически запросы на PCM
if (curmillis - prevRequest > RequestPeriod && header == 0) {
  NOanswer_timer = 1; prev_NOanswer = curmillis;           //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов 
  if (request == INIT_bus) {PCM_K_LINE.end(); delay (450); fastinit();} 
  else                     {sendMessagePCM(request); if (request == INIT) {inits++; if(inits>5) request = INIT_bus, inits=0;}} // отправляем на PCM текущий запрос
  TX_otladka();    
  prevRequest = curmillis;
                                                             }


if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   GAUGE_K_LINE.begin(9600);}

   receive ();
   if (curmillis - prevWatch > 3000)  { Watch (); prevWatch = curmillis; Trip ();}
   //if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
   if (curmillis - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = curmillis; Dvoet=!Dvoet;}
   Menu();
   LCDDataPrint();}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (curmillis - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = curmillis; }}
 

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  GAUGE_K_LINE.write (0x02);    delay (1);
  GAUGE_K_LINE.write (0x11);    delay (1);
  GAUGE_K_LINE.write(byte(0));  delay (1);
  GAUGE_K_LINE.write (0x13); }
 
 
 
 
  void receive () {
 
  // работа с К-Line софт сериал 16-17 (12 контакт ОБД)


while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {delay (10); GAUGE_K_LINE.write (0x7F); }                                                  
  if (inByte==0xF0) {delay (10);                                                                                                   
    for (byte i=0; i< sizeof(PIDGauge); i++) {GAUGE_K_LINE.write (PIDGauge[i]);  delay (delaybyte_TX);}
    
    InitGauge=1; Serial.println("   Ura! Panel init proshla uspeshno!"); }}}
  
  if (InitGauge) {
  if (GAUGE_K_LINE.available()) {
  
  // ниже ищем шапку кадра 
     
     byte inbyte = GAUGE_K_LINE.read();
     delay (7);
         if (inbyte == 0x23 && head_count == 0) {head_count = 1; head[0] = inbyte; } 
    else if (inbyte == 0xA1 && head_count == 1) {head_count = 2; head[1] = inbyte; } 
    else if (inbyte == 0x04 && head_count == 2) {head_count = 3; head[2] = inbyte; } 
    else {head_count = 0; for (byte i=0; i<sizeof(head); i++) head[i] = 0;} 

    // нашли шапку: 
  
  if (head_count == 3){
    
    head_count = 0; // очищаем переменную поиска шапки 
    
     byte Length = head[0];
     if (Length>100)Length=100;
    
    const byte sizeMes = Length+2;
    
    byte MessageRx_GAUGE [sizeMes] = {0};
    uint16_t cRc = 0; 
    for (byte i=0; i<3; i++){MessageRx_GAUGE[i]= head[i]; cRc += MessageRx_GAUGE[i]; head[i] = 0; Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" ");}  // очищаем переменные поиска шапки 
    
    bool CRC_OK = 0;

    // ниже пишем сообщение в буфер и считаем КС
    for (byte i = 3; i < sizeMes; i++) { MessageRx_GAUGE[i] = GAUGE_K_LINE.read();  if (i<=sizeMes-3) cRc += MessageRx_GAUGE[i]; delay (7); Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" "); }
//   Serial.println();
    int CrC =  ( ( unsigned int )MessageRx_GAUGE [sizeMes-2] << 8 ) | MessageRx_GAUGE [sizeMes-1];
    if (CrC==cRc) CRC_OK = 1;

    if (CRC_OK){Serial.println (" OK!!!");} // конец ифа с правильной CRC  

    else  Serial.println("  CRC FAIL!!!");
  }   
 }
}


  /*
  while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {GAUGE_K_LINE.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    GAUGE_K_LINE.write (0x02);  delay (1);
    GAUGE_K_LINE.write (0x11);  delay (1);
    GAUGE_K_LINE.write (0x00);  delay (1);
    GAUGE_K_LINE.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (GAUGE_K_LINE.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (GAUGE_K_LINE.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (GAUGE_K_LINE.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (GAUGE_K_LINE.available()>0)  { MessageRxGauge[numberbyte] = GAUGE_K_LINE.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 //else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 //if (ZamerNumber==9) {
 //Fuel = 0 ;
 //for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 //Fuel = (float)Fuel/10.0;}
 //ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
//

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //GAUGE_K_LINE.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 
*/
   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
  
   
   if (PCM_K_LINE.available() ){
    
 // первый старт байт
 if (header == 0 && Delay){TIMER_DELAY ; buf[0]=PCM_K_LINE.read();  
         if (buf[0]!=0xFF && bitRead (buf[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; 
         Serial.print (buf[0], HEX);  Serial.print (" "); }}                  

 // второй старт байт
 if (header == 1 && Delay){TIMER_DELAY ; buf[1]=PCM_K_LINE.read(); Serial.print (buf[1], HEX);  Serial.print (" ");if (buf[1]==DIAG_address){ header = 2;} else {Serial.println("Message fail"); header = 0; RESETheader_timer = 0;}} 

 // третий старт байт
 if (header == 2 && Delay){ 
  TIMER_DELAY ;
  buf[2]=PCM_K_LINE.read(); Serial.print (buf[2], HEX);  Serial.print (" ");
  if (buf[2]==PCM_address){ message_size = buf[0]; 
  if (buf[0] !=0x80) {header = 4;  bitWrite (message_size, 7 , 0);j=3;n=3;}
  else {header = 3; j=4;n=4;}
  if (message_size > bufsize) message_size = bufsize;  crc = 0;} else {header = 0; Serial.println("Message fail"); RESETheader_timer = 0;}
  
                          }  
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay){
  TIMER_DELAY ;
  buf[3]=PCM_K_LINE.read(); Serial.print (buf[3], HEX);  Serial.print (" ");
  message_size = buf[3]; 
  if (message_size > bufsize) message_size = bufsize;  
  crc = 0; header = 4;  
                         }

  // пишем тело сообщения 
 if (header == 4 && Delay && j< message_size+n+1) {
 buf[j] = PCM_K_LINE.read(); 
 if (j<message_size+n) crc+= buf[j]; // подсчёт КС
 
 if (j==message_size+n) header = 5; 
 TIMER_DELAY ; Serial.print (buf[j], HEX);  Serial.print (" ");  j++;} 
 }

 // сообщение приняли, действуем
 if (header == 5) {TIMER_DELAY ;  
 Serial.println();  
 NOanswer_timer = 0; noanswers = 0;    // сбрасываем таймер контроля неответов 

for(byte i = 0; i<n; i++) crc+=buf[i]; // прибавляем к контрольной сумме старт байты

 // если контрольная сумма верна: 
if ( crc == buf[message_size+n]) 
{  
  Serial.println("Received message is OK! Checksum is correct!" );  // Если КС совпала, тут чёнибудь нужное делаем
    
          if (buf[n]==0xC1 && buf[n+1]==0x6B && buf[n+2]==0x8F) {if (currentPage!=3) pids(); else request = DTCREAD, RequestPeriod = 5000; Serial.println ("     Initialization OK!!!!:  "); }
 else if (buf[n]==0x58 && buf[n+1]==0x00) {Serial.println ("     NO DTC  ");}
 else if (buf[n]==0x58 && buf[n+1] >0x00) {Serial.println ("     DTC is found!");} 
 else if (buf[n]==0x54 && buf[n+1]==0xFF && buf[n+2]==0x00){ Serial.println ("     DTC CLEARED  "); request = DTCREAD; RequestPeriod = 5000;}
 else if (buf[n]==0x61 && buf[n+1]==0x01) {Serial.println ("     Receive DATA");}
  
 }   

// если контрольная сумма не совпала: 
else Serial.println("CRC fail!!!" );
message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0;
}

// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; 

// таймер сброса заголовка если данные оборвались во время приёма заголовка
if (RESETheader_timer && curmillis - prevRESETheader > 500) {Serial.println("Message fail timeout"); RESETheader_timer = 0; header = 0;}   
 
// если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит.  
if (NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/8) {NOanswer_timer = 0; noanswers++; 
     if (noanswers>=6) { noanswers = 0; request = INIT_bus;}         }
 
   
   
   
   
   
   /*
   
   if (PCM_K_LINE.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( PCM_K_LINE.available() && k < 110) {
   inbyte = PCM_K_LINE.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }// очистка байтов массива
     
*/     
     
     } // конец receive 
     
   

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация PCM на 7 пине ОБД (fast init - 25ms LOW 25ms HIGH)
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   PCM_K_LINE.begin(10400); // baud rate of the OBD
   request = INIT; RequestPeriod = 500;
   
   } 



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("INTER  C", 300, 145);
    myGLCD.print("EXTER  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';    
        pids(); // на PCM в этом окне посылается запрос текущих параметров       
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров      
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';  
       request = DTCREAD; RequestPeriod = 5000;  // на PCM в этом окне посылается запрос чтения ошибок  
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        request = DTCREAD; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок  
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
       request = DTCERASE; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок 
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }




void sendMessagePCM(const byte &command)
{
 
  byte size =  PCM_Message_TX[command][0];
  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] = PCM_address;
    if (i==2) Mes[i] = DIAG_address;    
    if (i==3) {for (byte t=1; t<size+1; t++ ) {
           Mes[i]=PCM_Message_TX [command][t]; 
           Checksum+=Mes[i] ; 
           PCM_K_LINE.write (Mes[i]); 
           delay (delaybyte_TX);  
           PCM_K_LINE.read(); 
           i++;}}
    if (i!=siZe-1) Checksum+=Mes[i];
    else Mes[i] = Checksum;    
    PCM_K_LINE.write (Mes[i]);
    delay (delaybyte_TX);
    PCM_K_LINE.read();
                             }
                     
}


 void TX_otladka(){
    
      if (request == INIT_bus) Serial.println ("Bus_INIT"); 
 else if (request == INIT)     Serial.println ("Otpravil zapros Init");
 else if (request == DTCREAD)  Serial.println ("Otpravil zapros DTC read");
 else if (request == DTCERASE) Serial.println ("Otpravil zapros DTC clear");
                   }

void pids(){request = PID; RequestPeriod = 50;}
 

Извени за напряги. Делай когда есть желание и свободное время. Я так и остался профаном в отличии от тебя. Спасибо

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

С делеями 1024 и 1030. А это :

sendMessagePCM(request); prevRequest = curmillis;
Вставить в 739

viki13viki
Offline
Зарегистрирован: 14.11.2016

сразу для оринтеровки скетч

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define GAUGE_K_LINE Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial PCM_K_LINE   (12, 13); //RХ,TХ
 #define PCM_address  0x11
 #define DIAG_address 0xF1
 
 //-------------------------- Переменные для бортовика
  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;            //мгновенный расход топлива литров в час
 float L100SR = 0;          //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;      // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 

//-------------------------- Переменные для обмена к-лайн приборки 
 
 bool InitGauge = 0;
 
 byte EndSession []= {0x02, 0xB2, 0x00, 0xB4};
 byte PIDGauge []=   {0x02, 0x11, 0x00, 0x13};
 byte head_count = 0;
 byte head[4] = {0};


//-------------------------- Переменные для обмена к-лайн PCM 

uint32_t curmillis = 0;      // снимок текущего времени 
 
 uint32_t prevRequest = 0;   // таймер периодических запросов
 int RequestPeriod = 50;    // периодичность запросов , мс
 
 uint32_t prevRESETheader=0; // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 bool RESETheader_timer;     // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 
 uint32_t prev_NOanswer=0;   // таймер контроля неответов от ЭБУ после запросов
 bool NOanswer_timer = 0;    // таймер контроля неответов от ЭБУ после запросов
 byte noanswers = 0;         // количество подряд неответов от ЭБУ 
 
 uint32_t timerdelay = 0;    // таймер ожидания байт (для успевания появления данных в буфере UART)
 bool Delay = 0;             // таймер ожидания байт (для успевания появления данных в буфере UART)
 byte waitbyte_RX = 1;       // задержка, мс для успевания появления данных в буфере RX 
                             // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) 
 #define TIMER_DELAY Delay = 0; timerdelay = curmillis  // включение этого таймера
  
 byte delaybyte_TX  = 1;     // задержка между отправкой байт в запросах, мс
byte inits = 0;              // количество инитов посланных на PCM
byte header = 0;          // состояние заголовка
byte message_size = 0;    // размер тела сообщения
byte j = 3;               // инкремент
byte n = 3;               // количество старт байт
const byte bufsize = 110; // размер буфера принятого сообщения
byte buf [bufsize] = {0}; // буфер принятого сообщения
byte crc =0;              // байт контрольной суммы 


// возможные варианты запросов на ЭБУ:
enum REQUEST {
 INIT,    
 PID,     
 DTCERASE,
 DTCREAD,
 PRESENT,
 INIT_bus};
 
 byte PCM_Message_TX[][5] = {
 {1,  0x81,           0,0,0},      // запрос инициализации
 {2,  0x21,0x01,        0,0},      // запрос пид 2101
 {3,  0x14,0xFF,0x00,     0},      // запрос на стирание ошибок
 {4,  0x18,0x00,0xFF,0x00  },      // запрос на чтение ошибок
 {1,  0x3E,           0,0,0},      // запрос присутствия 
                            };

 byte request = INIT;      // переменная, показывающая какой запрос будем делать
 
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   PCM_K_LINE.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
   currentPage = '0';     
   drawHomeScreen();  

   //подсчет среднеарифметического усредненного расхода
   for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
   for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
   L100SR_TFT = (float)L100SR_TFT/110.0;
   if (L100SR_TFT<0) L100SR_TFT = 0;
   if (L100SR_TFT>99) L100SR_TFT = 99;
   
   // строка ниже используется для настройки даты и времени часов 
   // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
   // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
   // (год, месяц, день, часы, минуты, секунды)
   //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

   Temperature ();
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
   
   curmillis = millis ();
   
      
// ниже шлём периодически запросы на PCM
if (curmillis - prevRequest > RequestPeriod && header == 0) {
  NOanswer_timer = 1; prev_NOanswer = curmillis;           //т.к. сейчас будем делать запрос, то запускаем таймер контроля неответов 
  if (request == INIT_bus) {PCM_K_LINE.end(); delay (450); fastinit();} 
  else                     {sendMessagePCM(request); if (request == INIT) {inits++; if(inits>5) request = INIT_bus, inits=0;}} // отправляем на PCM текущий запрос
  TX_otladka();    
  prevRequest = curmillis;
                                                             }


if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   GAUGE_K_LINE.begin(9600);}

   receive ();
   if (curmillis - prevWatch > 3000)  { Watch (); prevWatch = curmillis; Trip ();}
   //if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
   if (curmillis - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = curmillis; Dvoet=!Dvoet;}
   Menu();
   LCDDataPrint();}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //VOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (curmillis - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = curmillis; }}
 

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  GAUGE_K_LINE.write (0x02);    delay (1);
  GAUGE_K_LINE.write (0x11);    delay (1);
  GAUGE_K_LINE.write(byte(0));  delay (1);
  GAUGE_K_LINE.write (0x13); }
 
 
 
 
  void receive () {
 
  // работа с К-Line софт сериал 16-17 (12 контакт ОБД)


while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {delay (10); GAUGE_K_LINE.write (0x7F); }                                                  
  if (inByte==0xF0) {delay (10);                                                                                                   
    for (byte i=0; i< sizeof(PIDGauge); i++) {GAUGE_K_LINE.write (PIDGauge[i]);  delay (delaybyte_TX);}
    
    InitGauge=1; Serial.println("   Ura! Panel init proshla uspeshno!"); }}}
  
  if (InitGauge) {
  if (GAUGE_K_LINE.available()) {
  
  // ниже ищем шапку кадра 
     
     byte inbyte = GAUGE_K_LINE.read();
     delay (7);
         if (inbyte == 0x23 && head_count == 0) {head_count = 1; head[0] = inbyte; } 
    else if (inbyte == 0xA1 && head_count == 1) {head_count = 2; head[1] = inbyte; } 
    else if (inbyte == 0x04 && head_count == 2) {head_count = 3; head[2] = inbyte; } 
    else {head_count = 0; for (byte i=0; i<sizeof(head); i++) head[i] = 0;} 

    // нашли шапку: 
  
  if (head_count == 3){
    
    head_count = 0; // очищаем переменную поиска шапки 
    
     byte Length = head[0];
     if (Length>100)Length=100;
    
    const byte sizeMes = Length+2;
    
    byte MessageRx_GAUGE [sizeMes] = {0};
    uint16_t cRc = 0; 
    for (byte i=0; i<3; i++){MessageRx_GAUGE[i]= head[i]; cRc += MessageRx_GAUGE[i]; head[i] = 0; Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" ");}  // очищаем переменные поиска шапки 
    
    bool CRC_OK = 0;

    // ниже пишем сообщение в буфер и считаем КС
    for (byte i = 3; i < sizeMes; i++) { MessageRx_GAUGE[i] = GAUGE_K_LINE.read();  if (i<=sizeMes-3) cRc += MessageRx_GAUGE[i]; delay (7); Serial.print (MessageRx_GAUGE[i], HEX); Serial.print (" "); }
//   Serial.println();
    int CrC =  ( ( unsigned int )MessageRx_GAUGE [sizeMes-2] << 8 ) | MessageRx_GAUGE [sizeMes-1];
    if (CrC==cRc) CRC_OK = 1;

    if (CRC_OK){Serial.println (" OK!!!");} // конец ифа с правильной CRC  

    else  Serial.println("  CRC FAIL!!!");
  }   
 }
}


  /*
  while(!InitGauge){
   if (GAUGE_K_LINE.available()) {
   byte inByte = GAUGE_K_LINE.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {GAUGE_K_LINE.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    GAUGE_K_LINE.write (0x02);  delay (1);
    GAUGE_K_LINE.write (0x11);  delay (1);
    GAUGE_K_LINE.write (0x00);  delay (1);
    GAUGE_K_LINE.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (GAUGE_K_LINE.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (GAUGE_K_LINE.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (GAUGE_K_LINE.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (GAUGE_K_LINE.available()>0)  { MessageRxGauge[numberbyte] = GAUGE_K_LINE.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 //else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 //if (ZamerNumber==9) {
 //Fuel = 0 ;
 //for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 //Fuel = (float)Fuel/10.0;}
 //ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
//

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //GAUGE_K_LINE.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 
*/
   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
  
   
   if (PCM_K_LINE.available() ){
    
 // первый старт байт
 if (header == 0 && Delay){TIMER_DELAY ; buf[0]=PCM_K_LINE.read();  
         if (buf[0]!=0xFF && bitRead (buf[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; 
         Serial.print (buf[0], HEX);  Serial.print (" "); }}                  

 // второй старт байт
 if (header == 1 && Delay){TIMER_DELAY ; buf[1]=PCM_K_LINE.read(); Serial.print (buf[1], HEX);  Serial.print (" ");if (buf[1]==DIAG_address){ header = 2;} else {Serial.println("Message fail"); header = 0; RESETheader_timer = 0;}} 

 // третий старт байт
 if (header == 2 && Delay){ 
  TIMER_DELAY ;
  buf[2]=PCM_K_LINE.read(); Serial.print (buf[2], HEX);  Serial.print (" ");
  if (buf[2]==PCM_address){ message_size = buf[0]; 
  if (buf[0] !=0x80) {header = 4;  bitWrite (message_size, 7 , 0);j=3;n=3;}
  else {header = 3; j=4;n=4;}
  if (message_size > bufsize) message_size = bufsize;  crc = 0;} else {header = 0; Serial.println("Message fail"); RESETheader_timer = 0;}
  
                          }  
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay){
  TIMER_DELAY ;
  buf[3]=PCM_K_LINE.read(); Serial.print (buf[3], HEX);  Serial.print (" ");
  message_size = buf[3]; 
  if (message_size > bufsize) message_size = bufsize;  
  crc = 0; header = 4;  
                         }

  // пишем тело сообщения 
 if (header == 4 && Delay && j< message_size+n+1) {
 buf[j] = PCM_K_LINE.read(); 
 if (j<message_size+n) crc+= buf[j]; // подсчёт КС
 
 if (j==message_size+n) header = 5; 
 TIMER_DELAY ; Serial.print (buf[j], HEX);  Serial.print (" ");  j++;} 
 }

 // сообщение приняли, действуем
 if (header == 5) {TIMER_DELAY ;  
 Serial.println();  
 NOanswer_timer = 0; noanswers = 0;    // сбрасываем таймер контроля неответов 

for(byte i = 0; i<n; i++) crc+=buf[i]; // прибавляем к контрольной сумме старт байты

 // если контрольная сумма верна: 
if ( crc == buf[message_size+n]) 
{  
  Serial.println("Received message is OK! Checksum is correct!" );  // Если КС совпала, тут чёнибудь нужное делаем
    
          if (buf[n]==0xC1 && buf[n+1]==0x6B && buf[n+2]==0x8F) {if (currentPage!=3) pids(); else request = DTCREAD, RequestPeriod = 5000; Serial.println ("     Initialization OK!!!!:  "); }
 else if (buf[n]==0x58 && buf[n+1]==0x00) {Serial.println ("     NO DTC  ");}
 else if (buf[n]==0x58 && buf[n+1] >0x00) {Serial.println ("     DTC is found!");} 
 else if (buf[n]==0x54 && buf[n+1]==0xFF && buf[n+2]==0x00){ Serial.println ("     DTC CLEARED  "); request = DTCREAD; RequestPeriod = 5000;}
 else if (buf[n]==0x61 && buf[n+1]==0x01) {Serial.println ("     Receive DATA");}
  
 }   

// если контрольная сумма не совпала: 
else Serial.println("CRC fail!!!" );
message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0;
}

// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; 

// таймер сброса заголовка если данные оборвались во время приёма заголовка
if (RESETheader_timer && curmillis - prevRESETheader > 500) {Serial.println("Message fail timeout"); RESETheader_timer = 0; header = 0;}   
 
// если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит.  
if (NOanswer_timer && curmillis - prev_NOanswer > RequestPeriod - RequestPeriod/8) {NOanswer_timer = 0; noanswers++; 
     if (noanswers>=6) { noanswers = 0; request = INIT_bus;}         }
 
   
   
   
   
   
   /*
   
   if (PCM_K_LINE.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( PCM_K_LINE.available() && k < 110) {
   inbyte = PCM_K_LINE.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }// очистка байтов массива
     
*/     
     
     } // конец receive 
     
   

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация PCM на 7 пине ОБД (fast init - 25ms LOW 25ms HIGH)
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   PCM_K_LINE.begin(10400); // baud rate of the OBD
   request = INIT; RequestPeriod = 500;
   sendMessagePCM(request); prevRequest = curmillis;
   } 



//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("INTER  C", 300, 145);
    myGLCD.print("EXTER  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';    
        pids(); // на PCM в этом окне посылается запрос текущих параметров       
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';     
        pids(); // на PCM в этом окне посылается запрос текущих параметров      
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';  
       request = DTCREAD; RequestPeriod = 5000;  // на PCM в этом окне посылается запрос чтения ошибок  
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        request = DTCREAD; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос чтения ошибок  
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
       request = DTCERASE; RequestPeriod = 5000; // на PCM при нажатии этой кнопки посылается запрос удаления ошибок 
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }




void sendMessagePCM(const byte &command)
{
 
  byte size =  PCM_Message_TX[command][0];
  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] = PCM_address;
    if (i==2) Mes[i] = DIAG_address;    
    if (i==3) {for (byte t=1; t<size+1; t++ ) {
           Mes[i]=PCM_Message_TX [command][t]; 
           Checksum+=Mes[i] ; 
           PCM_K_LINE.write (Mes[i]); 
           if (request == INIT) delay (5); else delay (delaybyte_TX);  
           PCM_K_LINE.read(); 
           i++;}}
    if (i!=siZe-1) Checksum+=Mes[i];
    else Mes[i] = Checksum;    
    PCM_K_LINE.write (Mes[i]);
    if (request == INIT) delay (5); else delay (delaybyte_TX);
    PCM_K_LINE.read();
                             }
                     
}


 void TX_otladka(){
    
      if (request == INIT_bus) Serial.println ("Bus_INIT"); 
 else if (request == INIT)     Serial.println ("Otpravil zapros Init");
 else if (request == DTCREAD)  Serial.println ("Otpravil zapros DTC read");
 else if (request == DTCERASE) Serial.println ("Otpravil zapros DTC clear");
                   }

void pids(){request = PID; RequestPeriod = 50;}
 

а вот вывод монитора

Otpravil zapros Init
Otpravil zapros adress Gauge
 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0   Ura! Panel init proshla uspeshno!
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
83 Message fail timeout
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
Otpravil zapros Init
Otpravil zapros Init
8F Message fail timeout
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Bus_INIT
Otpravil zapros Init
Otpravil zapros Init
8F Message fail timeout
Otpravil zapros Init

 

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

короче надо заново, сначала с PCM разобраться без лишнего. 

#include <SoftwareSerial.h>
 #define TX_PCM 13
 SoftwareSerial K_LINE_PCM   (12, TX_PCM); //RХ,TХ

#define PCM_address  0x11
#define DIAG_address 0xF1

 bool Init = 0;
 uint32_t curmillis = 0;
 uint32_t prev  = 0;
 

uint32_t prevRESETheader=0; // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 bool RESETheader_timer;     // таймер сброса заголовка если в момент приёма заголовка данные оборвались
 
 uint32_t prev_NOanswer=0;   // таймер контроля неответов от ЭБУ после запросов
 bool NOanswer_timer = 0;    // таймер контроля неответов от ЭБУ после запросов
 byte noanswers = 0;         // количество подряд неответов от ЭБУ 
 
 uint32_t timerdelay = 0;    // таймер ожидания байт (для успевания появления данных в буфере UART)
 bool Delay = 0;             // таймер ожидания байт (для успевания появления данных в буфере UART)
 byte waitbyte_RX = 1;       // задержка, мс для успевания появления данных в буфере RX 
                             // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) 
 #define TIMER_DELAY Delay = 0; timerdelay = curmillis  // включение этого таймера
  
byte delaybyte_TX  = 1;   // задержка между отправкой байт в запросах, мс
byte inits = 0;           // количество инитов посланных на PCM
byte header = 0;          // состояние заголовка
byte message_size = 0;    // размер тела сообщения
byte j = 3;               // инкремент
byte n = 3;               // количество старт байт
const byte bufsize = 110; // размер буфера принятого сообщения
byte buf [bufsize] = {0}; // буфер принятого сообщения
byte crc =0;              // байт контрольной суммы 

  
 byte messageInit[] =    {0x81, 0x11, 0xF1, 0x81, 0x04};            // запрос инициализации

// возможные варианты запросов на ЭБУ:
enum REQUEST {
 INIT,    
 PID,     
 DTCERASE,
 DTCREAD,
 PRESENT,
 INIT_bus};
 
 byte PCM_Message_TX[][5] = {
 {1,  0x81,           0,0,0},      // запрос инициализации
 {2,  0x21,0x01,        0,0},      // запрос пид 2101
 {3,  0x14,0xFF,0x00,     0},      // запрос на стирание ошибок
 {4,  0x18,0x00,0xFF,0x00  },      // запрос на чтение ошибок
 {1,  0x3E,           0,0,0},      // запрос присутствия 
                            };

 
   void setup() {
    
   Serial.begin(115200);
   K_LINE_PCM.begin(10400);
   pinMode(TX_PCM, OUTPUT);
   fastinit();
                }


    void loop() 
                {
curmillis = millis();
      
if (curmillis - prev > 500) { if (!Init) initialization(); else sendMessagePCM (PID); prev = curmillis;  }

receive ();
                }


 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (byte i = 0; i < sizeof (messageInit); i++) {
   K_LINE_PCM.write(messageInit[i]);
   delay (5); } 
   delay (55); }

 
 void fastinit() {
   digitalWrite (TX_PCM, HIGH);  
   delay(360);             
   digitalWrite (TX_PCM, LOW);  
   delay(25);
   digitalWrite (TX_PCM, HIGH); 
   delay(25);               
   K_LINE_PCM.begin(10400); } 
 
 
void receive () {

 if (K_LINE_PCM.available() ){
    
 // первый старт байт
 if (header == 0 && Delay){TIMER_DELAY ; buf[0]=K_LINE_PCM.read();  
         if (buf[0]!=0xFF && bitRead (buf[0],7)){header = 1; RESETheader_timer = 1; prevRESETheader = curmillis; 
         Serial.print (buf[0], HEX);  Serial.print (" "); }}                  

 // второй старт байт
 if (header == 1 && Delay){TIMER_DELAY ; buf[1]=K_LINE_PCM.read(); Serial.print (buf[1], HEX);  Serial.print (" ");if (buf[1]==DIAG_address){ header = 2;} else {Serial.println("Message fail"); header = 0; RESETheader_timer = 0;}} 

 // третий старт байт
 if (header == 2 && Delay){ 
  TIMER_DELAY ;
  buf[2]=K_LINE_PCM.read(); Serial.print (buf[2], HEX);  Serial.print (" ");
  if (buf[2]==PCM_address){ message_size = buf[0]; 
  if (buf[0] !=0x80) {header = 4;  bitWrite (message_size, 7 , 0);j=3;n=3;}
  else {header = 3; j=4;n=4;}
  if (message_size > bufsize) message_size = bufsize;  crc = 0;} else {header = 0; Serial.println("Message fail"); RESETheader_timer = 0;}
  
                          }  
// если размер сообщения указан в дополнительном байте (нулевой байт 0x80) читаем этот дополнительный байт:
if (header == 3 && Delay){
  TIMER_DELAY ;
  buf[3]=K_LINE_PCM.read(); Serial.print (buf[3], HEX);  Serial.print (" ");
  message_size = buf[3]; 
  if (message_size > bufsize) message_size = bufsize;  
  crc = 0; header = 4;  
                         }

  // пишем тело сообщения 
 if (header == 4 && Delay && j< message_size+n+1) {
 buf[j] = K_LINE_PCM.read(); 
 if (j<message_size+n) crc+= buf[j]; // подсчёт КС
 
 if (j==message_size+n) header = 5; 
 TIMER_DELAY ; Serial.print (buf[j], HEX);  Serial.print (" ");  j++;} 
 }

 // сообщение приняли, действуем
 if (header == 5) {TIMER_DELAY ;  
 Serial.println();  
 NOanswer_timer = 0; noanswers = 0;    // сбрасываем таймер контроля неответов 

for(byte i = 0; i<n; i++) crc+=buf[i]; // прибавляем к контрольной сумме старт байты

 // если контрольная сумма верна: 
if ( crc == buf[message_size+n]) 
{  
  Serial.println("Received message is OK! Checksum is correct!" );  // Если КС совпала, тут чёнибудь нужное делаем
    
          if (buf[n]==0xC1 && buf[n+1]==0x6B && buf[n+2]==0x8F) {Serial.println ("     Initialization OK!!!!:  "); Init = 1; }
 else if (buf[n]==0x58 && buf[n+1]==0x00) {Serial.println ("     NO DTC  ");}
 else if (buf[n]==0x58 && buf[n+1] >0x00) {Serial.println ("     DTC is found!");} 
 else if (buf[n]==0x54 && buf[n+1]==0xFF && buf[n+2]==0x00){ Serial.println ("     DTC CLEARED  ");}
 else if (buf[n]==0x61 && buf[n+1]==0x01) {Serial.println ("     Receive DATA");}
  
 }   

// если контрольная сумма не совпала: 
else Serial.println("CRC fail!!!" );
message_size = 0; header=0; RESETheader_timer = 0; j=3; crc = 0;
}

// таймер ожидания байт (для успевания появления данных в буфере UART)
if (!Delay && curmillis - timerdelay > waitbyte_RX) Delay = 1; 

// таймер сброса заголовка если данные оборвались во время приёма заголовка
if (RESETheader_timer && curmillis - prevRESETheader > 500) {Serial.println("Message fail timeout"); RESETheader_timer = 0; header = 0;}   
 
// если нет ответа после запроса: +1 к счетчику неответов. Если накопилось 6 и более: делаем реинит.  
if (NOanswer_timer && curmillis - prev_NOanswer > 400) {NOanswer_timer = 0; noanswers++; 
     if (noanswers>=6) { noanswers = 0; }         }
}

 
 
 void sendMessagePCM(const byte &command)
{
 
  byte size =  PCM_Message_TX[command][0];
  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] = PCM_address;
    if (i==2) Mes[i] = DIAG_address;    
    if (i==3) {for (byte t=1; t<size+1; t++ ) {
           Mes[i]=PCM_Message_TX [command][t]; 
           Checksum+=Mes[i] ; 
           K_LINE_PCM.write (Mes[i]); 
           delay (delaybyte_TX);  
           K_LINE_PCM.read(); 
           i++;}}
    if (i!=siZe-1) Checksum+=Mes[i];
    else Mes[i] = Checksum;    
    K_LINE_PCM.write (Mes[i]);
    delay (delaybyte_TX);
    K_LINE_PCM.read();
                             }
}

 

viki13viki
Offline
Зарегистрирован: 14.11.2016
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
Otpravil zapros Init
распечатывает без остановки
MaksVV
Offline
Зарегистрирован: 06.08.2015

так...,  вечером полностью твою рабочую логику вставлю, только уберу лишнее, нужно понять на каком моменте ему не нравится. 

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

убран экран  и датчики 




 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 bool InitGauge = 0;
 bool dataMessageOK=0;
 bool dataMessageEND = 0;
 bool MessageParse = 0;
 bool byte0 = 0;
 bool byte1 = 0;
 bool byte2 = 0; 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 

   void setup() 
   {
  
   
   Serial.begin(115200);
   mySerial.begin(10400);
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
   }



  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
           else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else {if (millis() - prevPID > PIDTime) { PIDs();  prevPID = millis(); }} //  шлем запрос пид2101  
      
if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   mySerial_gauge.begin(9600);}

   receive ();
  }
 


 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}


 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  mySerial_gauge.write (0x02);    delay (1);
  mySerial_gauge.write (0x11);    delay (1);
  mySerial_gauge.write(byte(0));  delay (1);
  mySerial_gauge.write (0x13); }
 

 void present() {
  Serial.println ("Otpravil zapros Present");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messagePresent[i]);
   delay (waitbyte); }}
 
 
  void receive () {
 
  //----------------------------------------работа с К-Line софт (Serial2 16-17 (12 контакт ОБД))
  
  while(!InitGauge){
   if (mySerial_gauge.available()) {
   byte inByte = mySerial_gauge.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    mySerial_gauge.write (0x02);  delay (1);
    mySerial_gauge.write (0x11);  delay (1);
    mySerial_gauge.write (0x00);  delay (1);
    mySerial_gauge.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (mySerial_gauge.available()>0)  { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 if (ZamerNumber==9) {
 Fuel = 0 ;
 for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 Fuel = (float)Fuel/10.0;}
 ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
*/

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 


//----------------------------------------конец опроса данных от щитка (Serial2 16-17 (12 контакт ОБД))


  
//----------------------------------------работа с К-Line софт сериал 12-13 (7 контакт ОБД)
 
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

//  if (currentPage == '3'){

 
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
 //   myGLCD.clrScr();             
 //   drawscreen_three();      
 //   myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
 //   myGLCD.clrScr();             
 //   drawscreen_three();      
 //   myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
 //    myGLCD.clrScr();             
 //    drawscreen_three();       
  }
/*  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  */
 
  
  // прописываем формулы к данным  
  
    else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; } // очистка байтов массива


  }          //---------------------------конец receive ()
  
   

 
 //отправка запроса на диагностическое соединение
 
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }

 
 //стартовая инициализация 7 пина ОБД
 
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 
 //запрос чтения и стирания ошибок
 
 
 void Read() {
   Serial.println ("Zapros error;  ");
   for (int i = 0; i < length8; i++) {
   mySerial.write(messageREAD[i]);
   delay (waitbyte); }}
   
 void Erase() {
   Serial.println ("Zapros erase;  ");
   for (int i = 0; i < length7; i++) {
   mySerial.write(messageERASE[i]);
   delay (waitbyte); }}
viki13viki
Offline
Зарегистрирован: 14.11.2016

я тут ща проверю

viki13viki
Offline
Зарегистрирован: 14.11.2016

отчет

Otpravil zapros Init
Otpravil zapros adress Gauge
 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Receive:   0 FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 3F 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 3F 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 41 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 41 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!

 

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

как так , с ДВС не соединяется . Где косяк то . Все тоже самое, ну убрал малёха лишнего.  Тот 1410 скетч точно рабочий? 

viki13viki
Offline
Зарегистрирован: 14.11.2016

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

 

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

ну блин ЭБУ ДВС то ведь отвечает как никак. А тут чето FF FF  и всё. Может вместо убранного кода delay добавить. Этот код ведь время занимает, может оно и нужно. 

добавь в лупе после receive ()

delay (10) поиграйся этой задержкой. Также попробуй в сетапе до и после fastinnit() задержки повставлять

viki13viki
Offline
Зарегистрирован: 14.11.2016

отчет

задержки до и после и вместе после и до fastinit(); ничего не меняют
Задиержки после receive (); 
без задржки...................................

Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
.................................................
delay (10)

Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 79     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 41 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5C 1A 46 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 41 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
...................................................
delay (50)

Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!

........................................................
delay (100)

Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 0 7D 23 A1 4 0 0 0 0 0 0     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E    
...........................................................
с задержкой delay (11) сообзение с ошибкой выравнивается по длинне но иногда сново дает короче ответ

Otpravil zapros Init
Otpravil zapros adress Gauge
 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 53 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 73     OK!!!
Receive:   0 FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 53 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 71     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 54 1A 46 0 0 0 23 A1 4 0 0 0 0 0 0 0 0     ERROR!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 56 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 74     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 57 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 76     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 58 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 77     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 58 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 77     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 58 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 76     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 59 1A 46 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 59     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 59 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 77     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5A 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 78     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 3F 5E 5A 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 77     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5A 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 78     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5A 1A 46 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5A     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5B 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5B 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5B 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 79     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5C 1A 46 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5C 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5C 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5C 1A 47 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5C 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 3F 5E 5D 1A 47 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Receive:   FF FF 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 3F 5E 5D 1A 47 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D     ERROR!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!

 

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

ты не смотри на байты от панели, там всё гуд. Нас интересуют байты Receive: B вот тут ответа от PCM так  и нет. Либо фастинит коряво прошёл (25мс low 25 ms high) либо сообщение инита (81 11 F1 81 04)   ему почемуто не нравится. 

viki13viki
Offline
Зарегистрирован: 14.11.2016

ща попробую фаст задержки поиграть

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

и закоменти в  сетапе mySerial.begin (10400)

viki13viki
Offline
Зарегистрирован: 14.11.2016

без результатно

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

да как так? залей старый скетч #103 только поправь на свои пины софт сериал

viki13viki
Offline
Зарегистрирован: 14.11.2016

вот

starting comunication (fastinit)
starting serial comunication
Transmit fast init:   8111F1814
FAST INIT OK

Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF FF FF 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros Temp:   82  11  F1  1  5  8A         250ms
                                                            Recieve:   FF FF FF 0 0 0 0 0 0 0 0 0
Zapros prisutstviya:   81  11  F1  3E  C1         5000ms

 

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

эмм я теперь читай как у тебя на этот скетч был ответ в 131 сообщении. Чёто не сходится

viki13viki
Offline
Зарегистрирован: 14.11.2016

ща пересмотрю може т чет упустил. да вроде все норм.... че могло изменится? да уж.....

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

пины 12 13 софтсериала прописал? 

viki13viki
Offline
Зарегистрирован: 14.11.2016

да конечно. смотри только что залил рабочий скетсч этот

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 bool InitGauge = 0;
 bool dataMessageOK=0;
 bool dataMessageEND = 0;
 bool MessageParse = 0;
 bool byte0 = 0;
 bool byte1 = 0;
 bool byte2 = 0; 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   mySerial.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
   currentPage = '0';       
   drawHomeScreen();  

   //подсчет среднеарифметического усредненного расхода
   for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
   for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
   L100SR_TFT = (float)L100SR_TFT/110.0;
   if (L100SR_TFT<0) L100SR_TFT = 0;
   if (L100SR_TFT>99) L100SR_TFT = 99;
   
   // строка ниже используется для настройки даты и времени часов 
   // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
   // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
   // (год, месяц, день, часы, минуты, секунды)
   //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

   Temperature ();
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
   else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else { if (currentPage != '3'){ // если открыта страница 0,1 или 2 шлем запрос пид2101, если страница 3 -  шлем запрос присутствия 
   if (millis() - prevPID > PIDTime) { PIDs();  prevPID = millis(); }}
   else if (millis() - prevpres > PresTime) {present(); prevpres = millis();}}  
      
if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   mySerial_gauge.begin(9600);}

   receive ();
   if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); Trip ();}
   if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
   if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
   Menu();
   LCDDataPrint();}

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (millis() - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = millis(); }}
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDs//отправка запроса пид 2101/////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  mySerial_gauge.write (0x02);    delay (1);
  mySerial_gauge.write (0x11);    delay (1);
  mySerial_gauge.write(byte(0));  delay (1);
  mySerial_gauge.write (0x13); }
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса присутствия/////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void present() {
  Serial.println ("Otpravil zapros Present");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messagePresent[i]);
   delay (waitbyte); }}
 
 /////////////////////////////////////////////////////////////////////////////////////////////
 //получение данных от ЭБУ, разборка входящих сообщений
 /////////////////////////////////////////////////////////////////////////////////////////////
  void receive () {
  ///////////////////////////////////////////////////////////////////////
  ////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД)
  ///////////////////////////////////////////////////////////////////////
  while(!InitGauge){
   if (mySerial_gauge.available()) {
   byte inByte = mySerial_gauge.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    mySerial_gauge.write (0x02);  delay (1);
    mySerial_gauge.write (0x11);  delay (1);
    mySerial_gauge.write (0x00);  delay (1);
    mySerial_gauge.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (mySerial_gauge.available()>0)  { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 if (ZamerNumber==9) {
 Fuel = 0 ;
 for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 Fuel = (float)Fuel/10.0;}
 ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}
*/

  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 

   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //отправка запроса на диагностическое соединение
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация 7 пина ОБД
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 //запрос чтения и стирания ошибок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void Read() {
   Serial.println ("Zapros error;  ");
   for (int i = 0; i < length8; i++) {
   mySerial.write(messageREAD[i]);
   delay (waitbyte); }}
   
 void Erase() {
   Serial.println ("Zapros erase;  ");
   for (int i = 0; i < length7; i++) {
   mySerial.write(messageERASE[i]);
   delay (waitbyte); }}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("DENTR  C", 300, 145);
    myGLCD.print("FUERA  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';           
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        Read();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        Erase();
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }

все работает. вот отчет и он к стати тоже имеет ошибку

Otpravil zapros Init
Otpravil zapros adress Gauge
 55 52 80 7F 2D A0 48 54 20 32 34 34 31 39 35 36 30 20 31 34 30 30 20 34 31 39 39 20 31 33 30 31 20 30 34 32 20 31 20 30 30 30 30 30 30 30 30 30 30 8 F0                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5C 1A 46 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7B     OK!!!
Receive:   0 FF FF 83 F1 11 C1 6B 8F 40 
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 40 5E 5C 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Otpravil zapros Init
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5C 1A 47 0 0 0 B7 FF 5E 1A 47 0 0 0 3 14 4E     ERROR!!!
Receive:   FF FF 83 F1 11 C1 6B 8F 40 
     Initialization OK!!!!:  
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B5 0 FF 40 5E 5D 1A 47 0 0 0 3 47 0 0 0 3 14 4E 78 4 92     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 44 0 0 C 24 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 6D 0 0 0 0 9 48 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 5D 23 A1 4 0 0 0 0 0 0 0 0 0 0 4 10 B8     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 44 0 0 C 24 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 6D 0 0 0 0 9 48 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 44 0 0 C 25 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 71 0 0 0 0 9 48 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 7C 23 A1 4 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 45 0 0 C 25 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 47 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5E 40 5D 47 0 0 3 14 4E 78 4 92 1B 0 0 5 7D 23     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 44 0 0 C 25 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 6D 0 0 0 0 9 48 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 4 92 1B 0 0 5 7C 23 A1 4 0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 45 0 0 C 25 0 0 2 5B 0 0 0 0 4 37 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F AF 0 0 0 0 9 47 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7C     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 45 0 0 C 25 0 0 2 5B 0 0 0 0 4 33 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 6F 0 0 0 0 9 47 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B9 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7D     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 45 0 0 C 25 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 6D 0 0 0 0 9 47 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B7 0 FF 40 5E 5D 1A 47 0 0 0 4 B6 FF 5E 5D 1A 47 0 0 0 3     ERROR!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 45 0 0 C 24 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 6D 0 0 0 0 9 48 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B8 0 FF 40 5F 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7E     OK!!!
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 45 0 0 C 25 0 0 2 5B 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 6F 0 0 0 0 9 47 0 0 C 4D 
Otpravil zapros 21 01
                         ReceiveGauge:   0 0 0 0 0 0 0 0 0 0 4 10 B6 0 FF 3F 5E 5D 1A 47 0 0 0 3 14 4E 78 4 92 1B 0 0 5 7A     OK!!!
Receive:   0 0 0 0 0 0 0 0 0 0 
Otpravil zapros 21 01

по ходу изза обибок он так тупо и медленно выводит инфу. блин я не думаю что это изза того что я щас компилю на версии 1.8 а раньше на 1.6.........

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

какую ошибку. ERROR? дак это просто контрольная сумма от щитка когда не совпадает, это пофиг. Нам важна строка Initialization OK!!! Вот на том проверочном этот инит не идёт

viki13viki
Offline
Зарегистрирован: 14.11.2016

позабывал уже все

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

ну хорошо будем из рабочего вырезать по очереди. 

пока так

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
// #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 bool InitGauge = 0;
 bool dataMessageOK=0;
 bool dataMessageEND = 0;
 bool MessageParse = 0;
 bool byte0 = 0;
 bool byte1 = 0;
 bool byte2 = 0; 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   mySerial.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
  // myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
   currentPage = '0';       
   drawHomeScreen();  

   
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
   else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else { if (currentPage != '3'){ // если открыта страница 0,1 или 2 шлем запрос пид2101, если страница 3 -  шлем запрос присутствия 
   if (millis() - prevPID > PIDTime) { PIDs();  prevPID = millis(); }}
   else if (millis() - prevpres > PresTime) {present(); prevpres = millis();}}  
      
if (!InitGauge) {Serial.println ("Otpravil zapros adress Gauge");
    
   digitalWrite (TX_gauge, HIGH);  delay (500); 
   digitalWrite (TX_gauge, LOW);   delay (20);
   digitalWrite (TX_gauge, HIGH ); delay (15);
   digitalWrite (TX_gauge, LOW);   delay (5);
   digitalWrite (TX_gauge, HIGH);  delay (5);
   mySerial_gauge.begin(9600);}

   receive ();
  // if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); Trip ();}
  // if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
  // if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 290, 5);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
  // Menu();
  // LCDDataPrint();
  }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (millis() - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = millis(); }}
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDs//отправка запроса пид 2101/////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  mySerial_gauge.write (0x02);    delay (1);
  mySerial_gauge.write (0x11);    delay (1);
  mySerial_gauge.write(byte(0));  delay (1);
  mySerial_gauge.write (0x13); }
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса присутствия/////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void present() {
  Serial.println ("Otpravil zapros Present");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messagePresent[i]);
   delay (waitbyte); }}
 
 /////////////////////////////////////////////////////////////////////////////////////////////
 //получение данных от ЭБУ, разборка входящих сообщений
 /////////////////////////////////////////////////////////////////////////////////////////////
  void receive () {
  ///////////////////////////////////////////////////////////////////////
  ////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД)
  ///////////////////////////////////////////////////////////////////////
 /* while(!InitGauge){
   if (mySerial_gauge.available()) {
   byte inByte = mySerial_gauge.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    mySerial_gauge.write (0x02);  delay (1);
    mySerial_gauge.write (0x11);  delay (1);
    mySerial_gauge.write (0x00);  delay (1);
    mySerial_gauge.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (mySerial_gauge.available()>0)  { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 if (ZamerNumber==9) {
 Fuel = 0 ;
 for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 Fuel = (float)Fuel/10.0;}
 ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}


  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 
*/
   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //отправка запроса на диагностическое соединение
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация 7 пина ОБД
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 //запрос чтения и стирания ошибок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void Read() {
   Serial.println ("Zapros error;  ");
   for (int i = 0; i < length8; i++) {
   mySerial.write(messageREAD[i]);
   delay (waitbyte); }}
   
 void Erase() {
   Serial.println ("Zapros erase;  ");
   for (int i = 0; i < length7; i++) {
   mySerial.write(messageERASE[i]);
   delay (waitbyte); }}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("DENTR  C", 300, 145);
    myGLCD.print("FUERA  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';           
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        Read();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        Erase();
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }

 

viki13viki
Offline
Зарегистрирован: 14.11.2016

отчет

Otpravil zapros Init
Otpravil zapros adress Gauge
Receive:   0 FF FF 83 F1 11 C1 6B 8F 40 
Otpravil zapros adress Gauge
Otpravil zapros Init
Otpravil zapros adress Gauge
Receive:   FF FF 83 F1 11 C1 6B 8F 40 
     Initialization OK!!!!:  
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3D 0 0 C 20 0 0 2 43 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 26 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 20 0 0 2 43 0 0 0 0 4 37 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 28 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 21 0 0 2 43 0 0 0 0 4 36 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 28 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 21 0 0 2 44 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 26 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 20 0 0 2 44 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 28 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 20 0 0 2 44 0 0 0 0 4 38 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 28 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 20 0 0 2 45 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 28 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3B 0 0 C 20 0 0 2 45 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 26 0 0 0 0 9 4D 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 21 0 0 2 45 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 26 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 21 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 21 0 0 2 46 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2A 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 21 0 0 2 46 0 0 0 0 4 35 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 20 0 0 2 48 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 28 0 0 0 0 9 4B 0 0 C 40 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 3D 0 0 C 21 0 0 2 55 0 0 0 0 4 37 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3E 0 0 C 20 0 0 2 56 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4B 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3D 0 0 C 21 0 0 2 57 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 30 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3D 0 0 C 20 0 0 2 58 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3D 0 0 C 21 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 30 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3D 0 0 C 20 0 0 2 59 0 0 0 0 4 33 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3D 0 0 C 20 0 0 2 59 0 0 0 0 4 36 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2F 0 0 0 0 9 4C 0 0 C 43 
Otpravil zapros 21 01
Otpravil zapros adress Gauge

один раз зашил, хотел второй раз вылетает ошибка 

exit status 1
Ошибка компиляции для платы Arduino/Genuino Mega or Mega 2560.
MaksVV
Offline
Зарегистрирован: 06.08.2015

тааак идём дальше

viki13viki
Offline
Зарегистрирован: 14.11.2016

конечно

 

MaksVV
Offline
Зарегистрирован: 06.08.2015
/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
// #include "Fonts/Gobold_Bold14pt7b.h";
 
 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 22   
 OneWire oneWire(ONE_WIRE_BUS);
 #include <DallasTemperature.h>
 DallasTemperature sensors(&oneWire);
 
 //датчик внутринней температуры и влаги
 #include "DHT.h"
 #define DHTPIN 26   
 #define DHTTYPE DHT22 
 DHT dht(DHTPIN, DHTTYPE);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 bool InitGauge = 0;
 bool dataMessageOK=0;
 bool dataMessageEND = 0;
 bool MessageParse = 0;
 bool byte0 = 0;
 bool byte1 = 0;
 bool byte2 = 0; 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {
   uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);  
   
   Serial.begin(115200);
   mySerial.begin(10400);
//   Wire.begin();
//   rtc.begin();
//   dht.begin();
//   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
  // myGLCD.setFont(&Gobold_Bold14pt7b); 
   
   //загрузка стартовой страницы
  // currentPage = '0';       
  // drawHomeScreen();  

   
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP FIN
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //LOOP
 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
   else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else { if (currentPage != '3'){ // если открыта страница 0,1 или 2 шлем запрос пид2101, если страница 3 -  шлем запрос присутствия 
   if (millis() - prevPID > PIDTime) { PIDs();  prevPID = millis(); }}
   else if (millis() - prevpres > PresTime) {present(); prevpres = millis();}}  
      
   receive ();
  
  }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID TRIP//////////////////////////////////////////////////////////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Trip () {
 
 if (flagkmAgeIGN){

 FuelTrip = FuelIGN - Fuel;                          
  if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
  if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
  if (kmAge==kmAgeIGN) kmTrip = 0;
 
 //подсчет расхода на 100км за поездку
 L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
  if (L100M<0) L100M = 0;
  if (L100M>99) L100M = 99;

 // ниже цикл считает среднеарифметический расход из еепром раз в пробег, указанный в переменной kmeeprom
  if (kmTrip-kmTFT>kmeeprom) {kmTFT = kmTrip; 

 // тут считаем среднеарифметический усредненного расход из ячеек еепром 
  for (int i = 0; i < 11; i++) L100_Eeprom [i]= EEPROM.read(i);
  for (int i = 0; i < 11; i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
  L100SR_TFT = (float)L100SR_TFT/110.00;
  if (L100SR_TFT<0) L100SR_TFT = 0;
  if (L100SR_TFT>99) L100SR_TFT = 99;}
 
 // ниже цикл считает расход топлива за пробег, указанный в переменной kmL, здесь же запись в ячейки еепром 
  if (kmTrip-km>kmL) {km=kmTrip; 

 L100SR = ((float)(Fuel_last-Fuel)*100.00)/(float)kmL; // расход/100км  - обновляется раз в 10км, меняется км в int kmL = 10;
 Fuel_last = Fuel;      // сохранение параметров с последнего измерениея 
  if (L100SR<0) L100SR = 0;
  if (L100SR>99) L100SR = 99;

 //расчет остатка километров в баке
 if (L100SR>0) kmREFUELING=((float)Fuel*100.0)/(float)L100SR; //если средний расход больше нуля, то расчитывать км в баке из него
 else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;    //если ноль или ментше то расчитывать км в баке с устредненного расхода

 // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
 //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
 n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
 EEPROM.write(n_eeprom, L100SR*10); 
 n_eeprom++; if (n_eeprom>10) n_eeprom=0;
 EEPROM.write (12,n_eeprom); }}}
 
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
 //BOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
 /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void LCDDataPrint(){
   unsigned long curData = millis();  
     
  if (millis() - prevData > Datadelay){  
     myGLCD.setColor(255, 255, 255);      //цвет текста
     myGLCD.printNumI(Speed, 350, 7, 3);
  //----------------------------------------------------------
  //страниц HOME
  //----------------------------------------------------------
  if (currentPage == '0') {
     myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
     myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
     myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
     myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
     myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
     //if (Fuel<53) 
     myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
     //else myGLCD.print("MAX", 210, 110); 
     myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
     myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
     myGLCD.printNumI(PumpRPM, 210, 180,5);
     myGLCD.printNumI(RPM, 210, 215,5);
     myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
     myGLCD.printNumI(Temp, 415, 40, 3);
     myGLCD.printNumI(TempOil, 415, 75, 3);
     myGLCD.printNumI(TempFuel, 415, 110,3); 
     myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
     myGLCD.printNumI(t, 415, 180, 3);
     myGLCD.printNumI(TempAir, 415, 215, 3); }
   //----------------------------------------------------------
   //страниц INF1
   //----------------------------------------------------------
   if (currentPage == '1') {
     myGLCD.printNumF(StaDaliv,1, 360, 40,'.', 3);
     myGLCD.printNumF(DesInj,1, 395, 75, '.', 4);
     myGLCD.printNumF(ActInj,1, 395, 110,'.', 4); 
     myGLCD.printNumF(DesaInjQua,1, 395, 145,'.', 4);  
     myGLCD.printNumF(InjQua,1, 395, 180,'.', 4); 
     myGLCD.printNumI(MAF, 170, 215, 4);
     myGLCD.printNumF(h, 1, 418, 215); }
   //----------------------------------------------------------
   //страниц INF2
   //----------------------------------------------------------
   if (currentPage == '2') {    
     myGLCD.printNumF(BoostPres,1, 395, 40,'.', 4);  
     myGLCD.printNumF(BoostPresCom,1, 395, 75,'.', 4); 
     myGLCD.printNumI(EGRmg, 395, 110, 4);  
     myGLCD.printNumF(EGRPul,1, 410, 145,'.', 3);  
     myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
     myGLCD.printNumF(SolenPre, 0, 410, 215,'.', 3); }
    prevData = millis(); }}
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDs//отправка запроса пид 2101/////////////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}

 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void PIDsGauge() {
  Serial.println ("                Otpravil zapros 02 11 na panel");
  mySerial_gauge.write (0x02);    delay (1);
  mySerial_gauge.write (0x11);    delay (1);
  mySerial_gauge.write(byte(0));  delay (1);
  mySerial_gauge.write (0x13); }
 
 ///////////////////////////////////////////////////////////////////////////
 //BOID PIDsGAUGR//отправка запроса присутствия/////////////////////////////
 ///////////////////////////////////////////////////////////////////////////
 void present() {
  Serial.println ("Otpravil zapros Present");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messagePresent[i]);
   delay (waitbyte); }}
 
 /////////////////////////////////////////////////////////////////////////////////////////////
 //получение данных от ЭБУ, разборка входящих сообщений
 /////////////////////////////////////////////////////////////////////////////////////////////
  void receive () {
  ///////////////////////////////////////////////////////////////////////
  ////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД)
  ///////////////////////////////////////////////////////////////////////
 /* while(!InitGauge){
   if (mySerial_gauge.available()) {
   byte inByte = mySerial_gauge.read();
   Serial.print(" ");
   Serial.print(inByte,HEX);
  if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
  if (inByte==0xF0) {
    mySerial_gauge.write (0x02);  delay (1);
    mySerial_gauge.write (0x11);  delay (1);
    mySerial_gauge.write (0x00);  delay (1);
    mySerial_gauge.write (0x13);  delay (1); InitGauge=1;  }}}
  
  MessageParse = 0;
  while (InitGauge && !MessageParse) {
   if (!dataMessageOK) {   
    if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
    if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
    else byte0=0;
    if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
    else {byte0=0; byte1=0;}
    if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
    numberbyte=0;}
    
else { if (mySerial_gauge.available()>0)  { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}  
    if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
     
  if (dataMessageEND) { 
   int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
   int CRC =200;
   for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

   Serial.print ("                         ReceiveGauge:   ");
   for (int i = 0; i < 34; i++) {
   Serial.print(MessageRxGauge[i],HEX); Serial.print (" ");}

  //при получении сообщения БЕЗ ошибок с данными от панели приборов, запишем в переменные остаток топлива и пробег
   if (CRC==crc) {Serial.println ("    OK!!!");
 
 Fuel2 = MessageRxGauge[16]/2.0; 
 if (!flagFuelIGN) {  Fuel = MessageRxGauge[16]/2.00;  kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;} //стартовая запись литров в баке для подсчета затраченных литро
 else Fuel = MessageRxGauge[17]/2.0; //для устреднения болтания в баке закоментировать эту строку, а раскоментировать ниже
 
 //для усреднения болтания топлива в баке, раскоментировать, высчитывает среднее
 /*else { FuelZamer[ZamerNumber] = MessageRxGauge[17]/2.00;
 if (ZamerNumber==9) {
 Fuel = 0 ;
 for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
 Fuel = (float)Fuel/10.0;}
 ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;}


  kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.0; //суточный пробег с панели приборов

  //бак у меня на 59 литров, а датчик показывает максимально 53 литра. для этого эта формула
  //если у вас тоже датчик имеет лимит то подправте 53 на свой лимит. 
  //если ваш датчик показывает одинаково с полным баком то закоментировать три нижние строки. 
  if (Fuel<53){
  if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
  if (!flagFuelIGN) { FuelIGN = Fuel; Fuel_last = Fuel; flagFuelIGN = 1; }}}
   
  else Serial.println ("    ERROR!!!");   
  dataMessageEND = 0; MessageParse = 1; //mySerial_gauge.flush();
  for (int i = 0; i < 34; i++) MessageRxGauge[i]=0; }}  // очистка байтов массива 
*/
   ////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 12-13 (7 контакт ОБД)
   ////////////////////////////////////////////////////////////////////
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

  if (currentPage == '3'){
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
    myGLCD.clrScr();             
    drawscreen_three();      
    myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
     myGLCD.clrScr();             
     drawscreen_three();       

  for (int i=0; i<MessageRx[8]; i++ ) {
     int y = i*35;
     bool nolA=0; bool nolB =0;
  if (!bitRead(MessageRx[11+(i*3)],6) && bitRead(MessageRx[11+(i*3)],7)){ myGLCD.setColor (0,255,0);
     myGLCD.print(" -Passive-", 300, (75+y));} // если DTC пасивныый делаем цвет зеленый 
  if (bitRead(MessageRx[11+(i*3)],7) && bitRead(MessageRx[11+(i*3)],6)) {myGLCD.setColor (255,0,0);  
     myGLCD.print(" -Active-", 300, (75+y));} // если DTC активный, делаем цвет красный 
     myGLCD.print("ERROR ", 50, (75+y));
     myGLCD.printNumI((i+1), 150, (75+y));
     
  if (!bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": P", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && !bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": C", 170, (75+y));
  if (!bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": B", 170, (75+y));
  if (bitRead(MessageRx[9+(i*3)],6) && bitRead(MessageRx[9+(i*3)],7)) myGLCD.print(": U", 170, (75+y));

  if (MessageRx[9+(i*3)]==0x00) {myGLCD.print("00", 230, (75+y)); nolA = 1;}
  if (MessageRx[9+(i*3)]<=0x0F&&MessageRx[9+(i*3)]!=0) {myGLCD.print("0", 230, (75+y)); nolA = 1;} 
  if (nolA)myGLCD.print(String (MessageRx[9+(i*3)],HEX), 246, (75+y)); 
  else myGLCD.print(String (MessageRx[9+(i*3)],HEX), 230, (75+y));

  if (MessageRx[10+(i*3)]==0x00) {myGLCD.print("00", 262, (75+y)); nolB = 1;}
  if (MessageRx[10+(i*3)]<=0x0F&&MessageRx[10+(i*3)]!=0) {myGLCD.print("0", 262, (75+y)); nolB = 1;}
  if (nolB)myGLCD.print(String (MessageRx[10+(i*3)]),HEX, 278, (75+y)); 
  else myGLCD.print(String (MessageRx[10+(i*3)],HEX), 262, (75+y));}}} 
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива

 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //отправка запроса на диагностическое соединение
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }

 /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //стартовая инициализация 7 пина ОБД
 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 //запрос чтения и стирания ошибок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void Read() {
   Serial.println ("Zapros error;  ");
   for (int i = 0; i < length8; i++) {
   mySerial.write(messageREAD[i]);
   delay (waitbyte); }}
   
 void Erase() {
   Serial.println ("Zapros erase;  ");
   for (int i = 0; i < length7; i++) {
   mySerial.write(messageERASE[i]);
   delay (waitbyte); }}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 void Menu () {
     
    if (currentPage == '0') {
     TouchHOME();
     TouchINF1();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '1') { 
     TouchHOME();
     TouchINF2();
     TouchCHECK(); }
    if (currentPage == '2') { 
     TouchHOME();
     TouchINF1();
     TouchCHECK(); }
    if (currentPage == '3') { 
     TouchHOME();
     TouchREAD();
     TouchERASE(); }}   
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,178); // линия вертикальная
    myGLCD.drawLine(80,178,80,247); // линия вертикальная
    myGLCD.print("L/H", 10, 40);
    myGLCD.print("L/A", 148, 40);
    myGLCD.print("L/V", 10, 75);
    myGLCD.print("L/M", 148, 75);
    myGLCD.print("D/K", 10, 110);
    myGLCD.print("D/L", 148, 110);
    myGLCD.print("V/K", 10, 145);
    myGLCD.print("V/L", 148, 145);
    myGLCD.print("PUMP RPM", 82, 180);
    myGLCD.print("ENGI   RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("OIL       C", 300, 75);
    myGLCD.print("FUEL    C", 300, 110);
    myGLCD.print("DENTR  C", 300, 145);
    myGLCD.print("FUERA  C", 300, 180);
    myGLCD.print("INTAIR C", 300, 215); 
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
  }
 //-------------------------------------------------
   void drawscreen_one() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Start of Delivery   *CA:", 10, 40);
    myGLCD.print("Desir inject Start  *CA:", 10, 75);
    myGLCD.print("Actua Inject Start *CA:", 10, 110);
    myGLCD.print("Desir Inject Quan  mg/s:", 10, 145);
    myGLCD.print("Actu Inject Quant mg/s:", 10, 180);
    myGLCD.print("MAF  mg/s:", 10, 215);
    myGLCD.print("Humedad %:", 255, 215);
    myGLCD.drawRoundRect (175, 255, 305, 310);
    myGLCD.print("INF 2", 215, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //-------------------------------------------------
  void drawscreen_two() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.print("Boost Press          Bar:", 10, 40);
    myGLCD.print("Boost Press Com  Bar:", 10, 75);
    myGLCD.print("EGR command     mg/s:", 10, 110);
    myGLCD.print("EGR Pulse Ratio      %:", 10, 145);
    myGLCD.print("Solenoide Pulse      %:", 10, 180);
    myGLCD.print("Solenoide Boost      %:", 10, 215);
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("INF 1", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("CHECK", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 7);
    myGLCD.print("Km/h", 410, 7);
    }
 //----------------------------------------------------------------------------
  void drawscreen_three() {
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); // линия горизонтальная
    myGLCD.drawRoundRect (15, 255, 145, 310);
    myGLCD.print("ERASE", 55, 270);
    myGLCD.drawRoundRect (335, 255, 465, 310);
    myGLCD.print("READ", 365, 270);
    myGLCD.drawRoundRect (1, 1, 77, 37);
    myGLCD.print("HOME", 10, 5);
    myGLCD.print("Km/h", 410, 3);
   }

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//кнопки тач . координаты и переходы
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void TouchHOME(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {if (p.x > 140 && p.x < 320 && p.y > 140 && p.y < 260 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (1, 1, 77, 37);
        currentPage = '0';           
        myGLCD.clrScr();             
        drawHomeScreen();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchINF1(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
      if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();
        x = 0;
        y = 0;
        p.z = 0;}}}
    
void TouchINF2(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
    if (p.x > 450 && p.x < 680 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (175, 255, 305, 310);
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchCHECK(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchREAD(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 690 && p.x < 950 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (335, 255, 465, 310);
        Read();
        x = 0;
        y = 0;
        p.z = 0;}}}

void TouchERASE(){
TSPoint p = ts.getPoint();
    pinMode(XM, OUTPUT);
    pinMode(YP, OUTPUT);
if (p.z > 10 && p.z < 1000)
    {
if (p.x > 150 && p.x < 450 && p.y > 770 && p.y < 890 && p.z > MINPRESSURE && p.z < MAXPRESSURE)
      { myGLCD.drawRoundRect (15, 255, 145, 310);
        Erase();
        x = 0;
        y = 0;
        p.z = 0;}}}
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 7); 
   myGLCD.printNumI(now.day(), 100, 7); } 
   else if (date >=10) {
   myGLCD.printNumI(now.day(), 85, 7); }
   myGLCD.print("/", 115, 7);
   if ( mon<10) {
   myGLCD.print("0", 130, 7); 
   myGLCD.printNumI(now.month(), 145, 7);} 
   else if (mon >=10) {
   myGLCD.printNumI(now.month(), 130, 7);}  
   myGLCD.print("/", 160, 7);
   myGLCD.printNumI(now.year(), 175, 7);
   if (hour<10) {
   myGLCD.print("0",255, 7); 
   myGLCD.printNumI(now.hour(), 270, 7); } 
   else if(hour>=10){ 
   myGLCD.printNumI(now.hour(), 255, 7); } 
   if (m<10) {
   myGLCD.print("0",300, 7); 
   myGLCD.printNumI(now.minute(), 315, 7); } 
   else if (m>=10){ 
   myGLCD.printNumI(now.minute(), 300, 7); }
    }

 void Temperature (){
   h = dht.readHumidity();
   t = dht.readTemperature();
   sensors.requestTemperatures(); 
   }

 

viki13viki
Offline
Зарегистрирован: 14.11.2016

отчет

Otpravil zapros Init
Receive:   0 FF FF 83 F1 11 C1 6B 8F 40 
Otpravil zapros Init
Receive:   FF FF 83 F1 11 C1 6B 8F 40 
     Initialization OK!!!!:  
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 5A 0 0 0 0 4 33 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4A 0 0 C 43 2 
Otpravil zapros 21 01
Receive:   A FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2A 0 0 0 0 9 4B 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 E E9 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3E 0 0 C 20 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4B 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 59 0 0 0 0 4 2F 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   0 2 2 FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 5A 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 35 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 5A 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 0 2 
Otpravil zapros 21 01
Receive:   6 FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3E 0 0 C 20 0 0 2 5A 0 0 0 0 4 33 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4B 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4B 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 20 0 0 2 5A 0 0 0 0 4 37 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 E E9 0 0 0 0 9 4A 0 0 C 43 C9 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3E 0 0 C 20 0 0 2 59 0 0 0 0 4 30 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4B 0 0 C 43 0 
Otpravil zapros 21 01
Receive:   2 6 FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 35 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2F 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 5A 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 5A 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   7 FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3E 0 0 C 20 0 0 2 5A 0 0 0 0 4 35 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4B 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3E 0 0 C 1F 0 0 2 59 0 0 0 0 4 35 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4B 0 0 C 43 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3F 0 0 C 1F 0 0 2 59 0 0 0 0 4 36 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2B 0 0 0 0 9 4A 0 0 C 43 8 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 3E 0 0 C 1F 0 0 2 59 0 0 0 0 4 30 0 0 0 0 32 C8 3 9E 4 29 3 20 E5 62 0 0 0 0 F 2D 0 0 0 0 9 4B 0 0 C 43 2 
Otpravil zapros 21 01
Receive:   6 FF FF FF 
Otpravil zapros 21 01

но на экране исчезло изображение. думаю твоих рук дело, на вермя......

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

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


 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {

   
   Serial.begin(115200);
   mySerial.begin(10400);


   
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }



  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
   else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else {if (millis() - prevPID > PIDTime) { PIDs();  prevPID = millis(); }}
   
 receive ();
  
  }


 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}


 

  void receive () {
 
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

 
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
 //   myGLCD.clrScr();             
 //   drawscreen_three();      
 //   myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
 //   myGLCD.clrScr();             
 //   drawscreen_three();      
 //   myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива

 
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }


 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 
 

 

viki13viki
Offline
Зарегистрирован: 14.11.2016

отчет

Otpravil zapros Init
Receive:   0 FF FF 83 F1 11 C1 6B 8F 40 
Otpravil zapros Init
Receive:   FF FF 83 F1 11 C1 6B 8F 40 
     Initialization OK!!!!:  
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 34 0 0 C 1D 0 0 2 3E 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 24 E5 62 0 0 0 0 E E3 0 0 0 0 9 4B 0 0 C 39 66 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1C 0 0 2 3E 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 25 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1D 0 0 2 3F 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 25 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1D 0 0 2 3F 0 0 0 0 4 35 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 25 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1D 0 0 2 3F 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 23 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1D 0 0 2 40 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4B 0 0 C 39 0 
Otpravil zapros 21 01
Receive:   2 AF FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1F 0 0 2 40 0 0 0 0 4 33 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1D 0 0 2 41 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 25 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1D 0 0 2 41 0 0 0 0 4 33 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1D 0 0 2 41 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 24 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B B5 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 AA 0 0 0 0 C 35 0 0 C 1F 0 0 2 42 0 0 0 0 4 38 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1C 0 0 2 42 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 25 0 0 0 0 9 4B 0 0 C 39 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1F 0 0 2 42 0 0 0 0 4 33 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 25 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 20 0 0 2 43 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 28 0 0 0 0 9 4C 0 0 C 3B 2 3 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1F 0 0 2 43 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 2 
Otpravil zapros 21 01
Receive:   0 FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1D 0 0 2 43 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 28 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1D 0 0 2 43 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1F 0 0 2 44 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 28 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1F 0 0 2 44 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 2 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 34 0 0 C 1F 0 0 2 44 0 0 0 0 4 36 0 0 0 0 32 C8 3 9E 4 29 3 24 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 34 0 0 C 1F 0 0 2 44 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 24 E5 62 0 0 0 0 F 25 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 34 0 0 C 1F 0 0 2 44 0 0 0 0 4 36 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1F 0 0 2 44 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 2 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1D 0 0 2 44 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 28 0 0 0 0 9 4C 0 0 C 3B 0 2 
Otpravil zapros 21 01
Receive:   2 FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1F 0 0 2 45 0 0 0 0 4 34 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 28 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1D 0 0 2 45 0 0 0 0 4 34 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 34 0 0 C 1F 0 0 2 45 0 0 0 0 4 35 0 0 0 0 32 C8 3 9E 4 29 3 23 E5 62 0 0 0 0 F 25 0 0 0 0 9 4C 0 0 C 3B 
Otpravil zapros 21 01
Receive:   FF FF FF 
Otpravil zapros 21 01
Receive:   FF FF FF 80 F1 11 4C 61 1 1 16 35 EA 0 0 0 0 C 35 0 0 C 1F 0 0 2 45 0 0 0 0 4 2F 0 0 0 0 32 C8 3 9D 4 29 3 23 E5 62 0 0 0 0 F 26 0 0 0 0 9 4C 0 0 C 3B FD 

 

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

похоже я понял где косяк был во всех моих модерннизированных сккетчах. Щас

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

пробуй этот 


 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 bool Init = 0;
 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
  
 byte messageInit[] = {0x81, 0x11, 0xF1, 0x81, 0x04};     // запрос инициализации
 byte messagePids[] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 
 unsigned long prevPID = 0;
 
 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 
   void setup() {
   
   Serial.begin(115200);
   mySerial.begin(10400);
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit();
 }

  void loop() {
    
   TimewaitPID = millis ();
   TimewaitInit = millis ();
   
   if (!Init) { if (!timerenabledInit){ timerwaitInit=TimewaitInit; timerenabledInit=1; initialization(); }
   else if (TIMEREXPIRED_Init) timerenabledInit=0;}
  
   else {if (millis() - prevPID > 500) { PIDs();  prevPID = millis(); }}
   
 receive ();
    }


 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < sizeof(messagePids); i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}

 
 void receive () {
 
   if (mySerial.available()) {
   delay(195);
   while( mySerial.available()) {
   byte inbyte = mySerial.read();
   if (inbyte <=15 ) Serial.print ("0"); Serial.print (inbyte, HEX); Serial.print (" ");
     }
Serial.println();
   }
  }
   
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < sizeof(messageInit); i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }


 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 

viki13viki
Offline
Зарегистрирован: 14.11.2016

ноль в порту ниче не происходит

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

так 


 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

 bool Init = 0;
 
 
 int numberbyte = 0;
 int PIDTime = 120;       // задержка ожидания запроса следующего pid 2101, мс
 int PresTime = 8000;     // задержка между посылками запросов присутствия, мс 
 int waitbyte = 1;        // задержка между отправкой байт в сообщении, мс
 int waitbyte_gauge = 4;  
 int Datadelay = 50;      // задержка между отрисовкой данных на LCD, мс
 
 float L100M = 0;           //расход на 100 км измеренный за поездку
 float L100 = 0;            //мгновенный расход литров на 100км
 float LHor = 0;           //мгновенный расход топлива литров в час
 float L100SR = 0;         //расход литров на 100км измеренный раз в интервал kmL  
 float L100SR_TFT = 0;     // самый средний из расходов на 100км, он выводится на экран

 int L100_Eeprom[11]= {10,10,10,10,10,10,10,10,10,10,10};
 int FuelZamer[10]= {0};  // массив для измерения уровня (количества) топлива 
 int ZamerNumber = 0;     // номер замера уровня (количества) топлива 
 int n_eeprom = 0;        // текущий адрес ячейки еепром для записи расхода
 
 int MAF = 0;              //26,27 байты   Sensor de flujo de aire en masa
 float BoostPres = 0;      //28,29 байты   Presión de refuerzo
 int RPM = 0;              //32,33 байты   Velocidad del motor
 int EGRmg = 0;            //34,35 байты   Comando EGR (Comando de recirculación de gases de escape)
 float BoostPresCom = 0;   //38,39 байты   Comando de presión de refuerzo
 int Speed = 0;            //44,45 байты   Velocidad del vehículo
 float DesaInjQua = 0;     //50,51 байты   Cantidad de inyección deseada
 float InjQua = 0;         //52,53 байты   Cantidad de la inyección
 float StaDaliv = 0;       //54,55 байты   Inicio de la entrega
 int PumpRPM = 0;          //56,57 байты   Velocidad de la bomba
 float EGRPul = 0;         //62,63 байты   Relación de impulsos EGR (recirculación de gases de escape
 float SolenPul = 0;       //64,65 байты   Velocidad de solenoide de control de nivel de remolino Relación de impulsos
 float SolenPre = 0;       //70,71 байты   Relación de impulsos Presión Electroválvula de presión
 float DesInj = 0;         //72,73 байты   Inyección deseada Inicio
 float ActInj = 0;         //16,17 байты   Inicio de la inyección real
 int TempAir = 0;          //74,75 байты   Temperatura del aire de admisión
 int Temp = 0;             //14,15 байты   Temperatura del refrigerante
 int TempOil = 0;          //18,19 байты   Temperatura del aceite del motor
 int TempFuel = 0;         //58,59 байты   Temperatura del combustible
 
 //все что касается топлива
 float Fuel = 0;  //остаток топлива 
 float Fuel2 = 0;  //остаток мгновенного топлива байт 16 , датчика в баке
 int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
 int Fuel_last = 0;   // для формул
 bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
 float FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
 
 //все что касается километража
 float kmAge = 0;             //пробег, полученный со щитка приборов
 int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
 int kmAge_last = 0;       // для формул
 bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
 float kmTrip = 0;            //пробег за один цикл включения зажигания
 int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
 int km = 0;              // переменная для расчетов
 int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
 int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
 int kmREFUELING = 0;            // пробег до заправки на остатке топлива 
 
 int colerror = 0;           //количество ошибок в правом верхнем углу третьего экрана
 //float Barom = 0;          // барометр 
 
 byte MessageRx[110] = {0};  // массив байтов принимаемого сообщения
 byte MessageRxGauge[60] = {0};  // массив байтов принимаемого сообщения от щитка приборов
 
 byte messageInit[5] = {0x81, 0x11, 0xF1, 0x81, 0x04};    // запрос инициализации
 byte messagePresent[5] = {0x81,0x11,0xF1,0x3E,0xC1};      // запрос присутствия 
 byte messagePids[6] = {0x82,0x11,0xF1,0x21,0x01,0xA6};    // запрос пид 2101
 byte messageREAD[8] = {0x84,0x11,0xF1,0x18,0x00,0xFF,0x00,0x9D};    // запрос ошибок
 byte messageERASE[7] = {0x83,0x11,0xF1,0x14,0xFF,0x00,0x98};    // стирание ошибок

 unsigned long prevPID = 0;
 unsigned long prevPIDgauge = 0;
 unsigned long prevTemperature = 0;
 unsigned long prevpres = 0;
 unsigned long prevWatch = 0;
 unsigned long prevDvoet = 0;
 unsigned long prevData = 0;

 unsigned long TimewaitPID, timerwaitPID = 0;
 bool timerenabledPID = 0;
 #define TIMEREXPIRED_PID (TimewaitPID - timerwaitPID)> 200 // здесь задержка на ожидание правильного ответа пидов, мс

 unsigned long TimewaitInit, timerwaitInit = 0;
 bool timerenabledInit = 0;
 #define TIMEREXPIRED_Init (TimewaitInit - timerwaitInit)> 500 // здесь задержка на ожидание ответа об удачной инициализации, мс

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

   void setup() {

   
   Serial.begin(115200);
   mySerial.begin(10400);


   
   pinMode(TX, OUTPUT);
   pinMode(TX_gauge, OUTPUT);
   fastinit(); initialization();
 }



  void loop() {
    
  
   
   if (millis() - prevPID > 500) { if (!Init) initialization(); else PIDs();  prevPID = millis(); }
   
 receive ();
  
  }


 void PIDs() {
   Serial.println ("Otpravil zapros 21 01");
   for (int i = 0; i < length6; i++) {
   mySerial.write(messagePids[i]);
   delay (waitbyte); }}


 

  void receive () {
 
   if (mySerial.available()) {
   delay(195);
   int k=0;
   byte inbyte=0;
    
   while( mySerial.available() && k < 110) {
   inbyte = mySerial.read();
   MessageRx[k] = inbyte;
   k++;   }
   
   Serial.print ("Receive:   ");
   for (int i = 0; i < k; i++) {
   Serial.print(MessageRx[i],HEX); Serial.print (" ");} 
   Serial.println ("");

  if (MessageRx[2]==0x83 && MessageRx[3]==0xF1 && MessageRx[4]==0x11 && MessageRx[5]==0xC1 && MessageRx[6]==0x6B && MessageRx[7]==0x8F && MessageRx[8]==0x40) {Init=1;
  timerenabledInit=0;  
  Serial.println ("     Initialization OK!!!!:  "); }

 
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    //Чтение и стирание ошибок
    ///////////////////////////////////////////////////////////////////////////////////////////////////
  //при получении этого сообщения выдавать на третий экран "NO ERROR"
  if (MessageRx[4]==0x82 && MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]==0x00 && MessageRx[9]==0xDC){
 //   myGLCD.clrScr();             
 //   drawscreen_three();      
 //   myGLCD.print("NO DTC", 165, 145);
    Serial.println ("     NO DTC  "); }
    
  //при получении этого сообщения выдавать на третий экран "DTC BORRADO"
  if (MessageRx[3]==0x83 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x54 && MessageRx[7]==0xFF && MessageRx[8]==0x00 && MessageRx[9]==0xD8){
 //   myGLCD.clrScr();             
 //   drawscreen_three();      
 //   myGLCD.print("DTC BORRADO", 165, 145);
    Serial.println ("     DTC BORRADO  "); }
   
  // при получении сообщения о наличии ошибок DTC разберем сообщение выведем на экран ошибки
  if (MessageRx[5]==0xF1 && MessageRx[6]==0x11 && MessageRx[7]==0x58 && MessageRx[8]>0){
     Serial.println ("DTC is found!");
}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописываем формулы к данным  ///////////////////////////////////////////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  else if (MessageRx[3]==0x80 && MessageRx[4]==0xF1 && MessageRx[5]==0x11 && MessageRx[6]==0x4C && MessageRx[7]==0x61 && MessageRx[8]==0x01)    {
   //Barom = MessageRx[39];
   L100 = (float)LHor*100.0/(float)Speed;
   LHor = (float)RPM* (float)InjQua*2.00/1000.0*60.00/1000.0/0.85;
   MAF =  ((MessageRx[29]*256)+MessageRx[30])/10;
   BoostPres =  ((MessageRx[31]*256)+MessageRx[32])/1000.0;
   RPM =  (MessageRx[35]*256)+MessageRx[36];
   EGRmg =  ((MessageRx[37]*256)+MessageRx[38])/10.0;
   BoostPresCom =  ((MessageRx[41]*256)+MessageRx[42])/1000.0;
   Speed =  ((MessageRx[47]*256)+MessageRx[48])/100;
   DesaInjQua =  ((MessageRx[53]*256)+MessageRx[54])/100.0;
   InjQua =  ((MessageRx[55]*256)+MessageRx[56])/100.0;
   StaDaliv =  ((MessageRx[57]*256)+MessageRx[58])/100.0;
   PumpRPM =  (MessageRx[59]*256)+MessageRx[60];
   EGRPul =  ((MessageRx[65]*256)+MessageRx[66])/100.0;
   SolenPul =  ((MessageRx[67]*256)+MessageRx[68])/100.0;
   SolenPre =  ((MessageRx[73]*256)+MessageRx[74])/100.0;
   DesInj =  ((MessageRx[75]*3)+(MessageRx[76])/100.0)+0.3;
   ActInj =  ((MessageRx[19]*3)+(MessageRx[20])/100.0)+0.3;
   //TempAir =  ((MessageRx[77]*26)-278)+MessageRx[78]/10.0;
   //Temp =  ((MessageRx[17]*26)-278)+MessageRx[18]/10.0;
   //TempOil =  ((MessageRx[21]*26)-278)+MessageRx[22]/10.0;
   //TempFuel =  ((MessageRx[61]*26)-278)+MessageRx[62]/10.0;
   //ниже идут расчетные формулы более точные чем те что закоментированы выше
   int A = 0;
   if  (MessageRx[77]<=0x0A) A = 277;
   if  (MessageRx[77]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[77]>=0x0D) A = 279;
   double B = MessageRx[78]/10.0;
   double cel , drob ;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempAir =  ((MessageRx[77]*26)-A)+cel;
   
   if  (MessageRx[17]<=0x0A) A = 277;
   if  (MessageRx[17]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[17]>=0x0D) A = 279;
   B = MessageRx[18]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     Temp =  ((MessageRx[17]*26)-A)+cel;


   if  (MessageRx[21]<=0x0A) A = 277;
   if  (MessageRx[21]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[21]>=0x0D) A = 279;
   B = MessageRx[22]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempOil =  ((MessageRx[21]*26)-A)+cel;


   if  (MessageRx[61]<=0x0A) A = 277;
   if  (MessageRx[61]==0x0B || MessageRx[77]==0x0C) A = 278;
   if  (MessageRx[61]>=0x0D) A = 279;
   B = MessageRx[62]/10.0;
   drob = modf(B, &cel);
   if (drob>0.6) cel++;
     TempFuel =  ((MessageRx[61]*26)-A)+cel;
     
   timerenabledPID=0; }
     for (int i = 0; i < 110; i++) MessageRx[i]=0; }} // очистка байтов массива

 
 void initialization() {
   Serial.println ("Otpravil zapros Init");
   for (int i = 0; i < length5; i++) {
   mySerial.write(messageInit[i]);
   delay (5); } 
   delay (55); }


 void fastinit() {
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(360);             // wait for K-line to be clear 3
   digitalWrite (TX, LOW);  // makes K-line low  3
   delay(25);
   digitalWrite (TX, HIGH); // makes K-line high  3
   delay(25);               //last delay before first message
   mySerial.begin(10400); } // baud rate of the OBD

 
 

 

viki13viki
Offline
Зарегистрирован: 14.11.2016
Otpravil zapros Init
Receive:   0 FF FF 
Otpravil zapros Init
Receive:   FF FF 
Otpravil zapros Init
Receive:   FF FF 
Otpravil zapros Init
 
MaksVV
Offline
Зарегистрирован: 06.08.2015

в строке 115 между fastinit и initialization поставь delay 1 или 5 или 10.