Получение данных по K-Line автомобиля - ISO 14230 KWP 10.4 Kbaud. ARDUINO

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Проблема в понимании процессов ...

Holodz
Offline
Зарегистрирован: 16.07.2022

MaksVV пишет:
Не пойму в чем проблема засниффить через вашу ардуину мега, к которой уже сделан клайн

Потому что уже по факту и не сделан, т.к. вчера потерял эту микруху, сейчас жду другую на днях должны привезти... Первым делом обязательно сделаю снифф и покажу что там будет "плавать" 

Komandir
Komandir аватар
Offline
Зарегистрирован: 18.08.2018

Что бы "подслушать" обмен - достаточно одного диода !
K-Line - KI - Rx.
KI это диод "стрелкой" в сторону K-Line
Соедмняете как обычно, добиваетесь правильного обмена, цепляете диод и опять проводите обмен...
В мониторе будет видно как общаются железки.

Holodz
Offline
Зарегистрирован: 16.07.2022

Komandir пишет:
Что бы "подслушать" обмен - достаточно одного диода ! K-Line - KI - Rx. KI это диод "стрелкой" в сторону K-Line Соедмняете как обычно, добиваетесь правильного обмена, цепляете диод и опять проводите обмен... В мониторе будет видно как общаются железки.

 

Ого, я понял, так и сделаю значит. Я думал чтобы подслушать обязательно так же нужна микросхема, хотя я сначала так и подумал чтобы напрямую цепануть через диод и послушать, но что-то я подумал что я ничего не увижу так. Оказывается наоборот.. Сегодня постараюсь так и сделать

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

Массу ардуино и автобиля не забываем соединить при этом. И направление диода не путать, можно поджечь дуню

Holodz
Offline
Зарегистрирован: 16.07.2022

MaksVV пишет:

Щас поправлю код чтобы лог подробнее был. и соберите адаптер на lm393. Продаётся за 10копеек в любом радио магазе. 

Здравствуйте MaksVV. Подскажите пожалуйста, можно ли вместо использования Mc33290 использовать компаратор Lm393? Получится ли через него отправить и получить данные как через обычную микруху 33290?

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

Сможете. Но схема адаптера естественно другая, нельзя просто перепаять микруху. По ссылке там не клайн адаптер.

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

Купите lm393 в dip корпусе, монтажную плату, и 8 резисторов, что тут сложного

Holodz
Offline
Зарегистрирован: 16.07.2022

MaksVV пишет:
Купите lm393 в dip корпусе, монтажную плату, и 8 резисторов, что тут сложного

 

Я так понимаю вот эта схема подойдёт? И вот данный Lm393 в дип корпусе подойдёт? С данной схемой, скейт общения по к лайн останется таким же? 

https://www.chipdip.by/product/lm393p

 

Схема

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

Дип подойдёт, скетч такой же. На схеме только не указана нога 8 (на vcc12v) и нога 4 (на gnd). Ну и само собой, раз у вас мега, Rx и Tx не 10 11 а другие - Serial2. Может имеет смысл монтажную купить размером с мегу и пинхидеры припаять, чтобы вставлялась в мегу как шилд, так проводов меньше и надёжнее.

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

этот скетч должен заработать 

#define PCM_ADDRESS 0x7A // тут выбираем адрес ЭБУ
#define K_LINE Serial2   // тут выбираем Serial, на котором висит Клайн адаптер
#define TX 16            // и соответствующий ему  пин TX

#define PID_PERIOD_ms 500   // выбираем периодичность диагн запросов
#define INIT_PERIOD_ms 25   // выбираем длительность импульсов fastinit

enum inita {NEED_INIT=1, SEND81=9, RECEIVE81, SEND10C0, INITOK};
byte bus_init = 0; 

const byte INIT[]          {0x81}; // start session
const byte BEGIN[]         {0x10, 0xC0};
const byte PID[]           {0x21, 0x80}; // PID

uint32_t prevReset = 0; 
bool timerReset = 0 ;

void setup() 
{
 Serial.begin(115200); 
 bus_init =NEED_INIT; 
}

void fastInit()
{
     static uint32_t timerInit = 0; 
     if (bus_init==NEED_INIT) {K_LINE.end(); pinMode (TX, OUTPUT); digitalWrite(TX, 0); timerInit = millis(); bus_init++;}
else if (bus_init==2 && millis() - timerInit>INIT_PERIOD_ms) {timerInit = millis(); digitalWrite(TX, 1); bus_init++; }
else if (bus_init==3 && millis() - timerInit>INIT_PERIOD_ms) {Serial.println("Fast init 25msLOW 25msHIGH"); K_LINE.begin (10400); sendMessage (INIT, sizeof(INIT));bus_init=SEND81; }
}

void sendMessage(const byte *command, const size_t size)
{
  if (!timerReset){timerReset=1; prevReset = millis();}
  Serial.println(); Serial.print("               Send to PCM:  ");
  const byte siZe = size+4;
  byte Mes[siZe];
  byte Checksum = 0;
  for(byte i=0; i<siZe; i++) 
  {
    if (i==0) {Mes[i]=size; bitWrite(Mes[i], 7 , 1);}
    if (i==1) Mes[i] = PCM_ADDRESS;
    if (i==2) Mes[i] = 0xF1;    
    if (i==3) {for (byte t=0; t<size; t++ ) 
        {Mes[i]=command[t]; Checksum+=Mes[i] ; 
        Serial.print(Mes[i],HEX); 
        Serial.print(" "); 
        K_LINE.write (Mes[i]); delayMicroseconds(10); K_LINE.read(); 
        i++;}}
    if (i!=siZe-1) Checksum+=Mes[i];
    else Mes[i] = Checksum;    
    Serial.print(Mes[i],HEX); 
    Serial.print(" "); 
    K_LINE.write (Mes[i]);  delayMicroseconds(10); K_LINE.read();
  }
  Serial.println();
}

void read_KLINE()
{
  static byte header = 0;             // состояние заголовка 
  static byte message_size = 0;       // размер тела принимаемого сообщения, кол-во байт
  static byte j = 1;                  // инкремент
  static byte n = 3;
  const byte bufsize = 60;            // размер буфера принятого сообщения
  static byte buf [bufsize] = {0};    // буфер принятого сообщения
  static byte checksum = 0;           // контрольная сумма входящего сообщения
  static uint32_t prevRESETheader=0;  // таймер сброса заголовка если в момент приёма сообщения данные оборвались
  static bool RESETheader_timer = 0;  // таймер сброса заголовка если в момент приёма сообщения данные оборвались

if (K_LINE.available()){
    

 // первый старт байт
 if (header == 0){buf[0]=K_LINE.read(); 
           if (buf[0]!=0xFF &&buf[0]!=0) {Serial.print("Receive from PCM: "); Serial.print(buf[0],HEX); Serial.print(" "); 
         header = 1; RESETheader_timer=1; prevRESETheader = millis();}
         else {header = 0; RESETheader_timer=0; }
         
         }                  
 // второй старт байт
 else if (header == 1){buf[1]=K_LINE.read(); Serial.print(buf[1],HEX);  Serial.print(" "); if (buf[1]==0xF1){ header = 2;} else {Serial.println(" MessageReset"); header = 0; RESETheader_timer=0;}} 

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

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

 } // end of K_LINE.available()

 // сообщение приняли, действуем
 if (header == 5) {  

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

//for (byte i=0; i<message_size+n+1; i++) {if (buf[i]<=0xF)Serial.print ("0"); Serial.print (buf[i], HEX); Serial.print(" ");}

 // если контрольная сумма верна: 
if (buf[message_size+n] == checksum) 
 {
  prevReset = millis(); // сбрасываем таймер сброса сессии при получении валидного пакета от эбу
    Serial.print(" CheckSUM good! " );
      if (buf[n]== 0x61 && buf[n+1]==0x80)   {Serial.println("Receive PID 2180");} //тут обрабатываем полученный ответ на PID 2180
 else if (buf[n]== 0xC1) {bus_init=RECEIVE81;}
 else if (buf[n]== 0x50) {bus_init=INITOK;}
 }     
    
// если контрольная сумма не совпала: 
else Serial.print(" CheckSUM fail!!!" );
message_size = 0; header=0; RESETheader_timer=0; j=1; checksum = 0;
Serial.println();
 }
// таймер сброса заголовка если данные оборвались по середине сообщения
if (RESETheader_timer && millis() - prevRESETheader > 500) {Serial.println("timeout"); message_size = 0; RESETheader_timer = 0; header = 0;checksum = 0;j=1;}   

}


 
void loop() 
{
fastInit();     
read_KLINE();
if (bus_init==RECEIVE81) {sendMessage (BEGIN, sizeof(BEGIN));bus_init=SEND10C0;}
static uint32_t prevtimePID = 0;
if (bus_init==INITOK && millis()-prevtimePID>PID_PERIOD_ms) {prevtimePID= millis();sendMessage (PID, sizeof(PID)); }
if (timerReset && millis()-prevReset>3000){timerReset=0; bus_init=NEED_INIT;}//таймер сброса сессии при молчании эбу
}