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

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

вот чуть поменял формулы. Должно получше быть. ПС для сравнения скетчей я пользуюсь он лайн сравнением текстов http://text.num2word.ru/

скетч 

/////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  #include <UTFT.h>
  #include <SPI.h>
  #include <EEPROM.h>
  
  
  //pin 20 SCL , 21 SDA датчик реального времени
  #include <Wire.h>
  #include "RTClib.h"
  RTC_DS3231 rtc;       
  
  //датчик наружней температуры
  #include <OneWire.h>
  #define ONE_WIRE_BUS 8   
  OneWire oneWire(ONE_WIRE_BUS);
  #include <DallasTemperature.h>
  DallasTemperature sensors(&oneWire);
  
  //датчик внутринней температуры и влаги
  #include "DHT.h"
  #define DHTPIN 9   
  #define DHTTYPE DHT22 
  DHT dht(DHTPIN, DHTTYPE);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  
 
  
  extern uint8_t GroteskBold16x32[];
 
  int x, y;
  char currentPage;

  float h;
  float t;

  
  bool Dvoet = 0;

  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
  #define mySerial_gauge Serial2
  
  #define TX_gauge 16
  #define TX 13

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

  int Fuel = 0;         //остаток топлива
  int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
  int Fuel_last = 0;   // для формул
  bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
  int FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
  
  
  
  int kmAge = 0;             //пробег, полученный со щитка приборов
  int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
  int kmAge_last = 0;       // для формул
  bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
  int kmTrip = 0;            //пробег за один цикл включения зажигания
  int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
  int km = kmL;              // переменная для расчетов
  int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
  int kmTFT =  kmeeprom;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
  int kmREFUELING;            // пробег до заправки на остатке топлива 
  
  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);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD();
    myGLCD.clrScr();
    myTouch.InitTouch();
    myTouch.setPrecision(PREC_MEDIUM);
    myGLCD.setFont(GroteskBold16x32);   
    
    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.00;
    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);}
//  else    {if (millis() - prevPIDgauge> 1000) {PIDsGauge(); prevPIDgauge = millis();}}
    receive ();
    if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); if (Fuel!=0&& Fuel<53) {Trip ();}}
    if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
    if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 285, 0);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
    Menu();
    LCDDataPrint();



   }

void Trip () {
  
  if (flagkmAgeIGN){
L100M = (float)FuelTrip/(float)kmTrip*100.00;
 if (L100M<0) L100SR_TFT = 0;
 if (L100M>99) L100SR_TFT = 99;
 
if (kmTrip>0 && kmTrip>kmTFT) {kmTFT = kmTrip + kmeeprom; 
// тут считаем среднеарифметический расход из ячеек еепром 
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;
}

FuelTrip = FuelIGN - Fuel;                          
if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
else kmTrip = 2000 - (kmAgeIGN - kmAge);  // 000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
if (kmAge==kmAgeIGN) kmTrip = 0;
if (kmTrip>km) {km=kmTrip+kmL; 



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

if (L100SR>0) kmREFUELING=1.00/(float)L100SR*(float)Fuel*100.00;
else kmREFUELING=1.00/(float)L100SR_TFT*(float)Fuel*100.00;

// тут записываем  L100SR последовательно в одну из 11 ячеек еепром
EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12);
EEPROM.write(n_eeprom, L100SR*10); 
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom);

}}
  
  
  }


   
   void LCDDataPrint(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
     
      myGLCD.setColor(255, 255, 255);
      myGLCD.printNumI(Speed, 350, 0, 3);
      
     if (currentPage == '0') {
       
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      if (kmTrip>=5) myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      else myGLCD.print("0", 123, 75); 
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      myGLCD.printNumI(Fuel, 210, 110,5);
      if (kmTrip>=1) myGLCD.printNumI(kmTrip, 60, 145,5);
      else myGLCD.print("0", 123, 145);
      if (FuelTrip>=1)myGLCD.printNumI(FuelTrip, 195, 145,5);
      else myGLCD.print("0", 273, 145);

      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 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);
      
    }
   
    if (currentPage == '1') {
     
      myGLCD.printNumF(StaDaliv,1, 395, 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, 415, 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, 395, 145,'.',3);  
      myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
      myGLCD.printNumF(SolenPre, 0, 395, 215,'.', 3);
        
      }
     prevData = millis();
    }
   }
  
  ///////////////////////////////////////////////////////////////////////////
  
  //отправка запроса пид 2101
  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 софт сериал 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!!!");
    
   Fuel = MessageRxGauge[17]/2.00;
   kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.00;
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = 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));} //двигает воторой байт в2 и 3 соо
       }
    }
   


    //прописываем формулы к данным
   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
    }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  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 (myTouch.dataAvailable()) {
         myTouch.read();
         x=myTouch.getX(); 
         y=myTouch.getY();
      if (currentPage == '0') {
      buttonHomeTouch();
      buttonINF1Touch();
      buttonINF2Touch();
      buttonCHECKTouch();     }
      if (currentPage == '1') { 
     buttonHomeTouch();
     buttonINF2Touch();
     buttonCHECKTouch();     }
      if (currentPage == '2') { 
     buttonHomeTouch();
     buttonINF1Touch();
     buttonCHECKTouch();      }
      if (currentPage == '3') { 
      buttonHomeTouch();
      buttonREADTouch();
      buttonERASETouch(); }}}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописывает заголовки на страницах
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   void drawHomeScreen() {
     line() ;
     Watch ();
     myGLCD.drawLine(295,35,295,248); // линия вертикальная
     myGLCD.setColor(0, 255, 0); // цвет линии зеленый
     myGLCD.drawLine(145,35,145,178); // линия вертикальная
     myGLCD.drawLine(1,178,295,178); // линия горизонтальная
     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", 10, 180);
     myGLCD.print("Engi RPM", 10, 215);
     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("IntAirC", 300, 215);
     buttonHome() ;
     buttonINF1() ;
     buttonINF2() ;
     buttonCHECK() ;
   }
  //-------------------------------------------------
    void drawscreen_one() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF2() ;
     buttonCHECK() ;
     }
  //-------------------------------------------------
   void drawscreen_two() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF1() ;
     buttonCHECK() ;
   }
  //----------------------------------------------------------------------------
   void drawscreen_three() {
     Watch ();
     myGLCD.setColor(255, 0, 0); // цвет линии красный
     myGLCD.drawLine(1,35,479,35); // линия горизонтальная
     myGLCD.drawLine(1,248,479,248); // линия горизонтальная
     buttonHome();
     buttonERASE();
     buttonREAD();
   }

  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //координаты тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawFrame(int x1, int y1, int x2, int y2) {
     myGLCD.setColor(255, 0, 0);
     myGLCD.drawRoundRect (x1, y1, x2, y2);
     while (myTouch.dataAvailable())
     myTouch.read();
     myGLCD.setColor(255, 255, 255); 
   }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка кнопок и координат тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void buttonHome() {
     myGLCD.setColor(0,0,0); // цвет кнопки -серый
     myGLCD.fillRoundRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
     myGLCD.setColor(255, 255,255); // цвет текста зеленый
     myGLCD.drawRoundRect (1, 1, 65, 33);      // кнопка будет рамкой
     myGLCD.print("HOME", 1, 0); // центровка строки
    }

    void buttonHomeTouch(){
      if ((x>=1) && (x<=65) &&(y>=1) && (y<=33)) {
        drawFrame(1, 1, 65, 33);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen(); 
       
      }}

     
     
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("INF 1", 25, 265);
    }
   void buttonINF1Touch() {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();       
       
      } }

   
  void buttonINF2() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (180, 255, 300, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (180, 255, 300, 310);
     myGLCD.print("INF 2", 200, 265);
    }
  void buttonINF2Touch() {
    if ((x>=180) && (x<=300) && (y>=255) && (y<=310)) {
        drawFrame(180, 255, 300, 310); 
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();   
                                                                      
      }}
  
  void buttonCHECK() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("CHECK", 375, 265);
    }
  void buttonCHECKTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();   
                                                                         
      } }

  
    void buttonERASE() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("ERASE", 25, 265);
    }
    
    void buttonERASETouch () {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        Erase();           //потом заменить на дейсвие
              
                                                                         
      }}
      
    void buttonREAD() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("READ", 375, 265);
    }
    
    void buttonREADTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        Read();        //потом заменить на дейсвие   
        
                                                                           
      }}

  ////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка линий
  ///////////////////////////////////////////////////////////////////////////////////////
  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(0, 255, 0); //зеленый цвет цифры
  
    if (date<10) { 
    myGLCD.print("0", 85, 0); 
    myGLCD.printNumI(now.day(), 100, 0); } 
    else if (date >=10) {
    myGLCD.printNumI(now.day(), 85, 0); }
    myGLCD.print("/", 115, 0);
    if ( mon<10) {
    myGLCD.print("0", 130, 0); 
    myGLCD.printNumI(now.month(), 145, 0);} 
    else if (mon >=10) {
    myGLCD.printNumI(now.month(), 130, 0);}  
    myGLCD.print("/", 160, 0);
    myGLCD.printNumI(now.year(), 175, 0);
    if (hour<10) {
    myGLCD.print("0",255, 0); 
    myGLCD.printNumI(now.hour(), 270, 0); } 
    else if(hour>=10){ 
    myGLCD.printNumI(now.hour(), 255, 0); } 
    if (m<10) {
    myGLCD.print("0",300, 0); 
    myGLCD.printNumI(now.minute(), 315, 0); } 
    else if (m>=10){ 
    myGLCD.printNumI(now.minute(), 300, 0); }
    myGLCD.print("Km/h", 410, 0);
 
  
 }
  void Temperature (){
    h = dht.readHumidity();
    t = dht.readTemperature();
    sensors.requestTemperatures();
    }
 

 

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

Что еще в будущем можно добавить ? сенсорную кнопку сброса среднего расхода (который хранится в еепром). 

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

Ну и сделать дополнительный экран,  где крупно будет один, 2 , 3 или 4 параметра отображаться и стрелочками можно листать параметры

viki13viki
Offline
Зарегистрирован: 14.11.2016
средняя скорость не интересна, но идея хороша, может кому и пригодится. отдельную страницу не хочется делать, хочу на первом экране и постоянно видеть температуры и расходу, без листания. потом чуток может изменю а пока что оставлю так. затирания убрал, пока нормально, единственное в kmTrip появляется 2000 до первого километра, твое затирание не работает на нем. потом будет видно нужны затирания или нет.
есть одна фигня. вчера заправился под завязку. бак у меня 59 литров. показания дают 53 литра, думаю не ужели должен быть и второй байт, но я все точно проверл, только один байт отвечает за топливо. подключил опком и вижу что он тоже показывает 53 литра. значит датчик имеет ограничение по максимальной точек это 53 литра. бак не на 50 литров, это точно , когда заправляюсь под завязку то километров 150 стрелка в упоре в право, а потом начинает ползти в лево. 150 км это примерно 10 литр соляры, прибавим к 53 равно 63. 59 литров старндарт ну и до горла литра 3-4. уже прошел почти 80 км а стрелка в упоре в право и показывает 53 литра. так что правильные подсчеты пойдут уже после того как начнет в действительности падать ниже 53 литров. 
MaksVV
Offline
Зарегистрирован: 06.08.2015

Это просто. сделать работу всех формул по условию if (Fuel<53). Не понял про какое затирание ты говорил. Я не делал затирание, я делал чтоб не отображалось ниже 1 км  и 1 л , а расход за поездку начал показывать после 5 км движения. 

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

viki13viki пишет:
сединственное в kmTrip появляется 2000 до первого километра, твое затирание не работает на нем.

прочитай что написано в строке 257 и добавь это в строку 258:

if (kmTrip==2000) kmTrip = 0;

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

всё равно тебе не проехать 2000 км за один цикл включения зажигания. Тяжело это))

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

извени, я имел ввиду не отображение до 1 кл. строчку 257 конечно видел и поменял на 2000, у меня суточный до 2000км. сейчас добавлю if (kmTrip==2000) kmTrip = 0;

MaksVV
Offline
Зарегистрирован: 06.08.2015
нет, вставь лучше так. Это будет гораздо более правильно
if (kmAge==kmAgeIGN) kmTrip = 0;

 

 

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

я вставил  if (kmTrip==2000) kmTrip = 0; и теперь стоит ноль до 1 км. или всетаки вставить это if (kmAge==kmAgeIGN) kmTrip = 0;?

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

Это будет колстыль. вставь лучше последнее, так логика не будет корявой, нужно ведь аккуратно учиться программировать, а не делать костыли. В последнем случае даже 2000 км можешь за раз проехать. )) Отпишись потом как себя ведёт L100SR_TFT, теперь при вкл. зажигания сразу чтонибудь показывает? 

 

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

ты прав на счет 2000ч. теперь скажи вот это ......сделать работу всех формул по условию if (Fuel<53).  формул много и разных.... для Fuel и kmAge ? все я потерялся снова. слишком много инфы для меня. не соображаю вообсче.

L100SR_TFT при включении показывает последний расчет. раньше показывал 0. Не уверен, так как перепрошивался и теперь естественн 0. после длительной вечерней поезки , утром посмотрю.

подкидываю освежонный скетч с подправками

/////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  #include <UTFT.h>
  #include <SPI.h>
  #include <EEPROM.h>
  
  
  //pin 20 SCL , 21 SDA датчик реального времени
  #include <Wire.h>
  #include "RTClib.h"
  RTC_DS3231 rtc;       
  
  //датчик наружней температуры
  #include <OneWire.h>
  #define ONE_WIRE_BUS 8   
  OneWire oneWire(ONE_WIRE_BUS);
  #include <DallasTemperature.h>
  DallasTemperature sensors(&oneWire);
  
  //датчик внутринней температуры и влаги
  #include "DHT.h"
  #define DHTPIN 9   
  #define DHTTYPE DHT22 
  DHT dht(DHTPIN, DHTTYPE);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  
 
  
  extern uint8_t GroteskBold16x32[];
 
  int x, y;
  char currentPage;

  float h;
  float t;

  
  bool Dvoet = 0;

  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
  #define mySerial_gauge Serial2
  
  #define TX_gauge 16
  #define TX 13

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

  int Fuel = 0;         //остаток топлива
  int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
  int Fuel_last = 0;   // для формул
  bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
  int FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
  
  
  
  int kmAge = 0;             //пробег, полученный со щитка приборов
  int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
  int kmAge_last = 0;       // для формул
  bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
  int kmTrip = 0;            //пробег за один цикл включения зажигания
  int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
  int km = kmL;              // переменная для расчетов
  int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
  int kmTFT =  kmeeprom;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
  int kmREFUELING;            // пробег до заправки на остатке топлива 
  
  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);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD();
    myGLCD.clrScr();
    myTouch.InitTouch();
    myTouch.setPrecision(PREC_MEDIUM);
    myGLCD.setFont(GroteskBold16x32);   
    
    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.00;
    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);}
//  else    {if (millis() - prevPIDgauge> 1000) {PIDsGauge(); prevPIDgauge = millis();}}
    receive ();
    if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); Trip ();}
    if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
    if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 285, 0);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
    Menu();
    LCDDataPrint();



   }

void Trip () {
  
  if (flagkmAgeIGN){
L100M = (float)FuelTrip/(float)kmTrip*100.00;
 if (L100M<0) L100SR_TFT = 0;
 if (L100M>99) L100SR_TFT = 99;
 
if (kmTrip>0 && kmTrip>kmTFT) {kmTFT = kmTrip + kmeeprom; 
// тут считаем среднеарифметический расход из ячеек еепром 
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;
}

FuelTrip = FuelIGN - Fuel;                          
if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
else kmTrip = 2000 - (kmAgeIGN - kmAge);  // 000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
if (kmAge==kmAgeIGN) kmTrip = 0;
if (kmTrip>km) {km=kmTrip+kmL; 



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

if (L100SR>0) kmREFUELING=1.00/(float)L100SR*(float)Fuel*100.00;
else kmREFUELING=1.00/(float)L100SR_TFT*(float)Fuel*100.00;

// тут записываем рандомно L100SR в одну из 11 ячеек еепром
EEPROM.write(n_eeprom, kmREFUELING*10); 
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
}}
  
  
  }


   
   void LCDDataPrint(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
     
      myGLCD.setColor(255, 255, 255);
      myGLCD.printNumI(Speed, 350, 0, 3);
      
     if (currentPage == '0') {
       
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      if (kmTrip>=5) myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      else myGLCD.print("0", 123, 75); 
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      myGLCD.printNumI(Fuel, 210, 110,5);
      if (kmTrip>=1) myGLCD.printNumI(kmTrip, 60, 145,5);
      else myGLCD.print("0", 123, 145);
      if (FuelTrip>=1)myGLCD.printNumI(FuelTrip, 195, 145,5);
      else myGLCD.print("0", 273, 145);

      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 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);
      
    }
   
    if (currentPage == '1') {
     
      myGLCD.printNumF(StaDaliv,1, 395, 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, 415, 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, 395, 145,'.',3);  
      myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
      myGLCD.printNumF(SolenPre, 0, 395, 215,'.', 3);
        
      }
     prevData = millis();
    }
   }
  
  ///////////////////////////////////////////////////////////////////////////
  
  //отправка запроса пид 2101
  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 софт сериал 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!!!");
    
   Fuel = MessageRxGauge[17]/2.00;
   kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.00;

if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = 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));} //двигает воторой байт в2 и 3 соо
       }
    }
   


    //прописываем формулы к данным
   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
    }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  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 (myTouch.dataAvailable()) {
         myTouch.read();
         x=myTouch.getX(); 
         y=myTouch.getY();
      if (currentPage == '0') {
      buttonHomeTouch();
      buttonINF1Touch();
      buttonINF2Touch();
      buttonCHECKTouch();     }
      if (currentPage == '1') { 
     buttonHomeTouch();
     buttonINF2Touch();
     buttonCHECKTouch();     }
      if (currentPage == '2') { 
     buttonHomeTouch();
     buttonINF1Touch();
     buttonCHECKTouch();      }
      if (currentPage == '3') { 
      buttonHomeTouch();
      buttonREADTouch();
      buttonERASETouch(); }}}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописывает заголовки на страницах
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   void drawHomeScreen() {
     line() ;
     Watch ();
     myGLCD.drawLine(295,35,295,248); // линия вертикальная
     myGLCD.setColor(0, 255, 0); // цвет линии зеленый
     myGLCD.drawLine(145,35,145,178); // линия вертикальная
     myGLCD.drawLine(1,178,295,178); // линия горизонтальная
     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", 10, 180);
     myGLCD.print("Engi RPM", 10, 215);
     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("IntAirC", 300, 215);
     buttonHome() ;
     buttonINF1() ;
     buttonINF2() ;
     buttonCHECK() ;
   }
  //-------------------------------------------------
    void drawscreen_one() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF2() ;
     buttonCHECK() ;
     }
  //-------------------------------------------------
   void drawscreen_two() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF1() ;
     buttonCHECK() ;
   }
  //----------------------------------------------------------------------------
   void drawscreen_three() {
     Watch ();
     myGLCD.setColor(255, 0, 0); // цвет линии красный
     myGLCD.drawLine(1,35,479,35); // линия горизонтальная
     myGLCD.drawLine(1,248,479,248); // линия горизонтальная
     buttonHome();
     buttonERASE();
     buttonREAD();
   }

  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //координаты тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawFrame(int x1, int y1, int x2, int y2) {
     myGLCD.setColor(255, 0, 0);
     myGLCD.drawRoundRect (x1, y1, x2, y2);
     while (myTouch.dataAvailable())
     myTouch.read();
     myGLCD.setColor(255, 255, 255); 
   }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка кнопок и координат тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void buttonHome() {
     myGLCD.setColor(0,0,0); // цвет кнопки -серый
     myGLCD.fillRoundRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
     myGLCD.setColor(255, 255,255); // цвет текста зеленый
     myGLCD.drawRoundRect (1, 1, 65, 33);      // кнопка будет рамкой
     myGLCD.print("HOME", 1, 0); // центровка строки
    }

    void buttonHomeTouch(){
      if ((x>=1) && (x<=65) &&(y>=1) && (y<=33)) {
        drawFrame(1, 1, 65, 33);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen(); 
       
      }}

     
     
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("INF 1", 25, 265);
    }
   void buttonINF1Touch() {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();       
       
      } }

   
  void buttonINF2() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (180, 255, 300, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (180, 255, 300, 310);
     myGLCD.print("INF 2", 200, 265);
    }
  void buttonINF2Touch() {
    if ((x>=180) && (x<=300) && (y>=255) && (y<=310)) {
        drawFrame(180, 255, 300, 310); 
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();   
                                                                      
      }}
  
  void buttonCHECK() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("CHECK", 375, 265);
    }
  void buttonCHECKTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();   
                                                                         
      } }

  
    void buttonERASE() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("ERASE", 25, 265);
    }
    
    void buttonERASETouch () {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        Erase();           //потом заменить на дейсвие
              
                                                                         
      }}
      
    void buttonREAD() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("READ", 375, 265);
    }
    
    void buttonREADTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        Read();        //потом заменить на дейсвие   
        
                                                                           
      }}

  ////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка линий
  ///////////////////////////////////////////////////////////////////////////////////////
  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(0, 255, 0); //зеленый цвет цифры
  
    if (date<10) { 
    myGLCD.print("0", 85, 0); 
    myGLCD.printNumI(now.day(), 100, 0); } 
    else if (date >=10) {
    myGLCD.printNumI(now.day(), 85, 0); }
    myGLCD.print("/", 115, 0);
    if ( mon<10) {
    myGLCD.print("0", 130, 0); 
    myGLCD.printNumI(now.month(), 145, 0);} 
    else if (mon >=10) {
    myGLCD.printNumI(now.month(), 130, 0);}  
    myGLCD.print("/", 160, 0);
    myGLCD.printNumI(now.year(), 175, 0);
    if (hour<10) {
    myGLCD.print("0",255, 0); 
    myGLCD.printNumI(now.hour(), 270, 0); } 
    else if(hour>=10){ 
    myGLCD.printNumI(now.hour(), 255, 0); } 
    if (m<10) {
    myGLCD.print("0",300, 0); 
    myGLCD.printNumI(now.minute(), 315, 0); } 
    else if (m>=10){ 
    myGLCD.printNumI(now.minute(), 300, 0); }
    myGLCD.print("Km/h", 410, 0);
 
  
 }
  void Temperature (){
    h = dht.readHumidity();
    t = dht.readTemperature();
    sensors.requestTemperatures();
    }
 

 

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

короче проверил еепром написав минискетчик, который имитирует раз в 10 км нажатием на кнопку. Всё работает супер. Когда ячейки пустые, там находится 255. Но мы, вычитывая из ячеек, делим на 10, поэтому расход показывает 25,5 при сбросе еепром или когда там пусто было изначально (наш вариант). Среднее арифметическое работает супер. 

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

строка 273 надо это EEPROM.write(n_eeprom, L100SR*10);

Ещё я переделаю чтобы адрес ячейки еепром выбирался не рандомно, а последовательно одна ячейка за другой. Даже после сброса питания начнет с того же места (адресс ячейки тоже решил в еепром запоминать). Это сделано чтобы все ячейки быстро заполнялись. А то при коротких поездках последние ячейки фиг когда заполнятся. 

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

очень жду твоего волшебства. самый освеженный с подправками скетч 1062. на щет короткой дистанции это точно

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

исправил из 1062, и добавил все фишечки рюшечки

/////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  #include <UTFT.h>
  #include <SPI.h>
  #include <EEPROM.h>
  
  
  //pin 20 SCL , 21 SDA датчик реального времени
  #include <Wire.h>
  #include "RTClib.h"
  RTC_DS3231 rtc;       
  
  //датчик наружней температуры
  #include <OneWire.h>
  #define ONE_WIRE_BUS 8   
  OneWire oneWire(ONE_WIRE_BUS);
  #include <DallasTemperature.h>
  DallasTemperature sensors(&oneWire);
  
  //датчик внутринней температуры и влаги
  #include "DHT.h"
  #define DHTPIN 9   
  #define DHTTYPE DHT22 
  DHT dht(DHTPIN, DHTTYPE);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  
 
  
  extern uint8_t GroteskBold16x32[];
 
  int x, y;
  char currentPage;

  float h;
  float t;

  
  bool Dvoet = 0;

  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
  #define mySerial_gauge Serial2
  
  #define TX_gauge 16
  #define TX 13

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

  int Fuel = 0;         //остаток топлива
  int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
  int Fuel_last = 0;   // для формул
  bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
  int FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
  
  
  
  int kmAge = 0;             //пробег, полученный со щитка приборов
  int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
  int kmAge_last = 0;       // для формул
  bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
  int kmTrip = 0;            //пробег за один цикл включения зажигания
  int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
  int km = kmL;              // переменная для расчетов
  int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
  int kmTFT =  kmeeprom;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
  int kmREFUELING;            // пробег до заправки на остатке топлива 
  
  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);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD();
    myGLCD.clrScr();
    myTouch.InitTouch();
    myTouch.setPrecision(PREC_MEDIUM);
    myGLCD.setFont(GroteskBold16x32);   
    
    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.00;
    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);}
//  else    {if (millis() - prevPIDgauge> 1000) {PIDsGauge(); prevPIDgauge = millis();}}
    receive ();
    if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); if (Fuel!=0&& Fuel<53) {Trip ();}}
    if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
    if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 285, 0);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
    Menu();
    LCDDataPrint();



   }

void Trip () {
  
  if (flagkmAgeIGN){
L100M = (float)FuelTrip/(float)kmTrip*100.00;
 if (L100M<0) L100M = 0;
 if (L100M>99) L100M = 99;
 
if (kmTrip>0 && kmTrip>kmTFT) {kmTFT = kmTrip + kmeeprom; 
// тут считаем среднеарифметический расход из ячеек еепром 
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;
}

FuelTrip = FuelIGN - Fuel;                          
if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
if (kmAge==kmAgeIGN) kmTrip = 0;
if (kmTrip>km) {km=kmTrip+kmL; 



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

if (L100SR>0) kmREFUELING=1.00/(float)L100SR*(float)Fuel*100.00;
else kmREFUELING=1.00/(float)L100SR_TFT*(float)Fuel*100.00;

// тут записываем  L100SR последовательно в одну из 11 ячеек еепром
EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12);
EEPROM.write(n_eeprom, L100SR*10); 
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom);

}}
  
  
  }


   
   void LCDDataPrint(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
     
      myGLCD.setColor(255, 255, 255);
      myGLCD.printNumI(Speed, 350, 0, 3);
      
     if (currentPage == '0') {
       
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      if (kmTrip>=5) myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      else myGLCD.print("0", 123, 75); 
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      if (Fuel<53) myGLCD.printNumI(Fuel, 210, 110,5);
      else myGLCD.print("MAX", 210, 110); 
      if (kmTrip>=1) myGLCD.printNumI(kmTrip, 60, 145,5);
      else myGLCD.print("0", 123, 145);
      if (FuelTrip>=1)myGLCD.printNumI(FuelTrip, 195, 145,5);
      else myGLCD.print("0", 273, 145);

      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 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);
      
    }
   
    if (currentPage == '1') {
     
      myGLCD.printNumF(StaDaliv,1, 395, 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, 415, 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, 395, 145,'.',3);  
      myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
      myGLCD.printNumF(SolenPre, 0, 395, 215,'.', 3);
        
      }
     prevData = millis();
    }
   }
  
  ///////////////////////////////////////////////////////////////////////////
  
  //отправка запроса пид 2101
  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 софт сериал 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!!!");
    
   Fuel = MessageRxGauge[17]/2.00;
   kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.00;
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = 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));} //двигает воторой байт в2 и 3 соо
       }
    }
   


    //прописываем формулы к данным
   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
    }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  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 (myTouch.dataAvailable()) {
         myTouch.read();
         x=myTouch.getX(); 
         y=myTouch.getY();
      if (currentPage == '0') {
      buttonHomeTouch();
      buttonINF1Touch();
      buttonINF2Touch();
      buttonCHECKTouch();     }
      if (currentPage == '1') { 
     buttonHomeTouch();
     buttonINF2Touch();
     buttonCHECKTouch();     }
      if (currentPage == '2') { 
     buttonHomeTouch();
     buttonINF1Touch();
     buttonCHECKTouch();      }
      if (currentPage == '3') { 
      buttonHomeTouch();
      buttonREADTouch();
      buttonERASETouch(); }}}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописывает заголовки на страницах
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   void drawHomeScreen() {
     line() ;
     Watch ();
     myGLCD.drawLine(295,35,295,248); // линия вертикальная
     myGLCD.setColor(0, 255, 0); // цвет линии зеленый
     myGLCD.drawLine(145,35,145,178); // линия вертикальная
     myGLCD.drawLine(1,178,295,178); // линия горизонтальная
     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", 10, 180);
     myGLCD.print("Engi RPM", 10, 215);
     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("IntAirC", 300, 215);
     buttonHome() ;
     buttonINF1() ;
     buttonINF2() ;
     buttonCHECK() ;
   }
  //-------------------------------------------------
    void drawscreen_one() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF2() ;
     buttonCHECK() ;
     }
  //-------------------------------------------------
   void drawscreen_two() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF1() ;
     buttonCHECK() ;
   }
  //----------------------------------------------------------------------------
   void drawscreen_three() {
     Watch ();
     myGLCD.setColor(255, 0, 0); // цвет линии красный
     myGLCD.drawLine(1,35,479,35); // линия горизонтальная
     myGLCD.drawLine(1,248,479,248); // линия горизонтальная
     buttonHome();
     buttonERASE();
     buttonREAD();
   }

  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //координаты тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawFrame(int x1, int y1, int x2, int y2) {
     myGLCD.setColor(255, 0, 0);
     myGLCD.drawRoundRect (x1, y1, x2, y2);
     while (myTouch.dataAvailable())
     myTouch.read();
     myGLCD.setColor(255, 255, 255); 
   }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка кнопок и координат тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void buttonHome() {
     myGLCD.setColor(0,0,0); // цвет кнопки -серый
     myGLCD.fillRoundRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
     myGLCD.setColor(255, 255,255); // цвет текста зеленый
     myGLCD.drawRoundRect (1, 1, 65, 33);      // кнопка будет рамкой
     myGLCD.print("HOME", 1, 0); // центровка строки
    }

    void buttonHomeTouch(){
      if ((x>=1) && (x<=65) &&(y>=1) && (y<=33)) {
        drawFrame(1, 1, 65, 33);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen(); 
       
      }}

     
     
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("INF 1", 25, 265);
    }
   void buttonINF1Touch() {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();       
       
      } }

   
  void buttonINF2() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (180, 255, 300, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (180, 255, 300, 310);
     myGLCD.print("INF 2", 200, 265);
    }
  void buttonINF2Touch() {
    if ((x>=180) && (x<=300) && (y>=255) && (y<=310)) {
        drawFrame(180, 255, 300, 310); 
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();   
                                                                      
      }}
  
  void buttonCHECK() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("CHECK", 375, 265);
    }
  void buttonCHECKTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();   
                                                                         
      } }

  
    void buttonERASE() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("ERASE", 25, 265);
    }
    
    void buttonERASETouch () {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        Erase();           //потом заменить на дейсвие
              
                                                                         
      }}
      
    void buttonREAD() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("READ", 375, 265);
    }
    
    void buttonREADTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        Read();        //потом заменить на дейсвие   
        
                                                                           
      }}

  ////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка линий
  ///////////////////////////////////////////////////////////////////////////////////////
  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(0, 255, 0); //зеленый цвет цифры
  
    if (date<10) { 
    myGLCD.print("0", 85, 0); 
    myGLCD.printNumI(now.day(), 100, 0); } 
    else if (date >=10) {
    myGLCD.printNumI(now.day(), 85, 0); }
    myGLCD.print("/", 115, 0);
    if ( mon<10) {
    myGLCD.print("0", 130, 0); 
    myGLCD.printNumI(now.month(), 145, 0);} 
    else if (mon >=10) {
    myGLCD.printNumI(now.month(), 130, 0);}  
    myGLCD.print("/", 160, 0);
    myGLCD.printNumI(now.year(), 175, 0);
    if (hour<10) {
    myGLCD.print("0",255, 0); 
    myGLCD.printNumI(now.hour(), 270, 0); } 
    else if(hour>=10){ 
    myGLCD.printNumI(now.hour(), 255, 0); } 
    if (m<10) {
    myGLCD.print("0",300, 0); 
    myGLCD.printNumI(now.minute(), 315, 0); } 
    else if (m>=10){ 
    myGLCD.printNumI(now.minute(), 300, 0); }
    myGLCD.print("Km/h", 410, 0);
 
  
 }
  void Temperature (){
    h = dht.readHumidity();
    t = dht.readTemperature();
    sensors.requestTemperatures();
    }
 

 

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

viki13viki пишет:
теперь скажи вот это ......сделать работу всех формул по условию if (Fuel<53).  формул много и разных.... для Fuel и kmAge ? все я потерялся снова. слишком много инфы для меня. не соображаю вообсче.

Во всех формулах почти Fuel ипользуется, поэтому отменяем все формулы если 53 л и более. 

viki13viki пишет:
L100SR_TFT при включении показывает последний расчет. раньше показывал 0. Не уверен, так как перепрошивался и теперь естественн 0. после длительной вечерней поезки , утром посмотрю.

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

 

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

еще выведи на экран переменную L100SR посмотри как она меняется и адекватно ли. Она должна стать больше 0 через 10 км пробега, и обновляеться через каждые 10. Мониторь адекватные ли цифры показывает. Просто от неё другие формулы зависят. 

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

L100SR_TFT при включении зажигания и заводке показывает 19.2 черз пять секунд стнановятся 0.0.  Проехал пять километров 0.0. 

L100SR и L100SR_TFT сейчас выведу рядом и гляну

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

строка 273 почитай

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

viki13viki пишет:
L100SR_TFT при включении зажигания и заводке показывает 19.2 черз пять секунд стнановятся 0.0.  Проехал пять километров 0.0.

нашел косяк, исправил в #1065

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

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

kmREFUELING так и остался на нуле

L100SR_TFT так и остался 19.2, когда остановился промелькнуло 19.3 где то секунду

L100M показывало 40 и 20 потом остановился показало 10. и через секунд пять стало 0.0. прокатил еще метров 500, все равно 0.0

 

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

нужно понять правильные ли данные идут в FuelTrip и kmTrip, сдается мне что что FuelTrip отрицательный иногда бывает

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

да бывало -1, но последние 3 прокатки небыло.  kmTrip показывает пробег правильно за поездку верно. как проверить  FuelTrip?

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

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

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

формулы подправил. Короче мучить их надо ппц. 

/////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  #include <UTFT.h>
  #include <SPI.h>
  #include <EEPROM.h>
  
  
  //pin 20 SCL , 21 SDA датчик реального времени
  #include <Wire.h>
  #include "RTClib.h"
  RTC_DS3231 rtc;       
  
  //датчик наружней температуры
  #include <OneWire.h>
  #define ONE_WIRE_BUS 8   
  OneWire oneWire(ONE_WIRE_BUS);
  #include <DallasTemperature.h>
  DallasTemperature sensors(&oneWire);
  
  //датчик внутринней температуры и влаги
  #include "DHT.h"
  #define DHTPIN 9   
  #define DHTTYPE DHT22 
  DHT dht(DHTPIN, DHTTYPE);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  
 
  
  extern uint8_t GroteskBold16x32[];
 
  int x, y;
  char currentPage;

  float h;
  float t;

  
  bool Dvoet = 0;

  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
  #define mySerial_gauge Serial2
  
  #define TX_gauge 16
  #define TX 13

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

  int Fuel = 0;         //остаток топлива
  int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
  int Fuel_last = 0;   // для формул
  bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
  int FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
  
  
  
  int kmAge = 0;             //пробег, полученный со щитка приборов
  int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
  int kmAge_last = 0;       // для формул
  bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
  int kmTrip = 0;            //пробег за один цикл включения зажигания
  int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
  int km = kmL;              // переменная для расчетов
  int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
  int kmTFT =  kmeeprom;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
  int kmREFUELING;            // пробег до заправки на остатке топлива 
  
  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);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD();
    myGLCD.clrScr();
    myTouch.InitTouch();
    myTouch.setPrecision(PREC_MEDIUM);
    myGLCD.setFont(GroteskBold16x32);   
    
    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.00;
    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);}
//  else    {if (millis() - prevPIDgauge> 1000) {PIDsGauge(); prevPIDgauge = millis();}}
    receive ();
    if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); if (Fuel!=0&& Fuel<53) {Trip ();}}
    if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
    if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 285, 0);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
    Menu();
    LCDDataPrint();



   }

void Trip () {
  
  if (flagkmAgeIGN){
L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
 if (L100M<0) L100M = 0;
 if (L100M>99) L100M = 99;
 
if (kmTrip>0 && kmTrip>kmTFT) {kmTFT = kmTrip + kmeeprom; 
// тут считаем среднеарифметический расход из ячеек еепром 
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;
}

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

if (kmTrip>km) {km=kmTrip+kmL; 

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

if (L100SR>0) kmREFUELING=((float)Fuel*100.00)/(float)L100SR;
else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;

// тут записываем  L100SR последовательно в одну из 11 ячеек еепром
EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12);
EEPROM.write(n_eeprom, L100SR*10); 
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom);

}}
  
  
  }


   
   void LCDDataPrint(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
     
      myGLCD.setColor(255, 255, 255);
      myGLCD.printNumI(Speed, 350, 0, 3);
      
     if (currentPage == '0') {
       
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      if (kmTrip>=5) myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      else myGLCD.print("0", 123, 75); 
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      if (Fuel<53) myGLCD.printNumI(Fuel, 210, 110,5);
      else myGLCD.print("MAX", 210, 110); 
      if (kmTrip>=1) myGLCD.printNumI(kmTrip, 60, 145,5);
      else myGLCD.print("0", 123, 145);
      if (FuelTrip>=1)myGLCD.printNumI(FuelTrip, 195, 145,5);
      else myGLCD.print("0", 273, 145);

      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 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);
      
    }
   
    if (currentPage == '1') {
     
      myGLCD.printNumF(StaDaliv,1, 395, 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, 415, 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, 395, 145,'.',3);  
      myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
      myGLCD.printNumF(SolenPre, 0, 395, 215,'.', 3);
        
      }
     prevData = millis();
    }
   }
  
  ///////////////////////////////////////////////////////////////////////////
  
  //отправка запроса пид 2101
  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 софт сериал 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!!!");
    
   Fuel = MessageRxGauge[17]/2.00;
   kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.00;
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = 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));} //двигает воторой байт в2 и 3 соо
       }
    }
   


    //прописываем формулы к данным
   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
    }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  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 (myTouch.dataAvailable()) {
         myTouch.read();
         x=myTouch.getX(); 
         y=myTouch.getY();
      if (currentPage == '0') {
      buttonHomeTouch();
      buttonINF1Touch();
      buttonINF2Touch();
      buttonCHECKTouch();     }
      if (currentPage == '1') { 
     buttonHomeTouch();
     buttonINF2Touch();
     buttonCHECKTouch();     }
      if (currentPage == '2') { 
     buttonHomeTouch();
     buttonINF1Touch();
     buttonCHECKTouch();      }
      if (currentPage == '3') { 
      buttonHomeTouch();
      buttonREADTouch();
      buttonERASETouch(); }}}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописывает заголовки на страницах
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   void drawHomeScreen() {
     line() ;
     Watch ();
     myGLCD.drawLine(295,35,295,248); // линия вертикальная
     myGLCD.setColor(0, 255, 0); // цвет линии зеленый
     myGLCD.drawLine(145,35,145,178); // линия вертикальная
     myGLCD.drawLine(1,178,295,178); // линия горизонтальная
     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", 10, 180);
     myGLCD.print("Engi RPM", 10, 215);
     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("IntAirC", 300, 215);
     buttonHome() ;
     buttonINF1() ;
     buttonINF2() ;
     buttonCHECK() ;
   }
  //-------------------------------------------------
    void drawscreen_one() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF2() ;
     buttonCHECK() ;
     }
  //-------------------------------------------------
   void drawscreen_two() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF1() ;
     buttonCHECK() ;
   }
  //----------------------------------------------------------------------------
   void drawscreen_three() {
     Watch ();
     myGLCD.setColor(255, 0, 0); // цвет линии красный
     myGLCD.drawLine(1,35,479,35); // линия горизонтальная
     myGLCD.drawLine(1,248,479,248); // линия горизонтальная
     buttonHome();
     buttonERASE();
     buttonREAD();
   }

  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //координаты тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawFrame(int x1, int y1, int x2, int y2) {
     myGLCD.setColor(255, 0, 0);
     myGLCD.drawRoundRect (x1, y1, x2, y2);
     while (myTouch.dataAvailable())
     myTouch.read();
     myGLCD.setColor(255, 255, 255); 
   }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка кнопок и координат тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void buttonHome() {
     myGLCD.setColor(0,0,0); // цвет кнопки -серый
     myGLCD.fillRoundRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
     myGLCD.setColor(255, 255,255); // цвет текста зеленый
     myGLCD.drawRoundRect (1, 1, 65, 33);      // кнопка будет рамкой
     myGLCD.print("HOME", 1, 0); // центровка строки
    }

    void buttonHomeTouch(){
      if ((x>=1) && (x<=65) &&(y>=1) && (y<=33)) {
        drawFrame(1, 1, 65, 33);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen(); 
       
      }}

     
     
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("INF 1", 25, 265);
    }
   void buttonINF1Touch() {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();       
       
      } }

   
  void buttonINF2() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (180, 255, 300, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (180, 255, 300, 310);
     myGLCD.print("INF 2", 200, 265);
    }
  void buttonINF2Touch() {
    if ((x>=180) && (x<=300) && (y>=255) && (y<=310)) {
        drawFrame(180, 255, 300, 310); 
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();   
                                                                      
      }}
  
  void buttonCHECK() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("CHECK", 375, 265);
    }
  void buttonCHECKTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();   
                                                                         
      } }

  
    void buttonERASE() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("ERASE", 25, 265);
    }
    
    void buttonERASETouch () {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        Erase();           //потом заменить на дейсвие
              
                                                                         
      }}
      
    void buttonREAD() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("READ", 375, 265);
    }
    
    void buttonREADTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        Read();        //потом заменить на дейсвие   
        
                                                                           
      }}

  ////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка линий
  ///////////////////////////////////////////////////////////////////////////////////////
  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(0, 255, 0); //зеленый цвет цифры
  
    if (date<10) { 
    myGLCD.print("0", 85, 0); 
    myGLCD.printNumI(now.day(), 100, 0); } 
    else if (date >=10) {
    myGLCD.printNumI(now.day(), 85, 0); }
    myGLCD.print("/", 115, 0);
    if ( mon<10) {
    myGLCD.print("0", 130, 0); 
    myGLCD.printNumI(now.month(), 145, 0);} 
    else if (mon >=10) {
    myGLCD.printNumI(now.month(), 130, 0);}  
    myGLCD.print("/", 160, 0);
    myGLCD.printNumI(now.year(), 175, 0);
    if (hour<10) {
    myGLCD.print("0",255, 0); 
    myGLCD.printNumI(now.hour(), 270, 0); } 
    else if(hour>=10){ 
    myGLCD.printNumI(now.hour(), 255, 0); } 
    if (m<10) {
    myGLCD.print("0",300, 0); 
    myGLCD.printNumI(now.minute(), 315, 0); } 
    else if (m>=10){ 
    myGLCD.printNumI(now.minute(), 300, 0); }
    myGLCD.print("Km/h", 410, 0);
 
  
 }
  void Temperature (){
    h = dht.readHumidity();
    t = dht.readTemperature();
    sensors.requestTemperatures();
    }
 

 

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

проехал еще 5 км. топливо показывало 51.  после остановки показало 50. во время езды так как у меня здесь повороты только в лево, правая сторона бака часто ниже а как я знаю топлива показывает меньше, то в основном катая 5 км было 46-48 литров. FuelTrip должен был от 51 начальных литров отнять например 46 и показать уже что FuelTrip- 5 литров. формула не срабатывает чтоли? 

kmREFUELING так и остался на 0, хотя он же не затратил 1 лт на 5 км, а показывает он после 1 литра.

L100SR_TFT так и остался 19.2

L100M показывало  0.0. 

FuelTrip так и остался 0.  

может не происходит запись FuelIGN ?

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

ещё поправил 

/////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  #include <UTFT.h>
  #include <SPI.h>
  #include <EEPROM.h>
  
  
  //pin 20 SCL , 21 SDA датчик реального времени
  #include <Wire.h>
  #include "RTClib.h"
  RTC_DS3231 rtc;       
  
  //датчик наружней температуры
  #include <OneWire.h>
  #define ONE_WIRE_BUS 8   
  OneWire oneWire(ONE_WIRE_BUS);
  #include <DallasTemperature.h>
  DallasTemperature sensors(&oneWire);
  
  //датчик внутринней температуры и влаги
  #include "DHT.h"
  #define DHTPIN 9   
  #define DHTTYPE DHT22 
  DHT dht(DHTPIN, DHTTYPE);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  
 
  
  extern uint8_t GroteskBold16x32[];
 
  int x, y;
  char currentPage;

  float h;
  float t;

  
  bool Dvoet = 0;

  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
  #define mySerial_gauge Serial2
  
  #define TX_gauge 16
  #define TX 13

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

  int Fuel = 0;         //остаток топлива
  int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
  int Fuel_last = 0;   // для формул
  bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
  int FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
  
  
  
  int kmAge = 0;             //пробег, полученный со щитка приборов
  int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
  int kmAge_last = 0;       // для формул
  bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
  int kmTrip = 0;            //пробег за один цикл включения зажигания
  int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
  int km = 0;              // переменная для расчетов
  int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
  int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
  int kmREFUELING;            // пробег до заправки на остатке топлива 
  
  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);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD();
    myGLCD.clrScr();
    myTouch.InitTouch();
    myTouch.setPrecision(PREC_MEDIUM);
    myGLCD.setFont(GroteskBold16x32);   
    
    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.00;
    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);}
//  else    {if (millis() - prevPIDgauge> 1000) {PIDsGauge(); prevPIDgauge = millis();}}
    receive ();
    if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); Trip ();}
    if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
    if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 285, 0);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
    Menu();
    LCDDataPrint();



   }

void Trip () {
  
  if (flagkmAgeIGN){
L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
 if (L100M<0) L100M = 0;
 if (L100M>99) L100M = 99;
 
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;
}

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

if (kmTrip-km>kmL) {km=kmTrip; 

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

if (L100SR>0) kmREFUELING=((float)Fuel*100.00)/(float)L100SR;
else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;

// тут записываем  L100SR последовательно в одну из 11 ячеек еепром
EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12);
EEPROM.write(n_eeprom, L100SR*10); 
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom);

}}
  
  
  }


   
   void LCDDataPrint(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
     
      myGLCD.setColor(255, 255, 255);
      myGLCD.printNumI(Speed, 350, 0, 3);
      
     if (currentPage == '0') {
       
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      if (kmTrip>=5) myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      else myGLCD.print("0", 123, 75); 
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      if (Fuel<53) myGLCD.printNumI(Fuel, 210, 110,5);
      else myGLCD.print("MAX", 210, 110); 
      if (kmTrip>=1) myGLCD.printNumI(kmTrip, 60, 145,5);
      else myGLCD.print("0", 123, 145);
      if (FuelTrip>=1)myGLCD.printNumI(FuelTrip, 195, 145,5);
      else myGLCD.print("0", 273, 145);

      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 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);
      
    }
   
    if (currentPage == '1') {
     
      myGLCD.printNumF(StaDaliv,1, 395, 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, 415, 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, 395, 145,'.',3);  
      myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
      myGLCD.printNumF(SolenPre, 0, 395, 215,'.', 3);
        
      }
     prevData = millis();
    }
   }
  
  ///////////////////////////////////////////////////////////////////////////
  
  //отправка запроса пид 2101
  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 софт сериал 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!!!");
    
   Fuel = MessageRxGauge[17]/2.00;
   kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.00;
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = 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));} //двигает воторой байт в2 и 3 соо
       }
    }
   


    //прописываем формулы к данным
   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
    }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  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 (myTouch.dataAvailable()) {
         myTouch.read();
         x=myTouch.getX(); 
         y=myTouch.getY();
      if (currentPage == '0') {
      buttonHomeTouch();
      buttonINF1Touch();
      buttonINF2Touch();
      buttonCHECKTouch();     }
      if (currentPage == '1') { 
     buttonHomeTouch();
     buttonINF2Touch();
     buttonCHECKTouch();     }
      if (currentPage == '2') { 
     buttonHomeTouch();
     buttonINF1Touch();
     buttonCHECKTouch();      }
      if (currentPage == '3') { 
      buttonHomeTouch();
      buttonREADTouch();
      buttonERASETouch(); }}}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописывает заголовки на страницах
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   void drawHomeScreen() {
     line() ;
     Watch ();
     myGLCD.drawLine(295,35,295,248); // линия вертикальная
     myGLCD.setColor(0, 255, 0); // цвет линии зеленый
     myGLCD.drawLine(145,35,145,178); // линия вертикальная
     myGLCD.drawLine(1,178,295,178); // линия горизонтальная
     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", 10, 180);
     myGLCD.print("Engi RPM", 10, 215);
     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("IntAirC", 300, 215);
     buttonHome() ;
     buttonINF1() ;
     buttonINF2() ;
     buttonCHECK() ;
   }
  //-------------------------------------------------
    void drawscreen_one() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF2() ;
     buttonCHECK() ;
     }
  //-------------------------------------------------
   void drawscreen_two() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF1() ;
     buttonCHECK() ;
   }
  //----------------------------------------------------------------------------
   void drawscreen_three() {
     Watch ();
     myGLCD.setColor(255, 0, 0); // цвет линии красный
     myGLCD.drawLine(1,35,479,35); // линия горизонтальная
     myGLCD.drawLine(1,248,479,248); // линия горизонтальная
     buttonHome();
     buttonERASE();
     buttonREAD();
   }

  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //координаты тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawFrame(int x1, int y1, int x2, int y2) {
     myGLCD.setColor(255, 0, 0);
     myGLCD.drawRoundRect (x1, y1, x2, y2);
     while (myTouch.dataAvailable())
     myTouch.read();
     myGLCD.setColor(255, 255, 255); 
   }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка кнопок и координат тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void buttonHome() {
     myGLCD.setColor(0,0,0); // цвет кнопки -серый
     myGLCD.fillRoundRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
     myGLCD.setColor(255, 255,255); // цвет текста зеленый
     myGLCD.drawRoundRect (1, 1, 65, 33);      // кнопка будет рамкой
     myGLCD.print("HOME", 1, 0); // центровка строки
    }

    void buttonHomeTouch(){
      if ((x>=1) && (x<=65) &&(y>=1) && (y<=33)) {
        drawFrame(1, 1, 65, 33);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen(); 
       
      }}

     
     
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("INF 1", 25, 265);
    }
   void buttonINF1Touch() {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();       
       
      } }

   
  void buttonINF2() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (180, 255, 300, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (180, 255, 300, 310);
     myGLCD.print("INF 2", 200, 265);
    }
  void buttonINF2Touch() {
    if ((x>=180) && (x<=300) && (y>=255) && (y<=310)) {
        drawFrame(180, 255, 300, 310); 
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();   
                                                                      
      }}
  
  void buttonCHECK() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("CHECK", 375, 265);
    }
  void buttonCHECKTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();   
                                                                         
      } }

  
    void buttonERASE() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("ERASE", 25, 265);
    }
    
    void buttonERASETouch () {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        Erase();           //потом заменить на дейсвие
              
                                                                         
      }}
      
    void buttonREAD() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("READ", 375, 265);
    }
    
    void buttonREADTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        Read();        //потом заменить на дейсвие   
        
                                                                           
      }}

  ////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка линий
  ///////////////////////////////////////////////////////////////////////////////////////
  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(0, 255, 0); //зеленый цвет цифры
  
    if (date<10) { 
    myGLCD.print("0", 85, 0); 
    myGLCD.printNumI(now.day(), 100, 0); } 
    else if (date >=10) {
    myGLCD.printNumI(now.day(), 85, 0); }
    myGLCD.print("/", 115, 0);
    if ( mon<10) {
    myGLCD.print("0", 130, 0); 
    myGLCD.printNumI(now.month(), 145, 0);} 
    else if (mon >=10) {
    myGLCD.printNumI(now.month(), 130, 0);}  
    myGLCD.print("/", 160, 0);
    myGLCD.printNumI(now.year(), 175, 0);
    if (hour<10) {
    myGLCD.print("0",255, 0); 
    myGLCD.printNumI(now.hour(), 270, 0); } 
    else if(hour>=10){ 
    myGLCD.printNumI(now.hour(), 255, 0); } 
    if (m<10) {
    myGLCD.print("0",300, 0); 
    myGLCD.printNumI(now.minute(), 315, 0); } 
    else if (m>=10){ 
    myGLCD.printNumI(now.minute(), 300, 0); }
    myGLCD.print("Km/h", 410, 0);
 
  
 }
  void Temperature (){
    h = dht.readHumidity();
    t = dht.readTemperature();
    sensors.requestTemperatures();
    }
 

 

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

еще 5 км. бак был 50 лт. потом в прокате падал с 49 до 46 из-за частого кренав право. остановка после 5 км 48. 

kmREFUELING так и остался на 0, 

L100SR_TFT так и остался 19.2

L100M показывало  0.0. 

FuelTrip показал 10 литров. а должно было показать 2 литра, по логике

через секунд 10-15 сново включил зажигание бак показал 50

сегодня после 25 км посмотрю че покажет. тогда будем делать выводы. что работает а что нет

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

Вообще не понятно поведение FuelTrip и L100M остальное вроде как не должно меняться до 10км

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

viki13viki пишет:
может не происходит запись FuelIGN ?

выводи его тогда тоже на экран. Может действительно тут косяк

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

отчет

kmTrip  0 , kmREFUELING 0 , L100SR_TFT 19.2 , Fuel 50       выезд с работы 

kmTrip  11 , kmREFUELING 260 , L100SR_TFT 19.3 , Fuel 50

kmTrip  22 , kmREFUELING 258 , L100SR_TFT 17.0 , Fuel 51

kmTrip  31 , kmREFUELING 258 , L100SR_TFT 17.0 , Fuel 51     остановка дома. L100M и FuelTrip так и не появились

утро

kmTrip  0 , kmREFUELING 0 , L100SR_TFT 16.8 , Fuel 49       выезд на работу 

kmTrip  11 , kmREFUELING 284 , L100SR_TFT 14.7 , Fuel 48

kmTrip  22 , kmREFUELING 470 , L100SR_TFT 13.3 , Fuel 48

kmTrip  31 , kmREFUELING 470 , L100SR_TFT 13.3 , Fuel 46     остановка на работе. L100M и FuelTrip так и не появились

На сколько я понимаю L100SR_TFT вроде как работает , по тихоньку идет к адекватному расходу

kmREFUELING чета тоже там считает. L100M не выводит потому что, что-то происходить с FuelTrip

 

 

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

вывел на экран FuelIGN, запись происходит. нашел кое что, есть два байта отвечающих за топливо, в опкоме пишет , 17 байт топливо бак и 16 байт мгновеное топливо. я ставил 17 байт, а оказывается это байт датчика с панели, а 16 датчик бака. так вот при записи FuelIGN датчик еще не поднялся до конца а запись уже происходит 42 л а потом датчик доходит до своей позиции и показывает 46 л, но записано то уже 42, точка отсчета не та, по этому и L100SR_TFT такой большой. Поставвил 16 байт и теперь запись и уровень записывается одинаково. я ставил 17 байт так как он стабильный а 16 типа мгновенный, не стабильный. оставляю 16 байт.

Сделал пробный заезд. Теперь все стало на свои места, байт 16 даказывает что все работает, показывает пройденые км и средний расход за поездку. так же закоментировал строки для ограничения вывода после 1 и 5 км, они не нужны. Осталась одна проблема, болтание датчика в баке, из за этого бегающие расчеты и бегающие данные на экране, из за крена на повортах и подьемов и спусков . Думаю проблему можно решить так,  сложный вариант, не для моих мозгов, первая запись Fuel у нас записыватся для подсчета пртраченых литров, потом делать еще одни записи в ячейки для Fuel после старта, и каждые 30 секунд или 1 минуту подсчитывать среднее и выводить на экран и  кормить формулы этим средним подсчетом, тогда и  L100M будет стабильным и Fuel, ну и все что пляшет от Fuel. Я так думаю...... Не знаю как будет правильнее.  

Я правильно понял как  поменять с 10 км обновление до 5 км. В кавычках жирным это на что нужно поменять.

125        int kmeeprom = 10(5)
123        int kmL = 10(5)
 
087        int L100_Eeprom[11(6)]= {10,10,10,10,10,10,10,10,10,10,10(оставить 6 ячеек)};
 
 
180        for (int i = 0; i < 11(6); i++) L100_Eeprom [i]= EEPROM.read(i);
181        for (int i = 0; i < 11(6); i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];
 
 
247        for (int i = 0; i < 11(6); i++) L100_Eeprom [i]= EEPROM.read(i);
248        for (int i = 0; i < 11(6); i++) L100SR_TFT = L100SR_TFT +  L100_Eeprom [i];

 Подправленый скетч

/////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  #include <UTFT.h>
  #include <SPI.h>
  #include <EEPROM.h>
  
  
  //pin 20 SCL , 21 SDA датчик реального времени
  #include <Wire.h>
  #include "RTClib.h"
  RTC_DS3231 rtc;       
  
  //датчик наружней температуры
  #include <OneWire.h>
  #define ONE_WIRE_BUS 8   
  OneWire oneWire(ONE_WIRE_BUS);
  #include <DallasTemperature.h>
  DallasTemperature sensors(&oneWire);
  
  //датчик внутринней температуры и влаги
  #include "DHT.h"
  #define DHTPIN 9   
  #define DHTTYPE DHT22 
  DHT dht(DHTPIN, DHTTYPE);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  
 
  
  extern uint8_t GroteskBold16x32[];
 
  int x, y;
  char currentPage;

  float h;
  float t;

  
  bool Dvoet = 0;

  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
  #define mySerial_gauge Serial2
  
  #define TX_gauge 16
  #define TX 13

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

  int Fuel = 0;         //остаток топлива
  int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
  int Fuel_last = 0;   // для формул
  bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
  int FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
  
  
  
  int kmAge = 0;             //пробег, полученный со щитка приборов
  int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
  int kmAge_last = 0;       // для формул
  bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
  int kmTrip = 0;            //пробег за один цикл включения зажигания
  int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
  int km = 0;              // переменная для расчетов
  int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
  int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
  int kmREFUELING;            // пробег до заправки на остатке топлива 
  
  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);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD();
    myGLCD.clrScr();
    myTouch.InitTouch();
    myTouch.setPrecision(PREC_MEDIUM);
    myGLCD.setFont(GroteskBold16x32);   
    
    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.00;
    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);}
//  else    {if (millis() - prevPIDgauge> 1000) {PIDsGauge(); prevPIDgauge = millis();}}
    receive ();
    if (millis() - prevWatch > 3000)  { Watch (); prevWatch = millis(); Trip ();}
    if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}
    if (millis() - prevDvoet > 500)  { if (!Dvoet) {myGLCD.print(":", 285, 0);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
    Menu();
    LCDDataPrint();



   }

void Trip () {
  
  if (flagkmAgeIGN){
L100M = ((float)FuelTrip*100.00)/(float)kmTrip;
 if (L100M<0) L100M = 0;
 if (L100M>99) L100M = 99;
 
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;
}

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

if (kmTrip-km>kmL) {km=kmTrip; 

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

if (L100SR>0) kmREFUELING=((float)Fuel*100.00)/(float)L100SR;
else kmREFUELING=((float)Fuel*100.00)/(float)L100SR_TFT;

// тут записываем  L100SR последовательно в одну из 11 ячеек еепром
//EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
n_eeprom = EEPROM.read (12);
EEPROM.write(n_eeprom, L100SR*10); 
n_eeprom++; if (n_eeprom>10) n_eeprom=0;
EEPROM.write (12,n_eeprom);

}}
  
  
  }


   
   void LCDDataPrint(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
     
      myGLCD.setColor(255, 255, 255);
      myGLCD.printNumI(Speed, 350, 0, 3);
      
     if (currentPage == '0') {
       
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      //if (kmTrip>=1) 
      myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      //else myGLCD.print("0", 123, 75); 
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      if (Fuel<53) myGLCD.printNumI(Fuel, 210, 110,5);
      else myGLCD.print("MAX", 210, 110); 
      //if (kmTrip>=1) 
      myGLCD.printNumI(kmTrip, 60, 145,5);
      //else myGLCD.print("0", 123, 145);
      //if (FuelTrip>=1)
      myGLCD.printNumI(FuelTrip, 210, 145,5);
      //else myGLCD.print("0", 273, 145);

      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 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);
      
    }
   
    if (currentPage == '1') {
     
      myGLCD.printNumF(StaDaliv,1, 395, 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, 415, 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, 395, 145,'.',3);  
      myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
      myGLCD.printNumF(SolenPre, 0, 395, 215,'.', 3);
        
      }
     prevData = millis();
    }
   }
  
  ///////////////////////////////////////////////////////////////////////////
  
  //отправка запроса пид 2101
  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 софт сериал 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!!!");
    
   Fuel = MessageRxGauge[16]/2.00;
   kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.00;
if (Fuel<53){
if (!flagkmAgeIGN) { kmAgeIGN = kmAge; flagkmAgeIGN =1;}
if (!flagFuelIGN) { FuelIGN = Fuel; last-Fuel = 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));} //двигает воторой байт в2 и 3 соо
       }
    }
   


    //прописываем формулы к данным
   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
    }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  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 (myTouch.dataAvailable()) {
         myTouch.read();
         x=myTouch.getX(); 
         y=myTouch.getY();
      if (currentPage == '0') {
      buttonHomeTouch();
      buttonINF1Touch();
      buttonINF2Touch();
      buttonCHECKTouch();     }
      if (currentPage == '1') { 
     buttonHomeTouch();
     buttonINF2Touch();
     buttonCHECKTouch();     }
      if (currentPage == '2') { 
     buttonHomeTouch();
     buttonINF1Touch();
     buttonCHECKTouch();      }
      if (currentPage == '3') { 
      buttonHomeTouch();
      buttonREADTouch();
      buttonERASETouch(); }}}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописывает заголовки на страницах
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   void drawHomeScreen() {
     line() ;
     Watch ();
     myGLCD.drawLine(295,35,295,248); // линия вертикальная
     myGLCD.setColor(0, 255, 0); // цвет линии зеленый
     myGLCD.drawLine(145,35,145,178); // линия вертикальная
     myGLCD.drawLine(1,178,295,178); // линия горизонтальная
     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", 10, 180);
     myGLCD.print("Engi RPM", 10, 215);
     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("IntAirC", 300, 215);
     buttonHome() ;
     buttonINF1() ;
     buttonINF2() ;
     buttonCHECK() ;
   }
  //-------------------------------------------------
    void drawscreen_one() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF2() ;
     buttonCHECK() ;
     }
  //-------------------------------------------------
   void drawscreen_two() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF1() ;
     buttonCHECK() ;
   }
  //----------------------------------------------------------------------------
   void drawscreen_three() {
     Watch ();
     myGLCD.setColor(255, 0, 0); // цвет линии красный
     myGLCD.drawLine(1,35,479,35); // линия горизонтальная
     myGLCD.drawLine(1,248,479,248); // линия горизонтальная
     buttonHome();
     buttonERASE();
     buttonREAD();
   }

  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //координаты тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawFrame(int x1, int y1, int x2, int y2) {
     myGLCD.setColor(255, 0, 0);
     myGLCD.drawRoundRect (x1, y1, x2, y2);
     while (myTouch.dataAvailable())
     myTouch.read();
     myGLCD.setColor(255, 255, 255); 
   }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка кнопок и координат тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void buttonHome() {
     myGLCD.setColor(0,0,0); // цвет кнопки -серый
     myGLCD.fillRoundRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
     myGLCD.setColor(255, 255,255); // цвет текста зеленый
     myGLCD.drawRoundRect (1, 1, 65, 33);      // кнопка будет рамкой
     myGLCD.print("HOME", 1, 0); // центровка строки
    }

    void buttonHomeTouch(){
      if ((x>=1) && (x<=65) &&(y>=1) && (y<=33)) {
        drawFrame(1, 1, 65, 33);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen(); 
       
      }}

     
     
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("INF 1", 25, 265);
    }
   void buttonINF1Touch() {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();       
       
      } }

   
  void buttonINF2() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (180, 255, 300, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (180, 255, 300, 310);
     myGLCD.print("INF 2", 200, 265);
    }
  void buttonINF2Touch() {
    if ((x>=180) && (x<=300) && (y>=255) && (y<=310)) {
        drawFrame(180, 255, 300, 310); 
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();   
                                                                      
      }}
  
  void buttonCHECK() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("CHECK", 375, 265);
    }
  void buttonCHECKTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();   
                                                                         
      } }

  
    void buttonERASE() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("ERASE", 25, 265);
    }
    
    void buttonERASETouch () {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        Erase();           //потом заменить на дейсвие
              
                                                                         
      }}
      
    void buttonREAD() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("READ", 375, 265);
    }
    
    void buttonREADTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        Read();        //потом заменить на дейсвие   
        
                                                                           
      }}

  ////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка линий
  ///////////////////////////////////////////////////////////////////////////////////////
  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(0, 255, 0); //зеленый цвет цифры
  
    if (date<10) { 
    myGLCD.print("0", 85, 0); 
    myGLCD.printNumI(now.day(), 100, 0); } 
    else if (date >=10) {
    myGLCD.printNumI(now.day(), 85, 0); }
    myGLCD.print("/", 115, 0);
    if ( mon<10) {
    myGLCD.print("0", 130, 0); 
    myGLCD.printNumI(now.month(), 145, 0);} 
    else if (mon >=10) {
    myGLCD.printNumI(now.month(), 130, 0);}  
    myGLCD.print("/", 160, 0);
    myGLCD.printNumI(now.year(), 175, 0);
    if (hour<10) {
    myGLCD.print("0",255, 0); 
    myGLCD.printNumI(now.hour(), 270, 0); } 
    else if(hour>=10){ 
    myGLCD.printNumI(now.hour(), 255, 0); } 
    if (m<10) {
    myGLCD.print("0",300, 0); 
    myGLCD.printNumI(now.minute(), 315, 0); } 
    else if (m>=10){ 
    myGLCD.printNumI(now.minute(), 300, 0); }
    myGLCD.print("Km/h", 410, 0);
 
  
 }
  void Temperature (){
    h = dht.readHumidity();
    t = dht.readTemperature();
    sensors.requestTemperatures();
    }
 

Остался последний штрих.

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

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

Чтобы сделать на 5 км надо только строки 123 и 125 поменять как ты указал и ВСЁ. Осталльные не трогай

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

блин а может оставить 17 байт, но сделать при старте записи Fuel задержку секунд 10 и проблема решена? 

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

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

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

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

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

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

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

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

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

не заню. если бы другая то в опкоме бы показывало разные цифры на бак и на датчик. но они были одинаковы. один раз видел 54 но не более того. при следующей заправке проверю байты в мониторе на разницу. это сильно поменят дело? или не столь важно? если что то потом 53 можно будет подправить. 

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

да к стати я менял 123 и 125, все равно выдало данные на 11 километре. но проверю еще раз.

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

viki13viki пишет:

не заню. если бы другая то в опкоме бы показывало разные цифры на бак и на датчик. но они были одинаковы. один раз видел 54 но не более того. при следующей заправке проверю байты в мониторе на разницу. это сильно поменят дело? или не столь важно? если что то потом 53 можно будет подправить. 

да нет, не важно это вобщемто, так мысли вслух

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

понял. но все равно ради интереса потом проверю

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

скетч 1082 строка 440 замени её на эту:

if (!flagFuelIGN) { FuelIGN = Fuel; last-Fuel = Fuel; flagFuelIGN = 1; }}

это чтобы первый замер был правильный. А то на первом замере L100SR будет 0 .  

 

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

1082 подправил

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

Сделал так. при старте идет запись в FuelIGN. Как только он записался, Fuel начинает вычисляться подругому - делается 10 замеров и считается среднеарифметическое, пэтому Fuel должен более плавно менятся. 

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

т.е. если Fuel будет больше чем FuelIGN на 5 л (исключить колебания 5 л хватит) - то значит идёт заправка, скидываем все расчеты до момента, как будто только включено зажигание

/////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  #include <UTFT.h>
  #include <SPI.h>
  #include <EEPROM.h>
  
  
  //pin 20 SCL , 21 SDA датчик реального времени
  #include <Wire.h>
  #include "RTClib.h"
  RTC_DS3231 rtc;       
  
  //датчик наружней температуры
  #include <OneWire.h>
  #define ONE_WIRE_BUS 8   
  OneWire oneWire(ONE_WIRE_BUS);
  #include <DallasTemperature.h>
  DallasTemperature sensors(&oneWire);
  
  //датчик внутринней температуры и влаги
  #include "DHT.h"
  #define DHTPIN 9   
  #define DHTTYPE DHT22 
  DHT dht(DHTPIN, DHTTYPE);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  
 
  
  extern uint8_t GroteskBold16x32[];
 
  int x, y;
  char currentPage;

  float h;
  float t;

  
  bool Dvoet = 0;

  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
  #define mySerial_gauge Serial2
  
  #define TX_gauge 16
  #define TX 13

  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

  int Fuel = 0;         //остаток топлива
  int FuelIGN = 0;      // количество топлвива в баке на момент включения зажигания
  int Fuel_last = 0;   // для формул
  bool flagFuelIGN = 0; // флаг записан ли остаток топлива в момент вкл. зажигания 
  int FuelTrip = 0;     // количество литров топлива, израсходованное за один цикл включения зажигания
  
  
  
  int kmAge = 0;             //пробег, полученный со щитка приборов
  int kmAgeIGN = 0;          //пробег который был в момент включения зажигания 
  int kmAge_last = 0;       // для формул
  bool flagkmAgeIGN = 0;     //флаг записан ли пробег в момент вкл. зажигания 
  int kmTrip = 0;            //пробег за один цикл включения зажигания
  int kmL = 10;               // интервал, через который будет происходить обновление среднего расхода на 100км
  int km = 0;              // переменная для расчетов
  int kmeeprom = 10;         // интервал, через который будет происходить подсчет среднеарифмитического расхода  L100SR_TFT
  int kmTFT =  0;     // переменная для расчетов периодического подсчета среднеарифмитического расхода топлива L100SR_TFT
  int kmREFUELING;            // пробег до заправки на остатке топлива 
  
  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);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD();
    myGLCD.clrScr();
    myTouch.InitTouch();
    myTouch.setPrecision(PREC_MEDIUM);
    myGLCD.setFont(GroteskBold16x32);   
    
    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.00;
    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(":", 285, 0);} else {myGLCD.print(" ", 285, 0);} prevDvoet = millis(); Dvoet=!Dvoet;}
    Menu();
    LCDDataPrint();



   }

void Trip () {
  
  if (flagkmAgeIGN){

if (Fuel > FuelIGN + 5) {flagkmAgeIGN = 0; flagFuelIGN = 0; kmTFT = 0; km = 0;}

FuelTrip = FuelIGN - Fuel;                          
if (kmAge>kmAgeIGN) kmTrip = kmAge - kmAgeIGN;
if (kmAge<kmAgeIGN) kmTrip = 2000 - (kmAgeIGN - kmAge);  // 2000 это через сколько км у тебя суточный пробег сбрасывается на ноль, поменяй если другое число
if (kmAge==kmAgeIGN) kmTrip = 0;
    
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км
Fuel_last = Fuel;      // сохранение параметров с последнего измерениея
if (L100SR<0) L100SR = 0;
if (L100SR>99) L100SR = 99;
 

if (L100SR>0) kmREFUELING=((float)Fuel*100.00)/(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(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
     
      myGLCD.setColor(255, 255, 255);
      myGLCD.printNumI(Speed, 350, 0, 3);
      
     if (currentPage == '0') {
       
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      //if (kmTrip>=1) 
      myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      //else myGLCD.print("0", 123, 75); 
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      if (Fuel<53) myGLCD.printNumI(Fuel, 210, 110,5);
      else myGLCD.print("MAX", 210, 110); 
      //if (kmTrip>=1) 
      myGLCD.printNumI(kmTrip, 60, 145,5);
      //else myGLCD.print("0", 123, 145);
      //if (FuelTrip>=1)
      myGLCD.printNumI(FuelTrip, 210, 145,5);
      //else myGLCD.print("0", 273, 145);

      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 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);
      
    }
   
    if (currentPage == '1') {
     
      myGLCD.printNumF(StaDaliv,1, 395, 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, 415, 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, 395, 145,'.',3);  
      myGLCD.printNumF(SolenPul, 1, 395, 180,'.', 4);  
      myGLCD.printNumF(SolenPre, 0, 395, 215,'.', 3);
        
      }
     prevData = millis();
    }
   }
  
  ///////////////////////////////////////////////////////////////////////////
  
  //отправка запроса пид 2101
  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 софт сериал 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!!!");
    
if (!flagFuelIGN)   Fuel = MessageRxGauge[16]/2.00;
else { FuelZamer[ZamerNumber] = MessageRxGauge[16]/2.00;
  ZamerNumber++; if (ZamerNumber>9) ZamerNumber = 0;
  if (ZamerNumber==9) {
  for (int i = 0; i < 10; i++) Fuel = Fuel + FuelZamer[i];
  Fuel = (float)Fuel/10.0;}
     }

   kmAge = (MessageRxGauge[23]+(MessageRxGauge[24]*256))/10.00;


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));} //двигает воторой байт в2 и 3 соо
       }
    }
   


    //прописываем формулы к данным
   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
    }

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  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 (myTouch.dataAvailable()) {
         myTouch.read();
         x=myTouch.getX(); 
         y=myTouch.getY();
      if (currentPage == '0') {
      buttonHomeTouch();
      buttonINF1Touch();
      buttonINF2Touch();
      buttonCHECKTouch();     }
      if (currentPage == '1') { 
     buttonHomeTouch();
     buttonINF2Touch();
     buttonCHECKTouch();     }
      if (currentPage == '2') { 
     buttonHomeTouch();
     buttonINF1Touch();
     buttonCHECKTouch();      }
      if (currentPage == '3') { 
      buttonHomeTouch();
      buttonREADTouch();
      buttonERASETouch(); }}}
  
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прописывает заголовки на страницах
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   void drawHomeScreen() {
     line() ;
     Watch ();
     myGLCD.drawLine(295,35,295,248); // линия вертикальная
     myGLCD.setColor(0, 255, 0); // цвет линии зеленый
     myGLCD.drawLine(145,35,145,178); // линия вертикальная
     myGLCD.drawLine(1,178,295,178); // линия горизонтальная
     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", 10, 180);
     myGLCD.print("Engi RPM", 10, 215);
     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("IntAirC", 300, 215);
     buttonHome() ;
     buttonINF1() ;
     buttonINF2() ;
     buttonCHECK() ;
   }
  //-------------------------------------------------
    void drawscreen_one() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF2() ;
     buttonCHECK() ;
     }
  //-------------------------------------------------
   void drawscreen_two() {
     line() ;
     Watch ();
     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);
     buttonHome() ;
     buttonINF1() ;
     buttonCHECK() ;
   }
  //----------------------------------------------------------------------------
   void drawscreen_three() {
     Watch ();
     myGLCD.setColor(255, 0, 0); // цвет линии красный
     myGLCD.drawLine(1,35,479,35); // линия горизонтальная
     myGLCD.drawLine(1,248,479,248); // линия горизонтальная
     buttonHome();
     buttonERASE();
     buttonREAD();
   }

  ////////////////////////////////////////////////////////////////////////////////////////////////////////
  //координаты тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawFrame(int x1, int y1, int x2, int y2) {
     myGLCD.setColor(255, 0, 0);
     myGLCD.drawRoundRect (x1, y1, x2, y2);
     while (myTouch.dataAvailable())
     myTouch.read();
     myGLCD.setColor(255, 255, 255); 
   }

  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка кнопок и координат тача
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  void buttonHome() {
     myGLCD.setColor(0,0,0); // цвет кнопки -серый
     myGLCD.fillRoundRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
     myGLCD.setColor(255, 255,255); // цвет текста зеленый
     myGLCD.drawRoundRect (1, 1, 65, 33);      // кнопка будет рамкой
     myGLCD.print("HOME", 1, 0); // центровка строки
    }

    void buttonHomeTouch(){
      if ((x>=1) && (x<=65) &&(y>=1) && (y<=33)) {
        drawFrame(1, 1, 65, 33);
        currentPage = '0';
        myGLCD.clrScr();
        drawHomeScreen(); 
       
      }}

     
     
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("INF 1", 25, 265);
    }
   void buttonINF1Touch() {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        currentPage = '1';           
        myGLCD.clrScr();             
        drawscreen_one();       
       
      } }

   
  void buttonINF2() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (180, 255, 300, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (180, 255, 300, 310);
     myGLCD.print("INF 2", 200, 265);
    }
  void buttonINF2Touch() {
    if ((x>=180) && (x<=300) && (y>=255) && (y<=310)) {
        drawFrame(180, 255, 300, 310); 
        currentPage = '2';           
        myGLCD.clrScr();             
        drawscreen_two();   
                                                                      
      }}
  
  void buttonCHECK() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("CHECK", 375, 265);
    }
  void buttonCHECKTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        currentPage = '3';           
        myGLCD.clrScr();             
        drawscreen_three();   
                                                                         
      } }

  
    void buttonERASE() {
    myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (10, 255, 120, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (10, 255, 120, 310);
     myGLCD.print("ERASE", 25, 265);
    }
    
    void buttonERASETouch () {
    if ((x>=10) && (x<=120) && (y>=255) && (y<=310)) {
        drawFrame(10, 255, 120, 310); 
        Erase();           //потом заменить на дейсвие
              
                                                                         
      }}
      
    void buttonREAD() {
     myGLCD.setColor(0,0,0);
     myGLCD.fillRoundRect (350, 255, 470, 310);
     myGLCD.setColor(0, 255, 0);
     myGLCD.drawRoundRect (350, 255, 470, 310);
     myGLCD.print("READ", 375, 265);
    }
    
    void buttonREADTouch() {
    if ((x>=350) && (x<=470) && (y>=255) && (y<=310)) {
        drawFrame(350, 255, 470, 310); 
        Read();        //потом заменить на дейсвие   
        
                                                                           
      }}

  ////////////////////////////////////////////////////////////////////////////////////////
  //прорисовка линий
  ///////////////////////////////////////////////////////////////////////////////////////
  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(0, 255, 0); //зеленый цвет цифры
  
    if (date<10) { 
    myGLCD.print("0", 85, 0); 
    myGLCD.printNumI(now.day(), 100, 0); } 
    else if (date >=10) {
    myGLCD.printNumI(now.day(), 85, 0); }
    myGLCD.print("/", 115, 0);
    if ( mon<10) {
    myGLCD.print("0", 130, 0); 
    myGLCD.printNumI(now.month(), 145, 0);} 
    else if (mon >=10) {
    myGLCD.printNumI(now.month(), 130, 0);}  
    myGLCD.print("/", 160, 0);
    myGLCD.printNumI(now.year(), 175, 0);
    if (hour<10) {
    myGLCD.print("0",255, 0); 
    myGLCD.printNumI(now.hour(), 270, 0); } 
    else if(hour>=10){ 
    myGLCD.printNumI(now.hour(), 255, 0); } 
    if (m<10) {
    myGLCD.print("0",300, 0); 
    myGLCD.printNumI(now.minute(), 315, 0); } 
    else if (m>=10){ 
    myGLCD.printNumI(now.minute(), 300, 0); }
    myGLCD.print("Km/h", 410, 0);
 
  
 }
  void Temperature (){
    h = dht.readHumidity();
    t = dht.readTemperature();
    sensors.requestTemperatures();
    }
 

 

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

Как раз еду домой и посмотрим

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

Первый косяк это, начал ехать и kmtrip начал давать сбои, дошёл до 3 км и сбился на 0, потом 6 и на 0, потом на 4,потом на 6, последние км доехал домой накрутил 7 км не сбившись на 0. Второй косяк это, при первом перерасчете выдало 447 км в баке, второй раз попало в расчёте на такие цифры что выдало 78 км в баке. Может все таки Fuel записывать в ячейки и выводить среднее значение на экран и кормить средним формулы? Слишком нестабильные данные бака. Беспонятия

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

дак вообщето так и пытался сделать.

закоментируй сначала строку 244. Это фишечка для заправки с вкл. зажиганием. Может она глючит. 

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

как проявляется нестабильность данных бака?  данные бака разве не стали более инерционными?

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

Да более инерционные, но выводит то на что попало в момент вывода, то есть, то висит 46 то 50 то 46 то 48 то MAX, короче на что попадет. Формулы я думаю так же попадают на разные цифры, слишком в разном диапазоне,вот и лажа что выдало в баке 447км а потом 78 км.