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

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

тоже самое эфки

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

ладно пока остановимся на этом. Короче эбу вредный ,ему видимо нужна определённая задержка между инитом шины 25мс 25мс и сообщением инита. По крайней мере если не получится сделать по нормальному, эту часть кода так оставим

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

ок.

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

ну на посоедок ещё так

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

#define PCM_address  0x11
#define DIAG_address 0xF1

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

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

  


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

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


 

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

    void loop() 
                {
curmillis = millis();

 if (!Init) { if (!timerenabledInit){ timerwaitInit=curmillis; timerenabledInit=1; sendMessagePCM (INIT); }
           else if (TIMEREXPIRED_Init) timerenabledInit=0;}
      
else if (curmillis - prev > 500) {  sendMessagePCM (PID); prev = curmillis;  }

receive ();
                }

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

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

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

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

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

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

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

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

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

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

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

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

update. исправил кое что в коде

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

ща сек. тишина. нет ничего в порту. я еще 2.5 недели буду в доступе по 12 часов в день. когда сможешь продолжим. спасибо

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

Ок

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

1446 поправил, пробуй

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

в 1446  все инит инит инит , короче не конектится

 

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

ещё исправил 1446, пробуй

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

все я тут 1446 тоже самое

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

1443 был последний рабочий, 1446 сделал из него теперь.  проверяй 1446

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

ужос нах, 1443 то точно каждый раз рабочий?  или может он тоже FF FF будет иногда выдавать? Я почти ничего не поменял по сравнению с рабочим

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

ща закину 1443 и скажу че дает

тоже эфки дает

 

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

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

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

каждый раз загружаю прошивку. потом включаю зажигание и запускаю монитор порта. всегда работало

 

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

1437 1441 1443 были рабочие

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

ща каждый загружу и скажу

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

работают 1437 1441

не работает 1443

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

попробуй увеличить задержку в фаст ините с 360 до 500

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

какой скетч 1443? ессли в нем то, не помогло

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

смотрю осциллом какая задержка идёт после фаст инита и посылаемым сообщением инита от проги опком

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

тоже 25 мс

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

пробуй такой скетч 


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

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

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


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

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


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

 

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

короче я спутал 25 мс это и есть часть фаст инита HIGH. Значит сразу сообщение идёт. Кстати измеренные задержки по 26мс и 4мс между байтами . Поправил в скетче 1474. Играйся ими. И попробуй в сетапе mySerial.begin закоментировать. 

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

эфки

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

24 мс и 6 мс пробовал? 

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

строка 44 delay 195 убавь на 20мс

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

вместо 25 ставил 24 не помогло

вместо 5 ставил 6 не помогло

вместо 195 ставил 175 не помогло

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

строка 28         цифру 500  попробуй на 2000 поправить

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

2000 не помогло

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

блин хз чё ему надо. как мы вообще при такой теме умудрились его разговорить. Повезло просто

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

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

 #include <SoftwareSerial.h>
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 byte messageInit[] = {0x81, 0x11, 0xF1, 0x81, 0x04};     // запрос инициализации
 
 void setup() {
   
   Serial.begin(115200);
   pinMode(TX, OUTPUT);
   fastinit();
              }

  void loop() {   
   
  if (mySerial.available()) {Serial.print (mySerial.read(), HEX); Serial.print (" ");}
   
    }

 void fastinit() {
  
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(400);             // 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);
   initialization();
   }  
   
 void initialization() {
   for (int i = 0; i < sizeof(messageInit); i++) {
   mySerial.write(messageInit[i]);
   delay (5); 
   mySerial.read();
} 
   Serial.println ("Otpravil zapros Init");
    }


 

 

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

все что но сказал 

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

после строки  delay (5) добавь mySerial.read(); (уже поправил в 1483)

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

все что сказал

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

неудачно выбран пин 13. Это led arduino, при коннекте ардуино к PCM после включения зажигания, хорошо бы нажать кнопку ресет. Но при этом при перезагрузке ардуино встроенный led мигает, возможно это и мешает нормальному фаст иниту.

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

ща попробую. не не попробую , ТУПЛЮ. он вставлен уже

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

можешь попробовать переписать этот простой скетч с отображением байт от PCM не в сериал а на свой экран,  тоже упрощённо. Чтобы юсб питание не мешало, т.е. включаем зажигание - на ардуино и PCM одновременно подается питание, возможно тогда будет корректная связь. 

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

вот так сделал

#include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args

uint16_t ID;
 int x, y;
 char currentPage;
#include <SoftwareSerial.h>
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 byte messageInit[] = {0x81, 0x11, 0xF1, 0x81, 0x04};     // запрос инициализации
 
 void setup() {
  uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);
   
   Serial.begin(115200);
   pinMode(TX, OUTPUT);
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b);
   fastinit();
              }

  void loop() {   
   
  if (mySerial.available()) {Serial.print (mySerial.read(), HEX); Serial.print (" ");}
   
    }

 void fastinit() {
  
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(400);             // 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);
   initialization();
   }  
   
 void initialization() {
   for (int i = 0; i < sizeof(messageInit); i++) {
   mySerial.write(messageInit[i]);
   delay (5); 
   mySerial.read();
} 
   myGLCD.println ("Otpravil zapros Init");
    }

как и в сериале, просто пишет  Otpravil zapros Init

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

Строка 36 на лсд переделай вывод инфы

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

вот так сделал if (mySerial.available()) {Serial.print (mySerial.read(), HEX); myGLCD.print (" ", 100, 100);

и myGLCD.print ("Otpravil zapros Init", 50, 50);

только пишет Otpravil zapros Init

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

Дак не правильно. Serial.print поменять на lcd

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

та делал тоже if (mySerial.available()) {myGLCD.print (mySerial.read(), HEX); myGLCD.print (" ", 20, 20);}

выдает ошибку  no matching function for call to 'UTFTGLUE::print(int, int)'

 

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

Потому что так можно только текст распечатать, а для распечатки переменной там что то типа printNumI

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

написало Otpravil zapros Init и чуть ниже 83 и чтото еще заломаное. еду домой завтра буду в эфире

напечатал myGLCD.println

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

Ну вот, 83 это уже начало ответа от РСМ. Копай дальше

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

заработал вот этот

#include <Adafruit_GFX.h>
 #include <MCUFRIEND_kbv.h>
 #include <UTFTGLUE.h>//use GLUE class and constructor
 #include "TouchScreen.h"
 #include <stdint.h>
 #include <SPI.h>
 #include <EEPROM.h>
 MCUFRIEND_kbv tft;
 #include "Fonts/Gobold_Bold14pt7b.h";
 UTFTGLUE myGLCD(0x1581,A2,A1,A3,A4,A0); //all dummy args

uint16_t ID;
 int x, y;
 char currentPage;
#include <SoftwareSerial.h>
 #define TX 13
 SoftwareSerial mySerial   (12, 13); //RХ,TХ
 
 byte messageInit[] = {0x81, 0x11, 0xF1, 0x81, 0x04};     // запрос инициализации
 
 void setup() {
  uint16_t ID = myGLCD.readID();
    if (ID == 0xD3D3) ID = 0x9486; // write-only shield
    myGLCD.begin(ID);
   
   Serial.begin(115200);
   pinMode(TX, OUTPUT);
   myGLCD.InitLCD(3);
   myGLCD.clrScr();
   myGLCD.setFont(&Gobold_Bold14pt7b);
   fastinit();
              }

  void loop() {   
   
  if (mySerial.available()) {Serial.print (mySerial.read(), HEX); Serial.print (" ");}
   
    }

 void fastinit() {
  
   digitalWrite (TX, HIGH);  // makes K-line high 3
   delay(400);             // 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);
   initialization();
   }  
   
 void initialization() {
   for (int i = 0; i < sizeof(messageInit); i++) {
   mySerial.write(messageInit[i]);
   delay (5); 
   mySerial.read();
} 
   Serial.println ("Otpravil zapros Init");
    }
ответ в сериале
Otpravil zapros Init
83 F1 11 C1 6B 8F 40 
MaksVV
Offline
Зарегистрирован: 06.08.2015

хм, круто конечно что заработало, но  блин что поменялось? Почти не чего ведь , влияющее на обмен К-лайн. Попробуй в 1483 в строке 8 поставить delay (1000)  и между строками 10 и 11 delay (1000). У меня задумка сделать подключение к PCM адаптивное, не в сетапе, а в loop .   Типа если связь прервалась, то будет автоматическое переподключение сеанса связи. Поэтому я и хочу выяснить почему твой PCM так капризно коннектится, а то задуманное не получится.    У меня похожие проекты два корячатся . 

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

без делеев получаем Otpravil zapros Init

с делеем межуд 10 и 11 
Otpravil zapros Init
83 F1 11 C1 6B 8F 40 
 
минимальная задержка которая срабатывает это 700, ниже уже все