Подключение к ECU авто

vitya-20051
Offline
Зарегистрирован: 10.09.2015

Здравствуйте.

Уже неделю бьюсь над проблемой, считать данные с мозгов авто по k-line.

Знаю, что если мозгам отправить  81 13 F0 81 05, ответ должен прийти  81 13 F0 81 05 83 F0 13 C1 E9 8F BF .

Перед тем, как отправить запрос, линию нужно подтянуть на 35мс к земле, потом обратно на 15мс и запрос.

Накидал програмку

#include <SoftwareSerial.h>
SoftwareSerial mySerial(10, 11); // RX, TX

void setup()  
{
  pinMode(11, OUTPUT);   
  Serial.begin(9600);
}

void loop() 
{
  digitalWrite(11, LOW);  
  delay(35);              
  digitalWrite(11, HIGH);   
  delay(15);

  mySerial.begin(9600);

  mySerial.write(0x81);  
  mySerial.write(0x13);  
  mySerial.write(0xF0);  
  mySerial.write(0x81);  
  mySerial.write(0x05);

  if (mySerial.available()>0){
    Serial.print(mySerial.read(),HEX);
  }

  mySerial.end();
  delay(1000);
}

В ответ мозги шлют 0(в терминале выглядит так 00 C0 00 00 C0 00 00 00 00 00 00 F8) Каждая цифра один запрос. Что не так, я не знаю, может, кто сталкивался?

PS. Через ELM не получится подключиться, т.к. протокол OBD1 и процесс инициализации типа Fast не соответствует у ELM.(У ELM по 25мс, у тойоты Low 35мс и High 15мс)

__Alexander
Offline
Зарегистрирован: 24.10.2012

там скорость 10400.

vitya-20051
Offline
Зарегистрирован: 10.09.2015

У тойоты скорость обменна по k-line 9600. У меня и комп на этой частоте подключатся нормально.

Radjah
Offline
Зарегистрирован: 06.08.2014

Замени if на while в 25 строке

__Alexander
Offline
Зарегистрирован: 24.10.2012

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

vitya-20051
Offline
Зарегистрирован: 10.09.2015

Заменил, но толку ноль. Я к Rx подцепился терминалом отдельно и мониторю. Паузу поставил в 35мс.(((

__Alexander
Offline
Зарегистрирован: 24.10.2012

используй лучше аппаратный уарт.

vitya-20051
Offline
Зарегистрирован: 10.09.2015

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

__Alexander
Offline
Зарегистрирован: 24.10.2012

странно. бут слетает? а внешнего программатора нет?

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

vitya-20051
Offline
Зарегистрирован: 10.09.2015

Фьюзы слитают(нужно будет фьюзодоктор собрать)

Подключил к аппаратному uart.

К k-linу подцепил второй k-line, что бы посмотреть, что передает.

Отправляю это 

   Serial.write(0x81);
   Serial.write(0x31);
   Serial.write(0xF0);
   Serial.write(0x81);
   Serial.write(0x05);

В терминале вижу HEX:3F 67 D0 EA 00  DEC:63 103 208 234 0

А по сути должен увидеть 81 31 F0 81 05

Что может идти не так?

Radjah
Offline
Зарегистрирован: 06.08.2014

В чем смысл строк 12-15?

17 в setup, 29 не нужна.

vitya-20051
Offline
Зарегистрирован: 10.09.2015

Fast-init это у toyota протокола...

GraninDm
Offline
Зарегистрирован: 01.08.2013

Я с k-line не работал. Может глупость спрошу, но почему mySerial.begin(9600); и mySerial.end(); в основном цикле находится?

Не правильнее ли просто открыть порт и читать/писать в него.

GraninDm
Offline
Зарегистрирован: 01.08.2013
if (mySerial.available()>0){
    Serial.print(mySerial.read(),HEX);
}

Так ничего не прочитатется. Нужно в цикле считывать поступающие данные и добавлять их в строку, например.

На момент проверки mySerial.available()>0 данные могли еще не поступить в порт и потом порт закрывается, и все пропадает.

vitya-20051
Offline
Зарегистрирован: 10.09.2015

Для инцилизации нужно поджать линию k-line к 0в на 35 мс, потом поднять до 12в на 15мс и только потом передавать данные.

GraninDm
Offline
Зарегистрирован: 01.08.2013

Я думаю инициализацию нужно делать отдельным ключем, а не портом, потому как при mySerial.end буфера сбросяться.

Логика в коде неправильная.

vitya-20051
Offline
Зарегистрирован: 10.09.2015

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

GraninDm
Offline
Зарегистрирован: 01.08.2013

Это не запрос не проходит, а ответ не приходит. По краеней мере так в коде.

После 

...

mySerial.write(0x05);

Ответ еще не пришел

mySerial.available() будет 0

Считывания не будет.

После этого порт закрывается

mySerial.end();

А вто тут delay(1000); данные приходят в закрытый порт, т.е. пропадают.

GraninDm
Offline
Зарегистрирован: 01.08.2013

Тогда по вашей логике нужно поставить задержку после mySerial.write(0x05);, чтобы данные пришли в буфер порта

__Alexander
Offline
Зарегистрирован: 24.10.2012

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

GraninDm
Offline
Зарегистрирован: 01.08.2013

Аппаратный UART и так работает по прерыванию.  Я код библиотеки аппаратного порта изучил вдоль и поперек.

Да и программный тоже

Multi-instance software serial library for Arduino/Wiring
-- Interrupt-driven receive and other improvements by ladyada
 
Так что ничего специально делать не нужно.
Просто читать в цикле данные и склеивать их с уже поступившими.
GraninDm
Offline
Зарегистрирован: 01.08.2013

Вот код из SoftwareSerial

// Read data from buffer
int SoftwareSerial::read()
{
  if (!isListening())
    return -1;

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

 

vitya-20051
Offline
Зарегистрирован: 10.09.2015

да, понятно... Как удалить тему?