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

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

MaksVV дружище, если обьявишся дай знать, оооооочень нужна твоя помощь.

 

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

Приветствую! говори

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

MaksVV такое дело. У меня начал выпендриватся тач, по пречине что изначально китайцы не поставили шлейф, я поставил, но суть не в этом. Хочу заменить другой экран, но.... проблема, что такие экраны как у меня был ( с широкой шиной пинов под мегу + гребенки по бокам, ниже фото) уже не суцествует в природе, есть только совместимы с мегой (которые имеют гребенку пинов по бокам, ниже фото). Купил такой, он не работает с UTFT и UTFTTouch библой, пытался в библах прописать пины тача и экрана, результат белый экран, а работает с скачать MCUFRIEND_kbv  и скачать Adafruit-TouchScreen и эта библа понадобится скачать Adafruit GFX graphics так как экран выдает ид  ID=0x1581 то там вроде чип R61581. Думал отделатся малой кровью, но...., там фунции и имена отличаются. Я взял с этой библы пробу тача и вывод текста на экра и скрестил их, получил текст на экране и корды тача выдаваемые в порту. В библе mcufriend_kbv есть пример GLUE_Demo_480x320, там функции и имена как в UTFT, но он не работает. Чувствую еще тот гемор будет со скетчем. Задача переделать скетч  под эти библы и не потерять функционал скетча. Я пробовал некоторые вещи типа замены myGLCD.print на tft.print но там функции отличаются вот и вываливается куча ошибок в компиляции. Я выложу вечером скетчи. Глянь как это можно реализовать, буду очень признателен.

P.S. Если решим эту проблему, выложу и под такие экраны, так как все смогут купить под мегу только совместимы, как купил я.

Был с такими пинами

купил с таким пинами 

Нашел уже кое-что. в библе MCUFRIEND_kbv есть некий файл UTFTGLUE.h, он работает как переводчик между UTFT и Adafruit. В скетче по идеи ничего менять не нужно, НО ЕЩЕ НЕ ПРОБОВАЛ, завтра попробую. Если запустится останится разобратся с тачем, я заносил все параметры в скетч для подключения TouccScreen библы до тех пор, пока скетч не начал выдавать ошибки. вод скетч который подправил:

IDE 1.8.9 испльзую

  /////////////////////////////////////////////////////////////////////////////////////////
  //библиотеки
  ///////////////////////////////////////////////////////////////////////////////////////////
  #include <UTouch.h>
  //#include <UTFT.h>
  #include <UTFTGLUE.h>//use GLUE class and constructor
  #include "TouchScreen.h"
  #include <stdint.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);
  
  ///////////////////////////////////////////////////////////////////////////////////
  //пины экрана и тача
  ///////////////////////////////////////////////////////////////////////////////////
  #define YP A1  // must be an analog pin, use "An" notation!
  #define XM A2  // must be an analog pin, use "An" notation!
  #define YM 6  // can be a digital pin
  #define XP 7   // can be a digital pin
  UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
  //UTFT    myGLCD(31,38,39,40,41); 
  UTouch  myTouch(6,5,4,3,2);
  TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
  //#define TFTWIDTH 320
  //#define TFTHEIGHT 480
  #define MINPRESSURE 10
  #define MAXPRESSURE 1000
  extern uint8_t GroteskBold16x32[];
  int x, y;
  char currentPage;
  float h;
  float t;
  bool Dvoet = 0;
  //////////////////////////////////////////////////////////////////////////////
  //все что касается OBD2
  ///////////////////////////////////////////////////////////////////////////////
  #include <SoftwareSerial.h>
  #define mySerial_gauge Serial2
  #define TX_gauge 16
  #define TX 13
  SoftwareSerial mySerial   (12, 13); //RХ,TХ
  
  int length5 = 5;
  int length6 = 6;
  int length8 = 8;
  int length7 = 7;

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

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

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

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

  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  //SETUP
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    uint16_t ID;
    
    void setup() {
      myGLCD.setRotation(2);
    ID = myGLCD.readID(); 
    if (ID == 0x1581) ID = 0x1581;
    myGLCD.begin(ID);  
    Serial.begin(115200);
    mySerial.begin(10400);
    Wire.begin();
    rtc.begin();
    dht.begin();
    sensors.begin();
    myGLCD.InitLCD(3);
    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.0;
    if (L100SR_TFT<0) L100SR_TFT = 0;
    if (L100SR_TFT>99) L100SR_TFT = 99;
    
    // строка ниже используется для настройки даты и времени часов 
    // раскоментировать, выставить времая и дату, залить в ардуино. в скетче закоментировать
    // обратно и залить еще раз, иначе каждый раз будет по новой выствлятся это же время и дата
    // (год, месяц, день, часы, минуты, секунды)
    //rtc.adjust(DateTime(2017, 7, 21, 13, 57, 0));

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

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

   void loop() {

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

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

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

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

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

  // тут записываем  L100SR последовательно в одну из 11 ячеек еепром
  //EEPROM.write (12,n_eeprom);      // ЗДЕСЬ ВНИМАТЕЛЬНО. ЗАГРУЗИТЬ ПРОШИВКУ С ЭТОЙ СТРОКОЙ ОДИН РАЗ, ПОТОМ ЗАКОМЕНТИРОВАТЬ И ЕЩЁ РАЗ ЗАГРУЗИТЬ
  n_eeprom = EEPROM.read (12);    // в ячейке 12 хранится № текущей ячейки для записи расхода, чтобы где остановился при выкл питания, от туда и продолжил
  EEPROM.write(n_eeprom, L100SR*10); 
  n_eeprom++; if (n_eeprom>10) n_eeprom=0;
  EEPROM.write (12,n_eeprom); }}}
  
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
  //BOID LCDDATAPRINT. прописываем данные и их расположение и цвет/////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////////////////////////////////////
   void LCDDataPrint(){
    unsigned long curData = millis();  
      
   if (millis() - prevData > Datadelay){  
      myGLCD.setColor(255, 255, 255);      //цвет текста
      myGLCD.printNumI(Speed, 350, 0, 3);
   //----------------------------------------------------------
   //страниц HOME
   //----------------------------------------------------------
   if (currentPage == '0') { 
      myGLCD.printNumF(LHor, 1, 60, 40, '.',5);
      myGLCD.printNumF(L100, 1, 210, 40,'.',5 );
      myGLCD.printNumF(L100M, 1, 60, 75,'.',5 );
      myGLCD.printNumF(L100SR_TFT, 1, 210, 75,'.',5 );
      myGLCD.printNumI(kmREFUELING, 60, 110,5 ); 
      //if (Fuel<53) 
      myGLCD.printNumF(Fuel, 1, 210, 110,'.',5);
      //else myGLCD.print("MAX", 210, 110); 
      myGLCD.printNumF(kmTrip, 1, 60, 145,'.',5);
      myGLCD.printNumF(FuelTrip, 1, 210, 145,'.',5);
      myGLCD.printNumI(PumpRPM, 210, 180,5);
      myGLCD.printNumI(RPM, 210, 215,5);
      myGLCD.printNumF(Fuel2, 1, 0, 215,'.',5);      
      myGLCD.printNumI(Temp, 415, 40, 3);
      myGLCD.printNumI(TempOil, 415, 75, 3);
      myGLCD.printNumI(TempFuel, 415, 110,3); 
      myGLCD.printNumI(sensors.getTempCByIndex(0), 415, 145 , 3);
      myGLCD.printNumI(t, 415, 180, 3);
      myGLCD.printNumI(TempAir, 415, 215, 3); }
    //----------------------------------------------------------
    //страниц INF1
    //----------------------------------------------------------
    if (currentPage == '1') {
      myGLCD.printNumF(StaDaliv,1, 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(); }}
  
  ///////////////////////////////////////////////////////////////////////////
  //BOID PIDs//отправка запроса пид 2101/////////////////////////////////////
  ///////////////////////////////////////////////////////////////////////////
  void PIDs() {
    Serial.println ("Otpravil zapros 21 01");
    for (int i = 0; i < length6; i++) {
    mySerial.write(messagePids[i]);
    delay (waitbyte); }}
	
  ///////////////////////////////////////////////////////////////////////////
  //BOID PIDsGAUGR//отправка запроса на панель приборов//////////////////////
  ///////////////////////////////////////////////////////////////////////////
  void PIDsGauge() {
   Serial.println ("                Otpravil zapros 02 11 na panel");
   mySerial_gauge.write (0x02);    delay (1);
   mySerial_gauge.write (0x11);    delay (1);
   mySerial_gauge.write(byte(0));  delay (1);
   mySerial_gauge.write (0x13); }
  
  ///////////////////////////////////////////////////////////////////////////
  //BOID PIDsGAUGR//отправка запроса присутствия/////////////////////////////
  ///////////////////////////////////////////////////////////////////////////
  void present() {
   Serial.println ("Otpravil zapros Present");
    for (int i = 0; i < length5; i++) {
    mySerial.write(messagePresent[i]);
    delay (waitbyte); }}
  
  /////////////////////////////////////////////////////////////////////////////////////////////
  //получение данных от ЭБУ, разборка входящих сообщений
  /////////////////////////////////////////////////////////////////////////////////////////////
   void receive () {
   ///////////////////////////////////////////////////////////////////////
   ////////////////// работа с К-Line софт сериал 16-17 (12 контакт ОБД)
   ///////////////////////////////////////////////////////////////////////
   while(!InitGauge){
    if (mySerial_gauge.available()) {
    byte inByte = mySerial_gauge.read();
    Serial.print(" ");
    Serial.print(inByte,HEX);
   if (inByte==0x80) {mySerial_gauge.write (0x7F); delay (1);}
   if (inByte==0xF0) {
     mySerial_gauge.write (0x02);  delay (1);
     mySerial_gauge.write (0x11);  delay (1);
     mySerial_gauge.write (0x00);  delay (1);
     mySerial_gauge.write (0x13);  delay (1); InitGauge=1;  }}}
   
   MessageParse = 0;
   while (InitGauge && !MessageParse) {
    if (!dataMessageOK) {   
     if (mySerial_gauge.read() == 0x23) {byte0=1; delay (waitbyte_gauge); }    
     if (mySerial_gauge.read() == 0xA1 && byte0) {byte1=1; delay (waitbyte_gauge);}
     else byte0=0;
     if (mySerial_gauge.read() == 0x04 && byte0 && byte1) {byte2=1; delay (waitbyte_gauge);}
     else {byte0=0; byte1=0;}
     if (byte0 && byte1 && byte2) {dataMessageOK = 1; byte0=0; byte1=0; byte2=0;}
     numberbyte=0;}
     
	else { if (mySerial_gauge.available()>0)  { MessageRxGauge[numberbyte] = mySerial_gauge.read(); numberbyte++; delayMicroseconds (250);}  
     if (numberbyte==34) {dataMessageEND = 1; dataMessageOK = 0; }}
      
   if (dataMessageEND) { 
    int crc =  ( ( unsigned int )MessageRxGauge[32] << 8 ) | MessageRxGauge[33]; // парсинг контрольной суммы из 2 последних байт 
    int CRC =200;
    for (int i = 0; i < 32; i++) CRC = CRC + MessageRxGauge[i];                 // подсчет контрольной суммы байт от 0 до 31

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

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

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

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

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

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

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

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

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


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

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

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

  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  //запрос чтения и стирания ошибок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////
  
  void Read() {
    Serial.println ("Zapros error;  ");
    for (int i = 0; i < length8; i++) {
    mySerial.write(messageREAD[i]);
    delay (waitbyte); }}
    
  void Erase() {
    Serial.println ("Zapros erase;  ");
    for (int i = 0; i < length7; i++) {
    mySerial.write(messageERASE[i]);
    delay (waitbyte); }}
  
  //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
  //прорисовка тач кнопок
  ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void Menu () {
      if (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", 82, 180);
     myGLCD.print("Engi RPM", 82, 215);
     myGLCD.print("D/La", 10, 180);
     myGLCD.print("Motor C", 300, 40);
     myGLCD.print("Oil   C", 300, 75);
     myGLCD.print("Fuel  C", 300, 110);
     myGLCD.print("Inter C", 300, 145);
     myGLCD.print("Exter C", 300, 180);
     myGLCD.print("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(); }
 

По идеи нужно будет 

39 закоментить, и в 8ми строках где myTouch правильно прописать

заработало но отображение корявое. ща буду капать.

 

 

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

и че как в итоге эти алгоритмы с расходами топлива  и остатком до заправки? работают или далеки от правды? 

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

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

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

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 //#include "Fonts/GroteskBold16x32.h" 

 //Adafruit_GFX_Button buttonHome, buttonINF1, buttonINF2, buttonCHECK, buttonERASE, buttonREAD;

 extern uint8_t GroteskBold16x32[];
 #define BLACK   0x0000

 #define MINPRESSURE 200
 #define MAXPRESSURE 1000

 #define BLACK   0x0000
 #define BLUE    0x001F
 #define RED     0xF800
 #define GREEN   0x07E0
 #define CYAN    0x07FF
 #define MAGENTA 0xF81F
 #define YELLOW  0xFFE0
 #define WHITE   0xFFFF
 
 //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);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 //#define YP A1  // must be an analog pin, use "An" notation!
 //#define XM A2  // must be an analog pin, use "An" notation!
 //#define YM 6  // can be a digital pin
 //#define XP 7   // can be a digital pin
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 //оринтеровка тача под myGLCD.setRotation(3);
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 int pixel_x, pixel_y;     //Touch_getXY() updates global vars
 bool Touch_getXY(void)
 {
    TSPoint p = ts.getPoint();
    pinMode(YP, OUTPUT);      //restore shared pins
    pinMode(XM, OUTPUT);
    digitalWrite(YP, HIGH);   //because TFT control pins
    digitalWrite(XM, HIGH);
    bool pressed = (p.z > MINPRESSURE && p.z < MAXPRESSURE);
    if (pressed) {
        pixel_x = map(p.x, TS_LEFT, TS_RT, 0, tft.width()); //.kbv makes sense to me
        pixel_y = map(p.y, TS_TOP, TS_BOT, 0, tft.height());
    }
    return pressed;
 }
 
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

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

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

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

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

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

 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //SETUP
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   uint16_t ID;
   
   void setup() {
   ID = myGLCD.readID(); 
   if (ID == 0x1581) ID = 0x1581;
   myGLCD.begin(ID);  
   Serial.begin(115200);
   mySerial.begin(10400);
   Wire.begin();
   rtc.begin();
   dht.begin();
   sensors.begin();
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   
   //myGLCD.setFont(GroteskBold16x32);
   //buttonINF1.initButton(&myGLCD,  10, 255, 130, 310, WHITE, CYAN, BLACK, "INF1", 2);   
   
   //загрузка стартовой страницы
   currentPage = '0';       
   drawHomeScreen();  

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

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

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

  void loop() {

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 //запрос чтения и стирания ошибок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////
 
 void Read() {
   Serial.println ("Zapros error;  ");
   for (int i = 0; i < length8; i++) {
   mySerial.write(messageREAD[i]);
   delay (waitbyte); }}
   
 void Erase() {
   Serial.println ("Zapros erase;  ");
   for (int i = 0; i < length7; i++) {
   mySerial.write(messageERASE[i]);
   delay (waitbyte); }}
 
 //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////  
 //прорисовка тач кнопок
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
 //прописывает заголовки и кнопки на страницах
 ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  void drawHomeScreen() {
    line() ;
    Watch ();
    myGLCD.setColor(255, 0, 0); // цвет линии и текста красный
    myGLCD.drawLine(295,35,295,248); // линия вертикальная
    myGLCD.drawLine(145,35,145,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", 82, 180);
    myGLCD.print("Engi RPM", 82, 215);
    myGLCD.print("D/La", 10, 180);
    myGLCD.print("Motor C", 300, 40);
    myGLCD.print("Oil   C", 300, 75);
    myGLCD.print("Fuel  C", 300, 110);
    myGLCD.print("Inter C", 300, 145);
    myGLCD.print("Exter C", 300, 180);
    myGLCD.print("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 buttonHome() {
    myGLCD.setColor(0,0,0); // цвет кнопки черный
    myGLCD.fillRect (1, 1, 80, 33);      // расположение кнопки прямоугольника
    myGLCD.setColor(255, 0, 0); // рамка будет красный
    myGLCD.drawRect (1, 1, 80, 33);      // кнопка будет рамкой
    myGLCD.print("HOME", 1, 0); }// центровка строки
 
   
  void buttonINF1() {
    myGLCD.setColor(0,0,0);
    myGLCD.fillRect (10, 255, 130, 310);
    myGLCD.setColor(255, 0, 0);  
    myGLCD.drawRect (10, 255, 130, 310);
    myGLCD.print("INF 1", 25, 265); }
  
  
  void buttonINF2() {
    myGLCD.setColor(0,0,0);
    myGLCD.fillRect (180, 255, 300, 310);
    myGLCD.setColor(255, 0, 0);
    myGLCD.drawRect (180, 255, 300, 310);
    myGLCD.print("INF 2", 200, 265); }
 
 
 void buttonCHECK() {
    myGLCD.setColor(0,0,0);
    myGLCD.fillRect (350, 255, 470, 310);
    myGLCD.setColor(255, 0, 0);
    myGLCD.drawRect (350, 255, 470, 310);
    myGLCD.print("CHECK", 375, 265);}
 
 
   void buttonERASE() {
   myGLCD.setColor(0,0,0);
    myGLCD.fillRect (10, 255, 120, 310);
    myGLCD.setColor(255, 0, 0);
    myGLCD.drawRect (10, 255, 120, 310);
    myGLCD.print("ERASE", 25, 265); }
   
  
   void buttonREAD() {
    myGLCD.setColor(0,0,0);
    myGLCD.fillRect (350, 255, 470, 310);
    myGLCD.setColor(255, 0, 0);
    myGLCD.drawRect (350, 255, 470, 310);
    myGLCD.print("READ", 375, 265); }
   
  
 ////////////////////////////////////////////////////////////////////////////////////////
 //прорисовка линий
 ///////////////////////////////////////////////////////////////////////////////////////
 void line() {
    myGLCD.setColor(255, 0, 0); // цвет линии красный
    myGLCD.drawLine(1,35,479,35); // линия горизонтальная
    myGLCD.drawLine(1,73,479,73); // линия горизонтальная
    myGLCD.drawLine(1,108,479,108); // линия горизонтальная
    myGLCD.drawLine(1,143,479,143); // линия горизонтальная
    myGLCD.drawLine(1,178,479,178); // линия горизонтальная
    myGLCD.drawLine(1,212,479,212); // линия горизонтальная
    myGLCD.drawLine(1,248,479,248); }// линия горизонтальная


 /////////////////////////////////////////////////////////////////////////////////////////////
 //верхняя часть экрана часы и дата отображается на всех экранах
 /////////////////////////////////////////////////////////////////////////////////////////////
 void Watch (){
   DateTime now = rtc.now();
   int m = now.minute(); 
   int hour = now.hour();
   int mon = now.month();
   int date = now.day();
 
   myGLCD.setColor(255, 255, 255); //белый цвет цифры
 
   if (date<10) { 
   myGLCD.print("0", 85, 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.setColor(255, 0, 0); 
   myGLCD.print("Km/h", 410, 0); }

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

 

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

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

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

почти разобрался c экраном, закончу кину скетч, давай оптимезируешь, с удовольствием приму :)

 

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

Блин второй день борюсь с отрисовкой и тачем. Выдернул меню из своего скетча, прописал тач, все работает. Вставлюю в основной скетчь строки для тачя, ЗАРАЗА НЕ РЕАГИРУЕТ. взял в скетче закоментил строку в лупе *receive ();, тач заработал но, отображение страноое вот

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

а кривит изображение строки Temperature (); в воид сетуп и if (millis() - prevTemperature > 60000)  { Temperature (); prevTemperature = millis();}  в воид луп

закоментив эти три сторки получаю гуд тачь и гуд прорисовка, единственное что присутствует видимость мигания обновления вывода данных, одн раз по времени и дате и три раза по данным, циклично, наверно потому что receive (); закоментирован в воид лупе.

скетч

/////////////////////////////////////////////////////////////////////////////////////////
 //библиотеки
 ///////////////////////////////////////////////////////////////////////////////////////////
 #include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 //Adafruit_GFX_Button buttonINF1, buttonINF2, buttonCHECK, buttonERASE, buttonREAD, buttonHome;

 #define MINPRESSURE 200
 #define MAXPRESSURE 1000
 
 //pin 20 SCL , 21 SDA датчик реального времени
 #include <Wire.h>
 #include "RTClib.h"
 RTC_DS3231 rtc;       
 
 //датчик наружней температуры
 #include <OneWire.h>
 #define ONE_WIRE_BUS 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);
 
 ///////////////////////////////////////////////////////////////////////////////////
 //пины экрана и тача
 ///////////////////////////////////////////////////////////////////////////////////
 //#define YP A1  // must be an analog pin, use "An" notation!
 //#define XM A2  // must be an analog pin, use "An" notation!
 //#define YM 6  // can be a digital pin
 //#define XP 7   // can be a digital pin
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args
 
 //оринтеровка тача под myGLCD.setRotation(3);
 const int XP = 6, XM = A2, YP = A1, YM = 7; 
 //const int TS_LEFT = 136, TS_RT = 907, TS_TOP = 139, TS_BOT = 942;
 TouchScreen ts = TouchScreen(XP, YP, XM, YM, 300);
 uint16_t ID;
 int x, y;
 char currentPage;
 float h;
 float t;
 bool Dvoet = 0;
 //////////////////////////////////////////////////////////////////////////////
 //все что касается OBD2
 ///////////////////////////////////////////////////////////////////////////////
 #include <SoftwareSerial.h>
 #define mySerial_gauge Serial2
 #define TX_gauge 16
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 int length5 = 5;
 int length6 = 6;
 int length8 = 8;
 int length7 = 7;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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


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

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

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

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

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

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

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

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

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

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


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

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

копаю дальше. по ходу гдето есть конфликт

нашел кусок который все валит,он в начале void receive ()

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

Не могу понять в чем причина зависания. MaksVV помоги разобратся, ПЛИЗ

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

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

не может соединиться со щитком приборов по какой либо причине. А там цикл while, т.е. в нем пытается соединиться со щитком , и если тщетно,  то это будет бесконечно, соотвественно ничего другое в этот момент не работает, и ты видишь это как зависание. Смотри что в порту Serial при этом пишет. В скетче присутствует вывод туда отладки. 

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

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

 

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

MaksVV вообщем думаю нужно разбирать панель и на живую ставить экран и уже смотреть че да как.... С перового июля буду целый месяц иметь время, займусь этим. Будет видно на живую. расчитываю на твою помощь. если в отпуск не уедешь:).

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

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

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

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

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

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

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

да макс так и было. :) без ничего. просто тестил настраивал и подправлял отображение на экране. и все отлично работает. кроме этого нюанса. по этому и говорю только ставить и на живую. 1 июля буду разберать и менять. надеюсь все пройдет гладко

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

Привет viki13viki, вот нашел на Али  дисплей 3,95" дюймов 320*480, вроде такой, какой Вы искали https://ru.aliexpress.com/item/3-8-3-95-320-480/32916041971.html с широкой колодкой пинов. После вставки шрифт постоянно меняется! )))

Потрясающе, что вы с MaksVV за 3 месяца смогли создать рабочий скетч для БК!!! Я сам давно хотел сделать для своей Нексии N150 БК, правда на PicBasicPro. Не хватило знаний,  теперь делаю на Ардуино. Язык Си для меня гораздо сложнее, поэтому скетчи MaksVV очень помогли. Кстати, у моей машины тоже протокол ISO 14230 Fast Init 10400 и адреса запросов совпадают с Вашими! Так что для меня это подарок! Отдельное спасибо MaksVV за то, что он помог нескольким новичкам с программированием БК!

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

Спасибо за ссылку, но это не такой. Я уже справился с тем что приобрёл. А за программирование, да, это заслуга Макса.

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

viki13viki пишет:
Я уже справился с тем что приобрёл.

Дак ты пробовал с новым экраном подключаться к машине? Т.е. уже всё заработало? 

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

по поводу оптимизации скетча, в частности обмена по к-лайн (KWP) . Почитайте сообщение #1201. Там довольно важная информация по протоколу. А то у ТС когда мы скетч делали бортовика до этого ещё не дошли, и действовали как слепые котята, используя delay в сотни миллисек и борясь из-за этого с паразитными непонятными FF байтами, которых на шине по факту и не было, а был это результат некорректного формирования кадров из шины. 

После бортовика ТС, я ещё способстовал проекту бортовика в этой теме  Targitai  на опель вектре.  Дак вот там уже фигурируют скетчи обмена по к-лайн более продвинутые, с отсутствием delay в сотни миллисекунд, с проверкой контрольной суммы, и с автоматическим переподключением к PCM, если связь по какойто причине прервалась. например скетч #1321. Жаль что Targitai вроде как дело до конца так и не довёл. А ведь немного оставалось. 

viki13viki
Онлайн
Зарегистрирован: 14.11.2016

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

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

Спасибо, MaksVV, обязательно посмотрю. Сам пару лет назад научился писать код с параллельными процессами, но потом слетел винт-многое потерял, а главное потерял интерес. Так что в программировании меня отбросило далеко назад. ) Если все-таки доделаю БК, то выложу что получилось. Главное, чтобы мне жена не отдала свой Дастер, а то проект загнется, ведь там БК уже есть! )))))

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

viki13viki, подскажите, а Ваш БК считает мгновенный расход и расход топлива на 100 км? Если да, то подскажите по каким формулам?

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

БК для Нексии заработал на индикаторе пока в текстовом режиме на основе скетча №157. Также на основе этого скетча написал скетч с запросами поддерживаемых PIDов. Оказалось что из 196 PIDов 1-го сервиса на моей машине поддерживаются только 18! (1, 3, 4, 5, 6, 7, 11, 12, 13, 14, 15, 17, 19, 20, 21, 28, 32 и 33).  Нет ни Мафа, ни бортового напряжения. )))) Вот теперь вопрос как из этих данных рассчитать мгновенный расход и расход на 100 км? Кучу инета перелопатил. Нашел только как рассчитать Маф через Мап. Если есть у кого подходящие формулы-поделитесь, пож-та!

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

по всей видимости вы решили черпать информацию из стандартных обд2 PIDов. Но лучше её брать из PIDа протокола автопроизводителя. Обычно это один длинный PID, который содержит в себе все диагностические параметры сразу. Расшаривается этот пид с помощью снифа диагностической сессии  диагностики и PCM. А также эмулятора PCM. 

PS напишите какая нексия и какой PCM

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

Нексия N150 DOHC 1.8л 16-клапанная, двигатель Sirius 42. Не знаю что такое эмулятор PCM. Вообще у меня есть лог соединения БК на основе нетбука программой ChevroletExplorer, там запрос инициализации  81 11 F1 81 04. 

Порт открыт процессом "CheviExplorer.exe" (PID: 608)
 
Порт закрыт
 
Порт открыт процессом "CheviExplorer.exe" (PID: 608)
 
Запрос:06.11.2016 16:30:21.06964
 
 81 11 F1 81 04                                    .ñ.           
 
Ответ:06.11.2016 16:30:21.10064 (+0.0313 seconds)
 
 81 11 F1 81 04 83 F1 11 C1 EF 8F C4               .ñ.ñ.ÁïÄ    
 
Запрос:06.11.2016 16:30:21.25664 (+0.1563 seconds)
 
 82 11 F1 27 01 AC                                 .ñ'.¬          
 
Ответ:06.11.2016 16:30:21.53864 (+0.2813 seconds)
 
 82 11 F1 27 01 AC 84 F1 11 67 01 4C 23 5D         .ñ'.¬ñ.g.L#]  
 
Запрос:06.11.2016 16:30:21.64764 (+0.1094 seconds)
 
 84 11 F1 27 02 31 18 F8                           .ñ'.1.ø        
 
Ответ:06.11.2016 16:30:22.92864 (+0.2813 seconds)
 
 84 11 F1 27 02 31 18 F8 83 F1 11 67 02 34 22      .ñ'.1.øñ.g.4" 
 
Запрос:06.11.2016 16:30:22.13164 (+0.2031 seconds)
 
 82 11 F1 1A 80 1E                                 .ñ..          
 
Ответ:06.11.2016 16:30:23.81964 (+1.6875 seconds)
 
 82 11 F1 1A 80 1E 80 F1 11 A5 5A 80 FF FF FF FF   .ñ..ñ.¥Zÿÿÿÿ
 53 41 54 30 30 31 53 41 54 46 52 00 00 53 30 30   SAT001SATFR..S00
 31 31 42 55 57 FF FF 00 96 94 06 68 4B 52 37 37   11BUWÿÿ..hKR77
 31 38 35 32 30 31 2D 2D 4B 52 37 37 31 38 35 31   185201--KR771851
 31 33 2D 2D 46 30 30 34 4A 53 46 30 2D 2D 2D 2D   13--F004JSF0----
 FF FE FF FF FF FF FF FF FF FF FF FE FF FF FF FE   ÿþÿÿÿÿÿÿÿÿÿþÿÿÿþ
 FF FE FF FF FF FF FF FF FF FF FF FE FF FF FF FE   ÿþÿÿÿÿÿÿÿÿÿþÿÿÿþ
 49 43 48 4F 4E 2D 2D 2D 35 57 59 35 39 30 38 41   ICHON---5WY5908A
 2D 2D 30 31 31 32 34 33 30 34 38 33 2D 47 4D 44   --0112430483-GMD
 31 31 30 36 32 34 31 36 30 37 30 38 31 33 FF FF   11062416070813ÿÿ
 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF 3C   ÿÿÿÿÿÿÿÿÿÿÿÿÿÿÿ<
 
Запрос:06.11.2016 16:30:24.91364 (+0.0938 seconds)
 
 80 11 F1 89 2C F0 01 01 01 0C 01 01 02 01 0C 20   .ñ,ð......... 
 01 03 01 0B 01 01 04 01 0B 08 01 05 01 0B 09 01   ................
 06 05 0B 11 01 0B 02 06 02 01 0D 01 05 06 01 0E   ................
 01 05 07 01 0F 02 04 02 01 11 02 04 06 01 13 02   ................
 04 12 01 15 02 04 16 01 17 04 03 01 01 1B 01 03   ................
 07 01 1C 01 01 07 01 1D 01 01 08 01 1E 01 04 09   ................
 01 1F 01 04 0D 01 20 01 0C 04 01 21 01 14 09 01   ...... ....!....
 22 02 01 02 01 24 02 01 04 01 26 02 01 06 01 28   "....$....&....(
 02 01 1C 01 2A 02 01 20 01 2C 02 01 16 7A         ....*.. .,...z  
 
Ответ:06.11.2016 16:30:25.56964 (+1.6563 seconds)
 
 80 11 F1 89 2C F0 01 01 01 0C 01 01 02 01 0C 20   .ñ,ð......... 
 01 03 01 0B 01 01 04 01 0B 08 01 05 01 0B 09 01   ................
 06 05 0B 11 01 0B 02 06 02 01 0D 01 05 06 01 0E   ................
 01 05 07 01 0F 02 04 02 01 11 02 04 06 01 13 02   ................
 04 12 01 15 02 04 16 01 17 04 03 01 01 1B 01 03   ................
 07 01 1C 01 01 07 01 1D 01 01 08 01 1E 01 04 09   ................
 01 1F 01 04 0D 01 20 01 0C 04 01 21 01 14 09 01   ...... ....!....
 22 02 01 02 01 24 02 01 04 01 26 02 01 06 01 28   "....$....&....(
 02 01 1C 01 2A 02 01 20 01 2C 02 01 16 7A 82 F1   ....*.. .,...zñ
 11 6C F0 E0                                       .lðà            
 
Запрос:06.11.2016 16:30:27.91364 (+1.3438 seconds)
 
 81 11 F1 3E C1                                    .ñ>Á           
 
Ответ:06.11.2016 16:30:27.19464 (+0.2813 seconds)
 
 81 11 F1 3E C1 81 F1 11 7E 01                     .ñ>Áñ.~.      
 
Запрос:06.11.2016 16:30:28.27264 (+1.0781 seconds)
 
 81 11 F1 82 05                                    .ñ.           
 
Ответ:06.11.2016 16:30:28.46064 (+0.1875 seconds)
 
 81 11 F1 82 05 81 F1 11 C2 45                     .ñ.ñ.ÂE      
 
Порт закрыт
 
MaksVV
Offline
Зарегистрирован: 06.08.2015

и зачем нужен MAF ? вам же не воздух нужно рассчитать, а топливо.

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

Обороты ДВС это рабочие циклы в минуту, переводим это в час получаем циклы в час. Перемножаем обороты и цикловую подачу, получаем тот же мл (или л)/ч.   если в г/ч то с помощью плотности переводим в л/ч. и поделить на 2 , т.к. ДВС 4 тактный

далее с помощью скорости получаем л/100 км

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

стоит также попробовать PID  остаток топлива в баке.  запрос:

82 11 F1 01 2F B4

 

 

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

такой PID у меня не поддерживается, максимум 21 HEX (33 децимальный).

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

тогда вот ещё полезная инфа 

Name,ShortName,ModeAndPID,Equation,Min Value,Max Value,Units,Header

,, Этот конфиг разработан специально для Chevrolet Aveo Седан T255 1.2V 16V с ЭБУ Sirius D42R
,, Частично будет совпадать для других машин на этом же ЭБУ, таких как:
,, Daewoo Matiz, Chevrolet Lacetti
,, Все строчки с запятой вначале отключены. 
,, PIDы для АКПП отключены, за ненадобностью лично мне
,, Для включения строчки в список дополнительных параметров необходимо стереть запятую в начале строки.
,, wosk, 2014

,,PID $01 из стандарта J1979
t ОЖ,ЕСТ,0105,A-40,-50,140,C,
t впуска,IAT,010f,A-40,-50,140,C,
МАР,МАР,010b,A,0,255,kPa,
RPM,RPM,010c,(A*256+B)/4,0,16000,,
Speed,Speed,010d,A,0,255,km/h,
ДЗ%,TPS,0111,A/255*100,0,100,%,
УОЗ,УОЗ,010e,(A-128)/2,-64,64,deg,
FTBb1s1,FTBb1s1,0114,(B-128)/128*100,0,100,%,
LTFT1,LTFT1,0107,(A-128)/128*100,0,100,%,
STFT1,STFT1,0106,(A-128)/128*100,0,100,%,
LoadEng,LoadEng,0104,A/255*100,0,100,%,
Closed Loop,CL,0103,{A:1}+{A:4},0,1,Off/On,


t ОЖ,ЕСТ,2102,A/255*192-49,-50,140,C,
t на впуске,IAT,2102,B/255*192-49,-50,140,C,
ДЗ%,TPS,2102,C/255*100,0,100,%,
Напряжение,Voltage,2102,D/8.88,0,16,V,
Скорость,Speed,2102,E,0,255,km/h,
Обороты,RPM,2102,(F<8)+G,0,9000,rpm,
Барометрическое давление,BARO,2102,H/255*119,0,119,kPa,
Давление во впускном коллекторе,МАР,2102,J/255*119,0,119,kPa,
Массовый расход воздуха,MAF,2102,((L<8)+M)/47,0,1400,mg/t,
Длительность впрыска пусковая,InjDurSt,2102,((N<8)+O)/62.5,0,1050,ms,
Длительность впрыска текущая,InjDur,2102,((P<8)+Q)/250,0,0,ms,
Коррекция длительности впрыска,Corr Inj,2102,(signed(T)*256+U)/250,0,65535,ms,
Передача МКПП,Gear,2102,V,0,5,,
,Режим АКПП,AKPP,2102,W,0,255,,
Скважность продувки адсорбера,AdsFlow,2102,X/255*100,0,100,%,
Рециркуляция отработаных газов,EGR,2102,Y/255*100,0,100,%,
Давление в системе кондиционирования,ACP,2102,AB*12,0,3100,kPa,
,Fuel%,Fuel%,2102,Z/255*100,0,100,%,

,,,,,, напряжения
Напр.дат.ТВпуск,VoltIAT,2101,((C<8)+D)/205,0,0,V,
,,, мб неправильный коэффициент (Макс 5В)
Напр.дат.РХХ,VoltIAR,2101,((E<8)+F)/205,0,0,V,
,,, мб неправильный коэффициент (Макс 12В)
Напр.ДУТ,VoltDUT,2101,((AA<8)+AB)/205,0,0,V,
Напр.дат.давл.хладагента,VoltACP,2101,((AC<8)+AD)/205,0,0,V,
Напр.дат.ТОЖ,VoltECT,2101,((A<8)+B)/205,0,5,V,
Датчик детонации,KnockSens,2101,((G<8)+H)/205,0,0,V,

,,,, УОЗы
УОЗ1,УОЗ1,2103,(192-A)/2.677,-30,72,deg,
,УОЗ2,УОЗ2,2103,(192-B)/2.677,-30,72,deg,
,УОЗ3,УОЗ3,2103,(192-C)/2.677,-30,72,deg,
,УОЗ4,УОЗ4,2103,(192-D)/2.677,-30,72,deg,
Требуемый УОЗ,треб УОЗ,2103,(G-64)/2.677,-30,72,deg,

Пробег,Mileage,2105,((AD<16)+(AE<8)+AF)/10,0,999999,km,

Счетчик включений зажигания,IgnCnt,2107,((N*256)+O),0,65535,,

,, Усредненое значение
Fuel Tank,FuelTankL,210b,(X-18)*2/255*45,0,45,l,
Fuel Tank%,FuelTank%,210b,(X-18)*2/255*100,0,100,%,
Бензонасос,FuelPump,210B,{A:0},0,1,0ff/On,
O2Heater,HeatO2S,210B,{B:0},0,1,0ff/On,
Режим ХХ,EngIdle,210B,{C:0},0,1,Off/on,
Отключение подачи топлива,InjOff,210B,{G:0},0,1,Off/on,
Полная нагрузка,FullLoad,210B,{H:0},0,1,0ff/On,
ДЗ закрыта,PSClose,210B,{I:0},0,1,0ff/On,
,Впускной коллектор переменной длины,TwinPort,210B,{Q:0},0,1,0ff/On,
Кондиционер,A/C,210B,{R:0},0,1,0ff/On,
Реле низкой скор.вент.охл-я,FanLow,210B,{S:0},0,1,0ff/On,
Реле высокой скор.вент.охл-я,FanHi,210B,{T:0},0,1,0ff/On,
,муфта гидротрансформатора АКПП,Clutch,210B,{U:0},0,1,0ff/On,
ABS левое переднее,ABS LF Speed,210B,AA,0,255,km/h,

,drive,drive,210C,{A:0},0,1,off/on,
Closed Loop,CL,210C,{D:0},0,1,off/on,
,RPM_avg,RPM_avg,210C,F*256+G,0,6000,rpm,
,Скорость3_raw,Speed3raw,210C,H,0,255,km/h,
,t ОЖ2,ECT2,210C,O/255*192-49,-50,140,C,
,t впуска2,IAT2,210C,P/255*192-49,-50,140,C,
Режим работы двигателя,EngState,210C,AF,0,5,,

,Режим работы двигателя,EngState2,210b,B,0,5,,
Требуемый ХХ,NeedIdleRPM,210D,(M<8)+N,500,1500,rpm,
ДЗ закрыта,notAccel,210D,{E:0},0,1,Off/on,

Время с запуска двигателя,EngRunTime,2117,((H<16)+(I<8)+J)/600,0,27961,min,

 

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

в ответе на запрос 21 02 много параметров

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

у меня еще есть ELM327  и программы Torque и Olivia, попробую с ними достать эту инфу из ЭБУ. Ок, попробую с 21 02, спасибо!!!

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

в вот картинка с вашей программы , см. внизу нужные вам параметры уже рассчитаны. У вас такие не показывают?  

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

Точно, надо снять скриншот!

Targitai
Offline
Зарегистрирован: 05.10.2018

MaksVV пишет:

Жаль что Targitai вроде как дело до конца так и не довёл. А ведь немного оставалось. 

Ну это как посмотреть. Уперлись то мы в совместимость TV OUT и задержки...., Это только если пробовать со второй Ардуиной

 а потом я еще и камеру китайскую снял, ибо задолбал квадрат малевича.

Хотя сейчас у меня уже 3 Ардуино валяются - Нано, Уно и Мега. Вот можно попробовать поиграться... Кажись, давал ссылку на этот же форум. Вроде получилось у товарища: http://arduino.ru/forum/programmirovanie/peredacha-dannykh-po-uart-pri-aktivnom-tvout

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

дак если камеры нет, может просто на графическом экране сделать как у ТС

Targitai
Offline
Зарегистрирован: 05.10.2018

Все таки я надеюсь на разборке какую то оригинальную найти и вместо китайской присобачить. В будущем.

А так смысл, если и так БК есть. Только ошибки читать - так это хоть лампочкой, хоть Опель Сканер.

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

или если Serial не работает с ТВоут, то  попробовать 2 ардуины связать по I2c или SPI. Одна выводит на дисплей, другая собирает параметры по к-лайн и отправляет их первой дуне, которая обслужвает дисплей

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

Привет, MaksVV, у меня куча информации с ELM327 и ChevroletExplorer, но я не понимаю как тут вставить и сделать ссылку файлы txt и jpg.

 

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

текст вставлять как код, вверху на вкладке правой галка свернуть. 

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

ответы на запросы 21 01:

starting comunication (fastinit)
starting serial comunication
Zapros Initialization:  81  11  F1  81  4  
Zapros Initialization:  81  11  F1  81  4  
                                                        Recieve:   83 F1 11 C1 EF 8F C4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
                                                     Initialization OK!:  

PID delay:  150ms
Present delay:  9000ms

21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AF 2 49 0 79 0 71 0 0 0 18 0 0 0 4E 0 0 0 0 0 68 0 C7 0 0 3 EB 3 FF 0 0 6F 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AF 2 49 0 79 0 82 0 0 0 31 0 0 0 1D 0 0 0 0 0 67 0 CC 0 0 3 EC 3 FF 0 0 6D 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AD 2 49 0 79 0 99 0 0 0 97 0 0 0 28 0 0 0 0 0 68 0 C7 0 0 3 EB 3 FF 0 0 EE 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AD 2 49 0 79 0 74 0 0 0 67 0 0 0 1E 0 0 0 0 0 67 0 C7 0 0 3 EC 3 FF 0 0 8F 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AD 2 49 0 79 0 97 0 0 0 85 0 0 0 2A 0 0 0 0 0 68 0 C5 0 0 3 EB 3 FF 0 0 DA 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AD 2 48 0 79 0 8F 0 0 0 58 0 0 0 1E 0 0 0 0 0 67 0 C4 0 0 3 EB 3 FF 0 0 96 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AD 2 48 0 79 0 8C 0 0 0 88 0 0 0 29 0 0 0 0 0 68 0 C9 0 0 3 EC 3 FF 0 0 D5 
Zapros prisutstviya:   81  11  F1  3E  C1         9000ms
                                                        Recieve:   81 F1 11 7E 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AD 2 48 0 79 0 89 0 0 0 48 0 0 0 1D 0 0 0 0 0 67 0 CE 0 0 3 EC 3 FF 0 0 8A 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AE 2 47 0 79 0 91 0 0 0 3E 0 0 0 28 0 0 0 0 0 67 0 C8 0 0 3 EC 3 FF 0 0 8D 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AE 2 47 0 79 0 92 0 0 0 A8 0 0 0 1D 0 0 0 0 0 68 0 C8 0 0 3 EC 3 FF 0 0 EE 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AE 2 47 0 79 0 A4 0 0 0 18 0 0 0 2D 0 0 0 0 0 67 0 C6 0 0 3 EB 3 FF 0 0 7C 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AE 2 48 0 79 0 8B 0 0 0 90 0 0 0 1F 0 0 0 0 0 68 0 C6 0 0 3 EB 3 FF 0 0 CF 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AE 2 46 0 79 0 86 0 0 0 2C 0 0 0 29 0 0 0 0 0 67 0 C5 0 0 3 EB 3 FF 0 0 6C 
21-01:   82  11  F1  21  1  A6  
                                                        Recieve:   A2 F1 11 61 1 0 AD 2 47 0 79 0 C3 0 0 0 A8 0 0 0 1E 0 0 0 0 0 68 0 CA 0 0 3 EC 3 FF 0 0 21

 

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

а ссылки на картинки как сделать?

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

я так понимаю ответы на запрос 2101 содержат инфу по АЦП (напряжния) разных датчиков, если верить файлу #1379

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

читай песочницу первую тему

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

получилоь. Olivia через ELM. На хх

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

а эксплоер показывает расход? 

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

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

и Olivia, и ChevriletExplorer на основе имеюшихся данных расчитывают мгновенны расход на мое машине. Осталось только разобраться как они это делают! ))))

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

По поводу запроса 21 01. В Вазовском документе 14230-3R.DOC по-другому расписаны байты ответа на этот запрос. Буду искать американский документ

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

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

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

lev2606 пишет:

и Olivia, и ChevriletExplorer на основе имеюшихся данных расчитывают мгновенны расход на мое машине. Осталось только разобраться как они это делают! ))))

скорее всего это не диагностическая программа рассчитывает, а получает готовую цифру от ЭБУ в PIDe