Модераторы: Snowy, MetalFan, bems, Poseidon

Поиск:

Закрытая темаСоздание новой темы Создание опроса
> Принять данные от машины по k-line, т.е. принять их по COM порту и разобрать 
:(
    Опции темы
mr_smit
  Дата 12.10.2011, 08:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Здравствуйте. Давно я не программировал на Delphi. А тут задался целью сделать для своей машины (ВАЗ 11183) считыватель ошибок на микроконтроллере. Чтобы разобраться с протоколом, хочу для начала из своего приложения на ПК посмотреть/почитать данные. Диагностическая линия (k-line) представляет из себя "обычный ком порт" только с измененными логическими уровнями. 0 вольт - это логический 0, +12 вольт - это логическая единица. У ком порта 0 это минус 12 вольт. Собственно все переходники для машины и представляют собой просто согласователи этих самых уровней.
Скачал бесплатную программу Diagnostic Tools. Подключился к машине. Всё работает. Всё показывает. Взял снифер ком порта, посмотрел что шлет программа. Скачал описание протокола обмена. Чуда не произошло, всё строго по пунктам smile

Не буду сильно вдаваться в подробности протокола. Собственно что меня интересует:

1. Чтобы начать диагностику, нам надо отправить:

Запрос startCommunication:
  81 10  F1 81 03
Ответ:
  83 F1 10 C1 6B 8F 3F

В ответе C1  означяет что ЭБУ готов с нами работать.

Поставил компонент AsyncFree104 для работы с com портом:
Код

var
  startCommunication: array [0..4] of byte = ($81, $10, $f1, $81, $03);

...

procedure TForm1.Button1Click(Sender: TObject);
begin
  AfComPort1.Open;
  AfComPort1.WriteData(startCommunication, sizeof(startCommunication));
end;


Как мне прочитать ответ? И как оттуда вытащить C1 ?

2. Сдернул клемму. Прочитал ошибки свои. Для определения значений данного параметра используется десятичная (BCD) кодировка.

Запрос ошибок readDTCByStatus:
  84 10 F1 18 00 00 00 9D
Ответ:
  88 F1 10 58 02 04 43 E0 14 26 E0 24
  
P0443  -  всё верно, 2 ошибки появилось.
P1426

Первые 3 байта нас не интересуют. Нам интересно: 58 - положительный ответ, 02 - число ошибок, дальше ошибки разделенные E0. Последняя цифра во всех запросах/ответах - контрольная сумма (2 младших разряда).

Как вытащить ошибки из этого ответа?

У компонента есть:
Код

AfComPort1.ReadData (var Buf; Size: Integer);

Как принимать в этот Buf ? Если длинна его меняется. И как разобрать данные?


Это сообщение отредактировал(а) mr_smit - 12.10.2011, 08:33
PM MAIL   Вверх
bems
Дата 12.10.2011, 08:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



1. В чем вопрос-то? Как вытащить четвертый байт из буффера?
2. Выделять с запасом


--------------------
Обижено школьников: 8
PM MAIL   Вверх
mr_smit
Дата 12.10.2011, 08:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Пока писал, сам сообразил. Вроде так:

Код

procedure TForm1.Button1Click(Sender: TObject);
begin
AfComPort1.Open;
AfComPort1.WriteData(startCommunication, sizeof(startCommunication));
AfComPort1.ReadData(ReadBuffer, Length(ReadBuffer));
if ReadBuffer[3] = $C1 then
  begin
  Label1.Caption:='ЭБУ на связи';
  end;
end;

Так?

Это сообщение отредактировал(а) mr_smit - 12.10.2011, 08:56
PM MAIL   Вверх
bems
Дата 12.10.2011, 09:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



зависит от того что такое ReadBuffer, но похоже, да


--------------------
Обижено школьников: 8
PM MAIL   Вверх
mr_smit
Дата 12.10.2011, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Цитата(bems @ 12.10.2011,  09:04)
зависит от того что такое ReadBuffer, но похоже, да

Да, забыл написать
Код

ReadBuffer: array of byte;


Если так, то тогда ещё вопрос:

BCD кодировка, как с ней работать? Как мне, например, в Memo отобразить ошибки?


Это сообщение отредактировал(а) mr_smit - 12.10.2011, 09:06
PM MAIL   Вверх
bems
Дата 12.10.2011, 09:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 3400
Регистрация: 5.1.2006

Репутация: 18
Всего: 88



ну и там же наверное чтонить и возвращается из WriteData и ReadData


--------------------
Обижено школьников: 8
PM MAIL   Вверх
mr_smit
Дата 12.10.2011, 09:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Хочу прочитать ошибки из тестового массива. 
Код

TestArray: array[0..11] of byte = ($88,$f1,$10,$58,$02,$04,$43,$E0,$14,$26,$E0,$24);
...
procedure TForm1.Button2Click(Sender: TObject);
var i:integer;
      j:integer;
begin
j:=5;
for i:=0 to TestArray[4]-1 do     // 5-й байт - число ошибок
  begin
  Memo1.Lines.Add('P'+IntToStr(TestArray[j])+IntToStr(TestArray[j+1]));
  j:=j+3;
  end;
end;


В мемо получается:
P467
P2038

А должно:
P0443
P1426

Как перевести из BCD формата в String?

Это сообщение отредактировал(а) mr_smit - 12.10.2011, 09:48
PM MAIL   Вверх
AndreyIQ
Дата 12.10.2011, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 5.2.2007

Репутация: 1
Всего: 8



Код

Memo1.Lines.Add('P'+IntToHex(TestArray[j],2)+IntToHex(TestArray[j+1],2));

PM MAIL   Вверх
mr_smit
Дата 12.10.2011, 10:15 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Цитата(AndreyIQ @ 12.10.2011,  09:49)
Код

Memo1.Lines.Add('P'+IntToHex(TestArray[j],2)+IntToHex(TestArray[j+1],2));

Оооооо....!!!! Спасибо! Работает.

Кстати. Вот запрос параметров:
  82 10 F1 21 01 A5
ЭБУ моей машины отвечает:
 80 F1 10 26 61 01 3B 90 41 04   
 00 00 00 00 47 80 00 00 00 52 52 80 18 00 8E 00   
 5C 00 00 00 00 00 00 00 00 00 FF FF DD A4 47 02

 CE

61 - Положительный ответ readDataByLocalIdentifier
01 - afterSalesServiceRecordLocalIdentifier (что то там....)
....
11-й байт - Температура охлаждающей жидкости
....


Формула для расчета: N=E-40 [°C]
  E - передаваемое значение
  N - физическая величина
У меня это значение 47. Берем windows калькулятор. Переводим 47 hex в dec. Получаем 71. Дальше 71-40=31°C. Соглашусь. На момент снятия данных машина часа полтора простояла на улице. До конца не остыла.

Как бы мне теперь на Delphi так конвертнуть?
PM MAIL   Вверх
AndreyIQ
Дата 12.10.2011, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 5.2.2007

Репутация: 1
Всего: 8



Цитата(mr_smit @ 12.10.2011,  10:15)
47 hex в dec

Код

StrToInt('$' + IntToStr(47))

PM MAIL   Вверх
mr_smit
Дата 12.10.2011, 11:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Чего то у меня в ошибку вываливается на строке:
Код

if ReadBuffer[3] = $C1 then


Может где то длинну массиву назначать?

Это сообщение отредактировал(а) mr_smit - 12.10.2011, 11:48
PM MAIL   Вверх
AndreyIQ
Дата 12.10.2011, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 185
Регистрация: 5.2.2007

Репутация: 1
Всего: 8



Цитата(mr_smit @ 12.10.2011,  11:48)
Может где то длинну массиву назначать?

SetLength.

Это сообщение отредактировал(а) AndreyIQ - 12.10.2011, 11:58
PM MAIL   Вверх
mr_smit
Дата 12.10.2011, 11:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Кажется понял, ReadBuffer у меня сейчас пустой, а я пытаюсь 4-й элемент массива прочитать.

А где её задавать? Сразу после чтения?
Код

SetLength(ReadBuffer, Length(ReadBuffer));


Добавлено @ 12:07
Код

AfComPort1.ReadData(ReadBuffer, sizeof(ReadBuffer));
SetLength(ReadBuffer, Length(ReadBuffer));
try
if ReadBuffer[3] = $C1 then
  begin
  Label1.Caption:='ЭБУ на связи';
  end;
except
  Label1.Caption:='нет ответа от ЭБУ';
end;


Так?

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

Это сообщение отредактировал(а) mr_smit - 12.10.2011, 13:51
PM MAIL   Вверх
northener
Дата 12.10.2011, 14:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1361
Регистрация: 2.9.2010

Репутация: 12
Всего: 20



Цитата(mr_smit @  12.10.2011,  11:58 Найти цитируемый пост)
AfComPort1.ReadData(ReadBuffer, sizeof(ReadBuffer));
SetLength(ReadBuffer, Length(ReadBuffer));

1. Размер массиву ReadBuffer задавать ДО передачи его в качестве параметра функции ReadData.
2. Размер массива это Length, а SizeOf это размер переменной, которая хранит адрес массива в памяти.
3. Первый параметр в функции ReadData должен быть передан как ReadBuffer[0].


--------------------
Но только лошади летают вдохновенно.
Иначе лошади разбились бы мгновенно!
PM MAIL   Вверх
mr_smit
Дата 12.10.2011, 15:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 254
Регистрация: 27.2.2008
Где: Самара

Репутация: нет
Всего: 4



Чего то у меня не работает код smile

Дело в том что, как я понимаю, поскольку по K-Line обмен идет по одному проводу, то в момент передачи, принимать ничего не надо! Закончили передавать - начинаем линию слушать. Вот как этот момент реализовать?

Добавлено @ 15:39
Я когда сниффером обмен смотрю:
Запрос startCommunication:
  81 10  F1 81 03
Ответ:
  81 10  F1 81 03 83 F1 10 C1 6B 8F 3F

Реальный ответ это только 83 F1 10 C1 6B 8F 3F. А в начале идет запрос, просто он автоматом попадает на вход. Провод то связи один.  Он и на передачу работает и на прием.


Это сообщение отредактировал(а) mr_smit - 12.10.2011, 15:46
PM MAIL   Вверх
Страницы: (3) Все [1] 2 3 
Закрытая темаСоздание новой темы Создание опроса
Правила форума "Delphi: Для новичков"
SnowyMetalFan
bemsPoseidon
Rrader

Запрещается!

1. Публиковать ссылки на вскрытые компоненты

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

  • Литературу по Дельфи обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Дельфи


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Snowy, MetalFan, bems, Poseidon, Rrader.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: Для новичков | Следующая тема »


 




[ Время генерации скрипта: 0.1192 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.