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

abt
Offline
Зарегистрирован: 23.11.2013

MaksVV, огромное спасибо за помощь! попробую по совету! )

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

Lev2606, ваш сниф если правильно отформатировать то получится следующее : 

Diag to PCM:   81 11 F1 81 4   // запрос на подключение к ЭБУ

      PCM to Diag: 83 F1 11 C1 EF 8F C4  // ответ ЭБУ с KEYWORDами

Diag to PCM:   82 11 F1 1A 80 1E  // запрос идентов блока

      PCM to Diag: 80 F1 11 A5 5A 80 FF FF FF FF 53 41 54 30 30 31 53 41 54 46 52 0 0 53 30 30 31 31 42 55 57 FF FF 0 96 94 6 68 4B 52 37 37 31 38 35 32 30 31 2D 2D 4B 52 37 37 31 38 35 59 FF // и т.д. это идентификаторы, полностью сообщение не влезло в сниф

Diag to PCM:   80 11 F1 89 2C F0 1 1 1 C 1 1 2 1 C 20 1 3 1 B 1 1 4 1 B 8 1 5 1 B 9 1 6 5 B 11 1 B 2 6 2 1 D 1 5 6 1 E 1 5 7 1 F 2 4 2 1 11 2 4 6 1 13 1 1 1 4 1 2 26 1C 2C  // тут тоже какая то длинная хрень. диагностика видимо запрашивает какие PIDы блок поддерживает

      PCM to Diag: 82 F1 11 6C F0 E0 // ответ блока на эту длинную хрень

Diag to PCM:   81 11 F1 3E C1 // запрос поддержания связи 

      PCM to Diag:  81 F1 11 7E 1  // ответ поддержания связи
 

// и далее диагностика начинает запрашивать попеременно диагностические параметры двумя PIDами  это 2102   и 21F0


Diag to PCM:   82 11 F1 21 2 A7  // запрос 2102
      PCM to Diag: A2 F1 11 61 2 A5 80 0 6F 0 0 0 D0 E8 D0 E8 0 0 0 0 0 0 0 0 0 0 0 0 0 1 7F 0 0 0 0 0 0 8B // ответ на 2102

Diag to PCM:   82 11 F1 21 F0 95  // запрос 21F0
      PCM to Diag: AF F1 11 61 F0 0 0 0 0 1 0 0 0 0 0 0 4E 0 0 54 0 54 0 0 0 0 0 B3 B3 B3 B3 80 0 0 5 5 0 1 4B 1 48 2 7B 0 F3 3 0 0 66 0 BD // ответ на 21F0

далее я нашёл разбор PIDа 2102 для вашей нексии. 

собственно говоря вот байты ответа на запрос 2102 (внизу буквенное название этих байтов в ПИДе). Жирным шапка ПИДа

 A2 F1 11 61 2  A5 80  0 6F 0 0 0 D0 E8 D0 E8 0 0 0  0 0 0 0  0 0 0 0 0  0 1 7F 0    0   0   0   0   0  8B

                         A   B  C  D  E F  G  H   I   J   K  L M N O P Q R S T U V W X Y Z  AA AB AC AD AE AF AG
 
 
например посчитаем напряжение борт сети. Смотрим в таблицу , за это отвечает байт D. Он равен у нас 0x6F в DEC это 111. Подставляем в формулу. (111+1,5)/9,854 = 11,42 В 
остальное аналогично. 
описание пида 21F0  не нашёл 
 
lev2606
Offline
Зарегистрирован: 19.06.2019

Огромное спасибо, MaksVV!!! Посчитал, все значения в снифе по запросу 2102-находятся в диапазоне допустимых в соответствии с таблицей на Sirius-42! Правда немного странные значения длительности впрыска и коррекции, но все в рамках. Вот только смущает напряжение бортсети, у меня в Chevrolet-Explorere с заведенным двигателем показывало значение 13-13,3 вольта. А тут получается 11,5! Подозреваю что это ошибка в формуле, нужно так: D/9.854 + 1.5 . Тогда получается 13 вольт. 

Круто, теперь можно дальше делать свой БК, а то я зациклился на его внешнем виде -на картинке в дисплее (хочу БК в приборку Нексии поставить вместо индикаторов топлива и температуры).  Еще раз -низкий поклон, Макс, очень выручил!!!

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

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

#define K_LINE_GAUGE Serial2
 #define TX_gauge 16


//#define debugPCM                 // раскоментировать эту строку для отладки в Serial порту обмена с PCM
#define debugGAUGE             // раскоментировать эту строку для отладки в Serial порту обмена co щитком приборов

uint32_t curmillis = 0;         // снимок текущего времени 

uint32_t prevRESETheaderGAUGE=0; // таймер сброса сообщения, если данные оборвались посередине сообщения 
 bool RESETheader_timerGAUGE;     // таймер сброса сообщения, если данные оборвались посередине сообщения  

uint32_t timerdelayGAUGE = 0;    // таймер ожидания байт (для успевания появления данных в буфере UART)
 bool DelayGAUGE = 0;             // таймер ожидания байт (для успевания появления данных в буфере UART)
 byte waitbyte_RX_GAUGE = 1;       // задержка, мс для успевания появления данных в буфере RX 
                             // (подрегулировать в зависимости от уровня жизнидеятельности на Марсе) 
 #define TIMER_DELAYGAUGE DelayGAUGE = 0; timerdelayGAUGE = curmillis  // включение этого таймера

byte headerGAUGE = 0;          // состояние заголовка
byte message_sizeGAUGE = 0;    // размер тела сообщения
byte jGAUGE = 3;               // инкремент
byte nGAUGE = 3;               // количество старт байт
const byte bufsize = 150;
byte MessageRx_GAUGE [bufsize] = {0}; // буфер принятого сообщения
int ChecksumGAUGE =0;              // байт контрольной суммы 

byte PIDgauge[] = {0x02, 0x11, 0x00, 0x13};

byte InitGauge = 1;


 
void setup() {
 Serial.begin (115200);
 pinMode(TX_gauge, OUTPUT);
 delay (1500);
 
 Serial.println ("Send startsession - address 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);
   K_LINE_GAUGE.begin(9600);

}



void loop() {

curmillis = millis();


  receiveGAUGE (); // приём сообщений от приборки

}



void receiveGAUGE () {

 if (K_LINE_GAUGE.available() ){
    
 // первый старт байт
 if (headerGAUGE == 0 && DelayGAUGE){TIMER_DELAYGAUGE ; MessageRx_GAUGE[0]=K_LINE_GAUGE.read();  
         if ((InitGauge ==1 && MessageRx_GAUGE[0]==0x55) || InitGauge ==2 && MessageRx_GAUGE[0]!=0xFF){headerGAUGE = 1; RESETheader_timerGAUGE = 1; prevRESETheaderGAUGE = curmillis; 
               #ifdef debugGAUGE
                  Serial.print (F("Receive GAUGE: ")); printDebugRX(MessageRx_GAUGE[0]);
               #endif               
                                                }
                          }                  

 // второй старт байт
 if (headerGAUGE == 1 && DelayGAUGE){TIMER_DELAYGAUGE ; MessageRx_GAUGE[1]=K_LINE_GAUGE.read(); 
 #ifdef debugGAUGE
      printDebugRX (MessageRx_GAUGE[1]);
 #endif
      if ( (InitGauge ==1 && MessageRx_GAUGE[1]==0x52)  ||     (InitGauge ==2 && (MessageRx_GAUGE[1]==0xA0 || MessageRx_GAUGE[1]==0xA1))){ headerGAUGE = 2;} 
      else {
        #ifdef debugGAUGE 
        Serial.println(F(" GAUGE Message fail address")); 
        #endif
        headerGAUGE = 0; RESETheader_timerGAUGE = 0;}} 

 // третий старт байт
 if (headerGAUGE == 2 && DelayGAUGE){ 
  TIMER_DELAYGAUGE ;
  MessageRx_GAUGE[2]=K_LINE_GAUGE.read(); 
  #ifdef debugGAUGE
  printDebugRX (MessageRx_GAUGE[2]);
  #endif
  if (InitGauge ==2 && (MessageRx_GAUGE[2]==0x48 || MessageRx_GAUGE[2]==0x04)){ message_sizeGAUGE = MessageRx_GAUGE[0]-2; prevRESETheaderGAUGE = curmillis;
       headerGAUGE = 4;  jGAUGE=3; nGAUGE=3;
      
       if (message_sizeGAUGE > bufsize) message_sizeGAUGE = bufsize;  ChecksumGAUGE = 0;} 
  else if (InitGauge ==1 && MessageRx_GAUGE[2]==0x80) {InitGauge = 2; K_LINE_GAUGE.write(0x7F); headerGAUGE = 0; RESETheader_timerGAUGE = 0; 
             #ifdef debugGAUGE
             Serial.println ("Gauge INIT is good!"); 
             #endif
                                                      }     
  else {headerGAUGE = 0; 
        #ifdef debugGAUGE 
        Serial.println(F("GAUGE Message fail address")); 
        #endif
        RESETheader_timerGAUGE = 0;}
  
                          }  

  // пишем тело сообщения 
 if (headerGAUGE == 4 && DelayGAUGE && jGAUGE< message_sizeGAUGE+nGAUGE+1) {
 MessageRx_GAUGE[jGAUGE] = K_LINE_GAUGE.read(); prevRESETheaderGAUGE = curmillis;
 if (jGAUGE<message_sizeGAUGE+nGAUGE-1) ChecksumGAUGE+= MessageRx_GAUGE[jGAUGE]; // подсчёт КС
 
 if (jGAUGE==message_sizeGAUGE+nGAUGE) headerGAUGE = 5; 
 TIMER_DELAYGAUGE ; 
 #ifdef debugGAUGE
 printDebugRX(MessageRx_GAUGE[jGAUGE]);
 #endif  
 jGAUGE++;                                             } 
 }

 // сообщение приняли, действуем
 if (headerGAUGE == 5) {TIMER_DELAYGAUGE ;  
 #ifdef debugGAUGE
 Serial.println();
 #endif  
 
  
for(byte i = 0; i<nGAUGE; i++) ChecksumGAUGE+=MessageRx_GAUGE[i]; // прибавляем к контрольной сумме старт байты
int ChecksumG =  ( ( unsigned int )MessageRx_GAUGE[message_sizeGAUGE+nGAUGE-1] << 8 ) | MessageRx_GAUGE[message_sizeGAUGE+nGAUGE]; // парсинг контрольной суммы из 2 последних байт 
 // если контрольная сумма верна: 
if ( ChecksumGAUGE == ChecksumG) 
{  
  #ifdef debugGAUGE
  Serial.print (F("Received message is OK! Checksum is correct!"));  Serial.print (F("  ")); Serial.println (millis()); // Если КС совпала, тут чёнибудь нужное делаем
  #endif

      if (MessageRx_GAUGE[1]== 0xA0 && MessageRx_GAUGE[2]== 0x48) {
           #ifdef debugGAUGE
           Serial.println ("ID panel receive! Send request PIDGauge"); 
           #endif
           for (byte i=0; i<sizeof(PIDgauge); i++) {delay (1); K_LINE_GAUGE.write (PIDgauge[i]);}
                                                                  }

      if (MessageRx_GAUGE[1]== 0xA1 && MessageRx_GAUGE[2]== 0x04) {
           #ifdef debugGAUGE
           Serial.println (" receive Datastream Gauge!");
           #endif
                                                                  }
 }   

// если контрольная сумма не совпала: 
#ifdef debugGAUGE
  else Serial.println("CRC fail!!!" );
#endif
message_sizeGAUGE = 0; headerGAUGE=0; RESETheader_timerGAUGE = 0; jGAUGE=3; ChecksumGAUGE = 0;
}

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

// таймер сброса целостности сообщения (если данные оборвались посередине сообщения)
if (RESETheader_timerGAUGE && curmillis - prevRESETheaderGAUGE > 1000) { 
  #ifdef debugGAUGE 
  Serial.println(F("Message fail timeout")); 
  #endif 
  RESETheader_timerGAUGE = 0; headerGAUGE = 0;}   

 

}// end receiveGAUGE



void printDebugRX (const byte &inbyte) {if (inbyte<=15) Serial.print(F("0")); Serial.print (inbyte, HEX);  Serial.print (F(" "));}

 

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

Макс, свалил в отпуск, буду в начале сентября. Дам знать когда опробую. Спасибо