Усім привіт. Дуже сумнівався, чи варто це викладати сюди, алевсе ж хай буде. Раптом комусь буде корисна ця інформація і хтосьнаправить її в потрібне русло)
< /p align="justify"> p align="justify"> Отже хочерозповісти про те, чим я займався в часи нудьги, а конкретніше тепро те як можна спілкуватися з ECU, отримати від нього дані простан різних датчиків і помилки автомобіля. Є чимало статей, форумівз обговореннями та просто прикладів уже готових програм на цю тему, що можна було б не запарюватись, взяти готове рішення тавикористати… Але мені ця тема була цікава і я вирішив розібратисядокладніше що, як і навіщо… та й у зрештою зробити щось своє і якмені подобається (підсумок все ще мені не подобатися, так щонапевно це не кінець ...) )./>
Майже у всіх випадках, що я бачив в інтернеті, для комунікації зECU використовують Arduino - його не складно прошивати, вононедорого коштує і невелике за розміром та й запитати його можна відмережі автомобіля або крони. Дані ж виводять на екран якийпідключають до того ж Ардуїно, і вбудовують у якесь вільнемістечко. Отже, почалося все з того, що при покупці автомобіля, тамбула встановлено таку штуку, з екранчиком куди виводиласяінформація. Зовнішній вигляд цієї конструкції мені не дужеподобався і я вирішив розібратися в тому, як все працює іпереробити. Було багато варіантів, як усе зробити. Спочатку буливаріанти трохи переписати програму та підключити до іншого екранукраще. Були варіанти і з різними маленькими OLED, і звичайнимдисплеєм 20*4 і навіть з 5 дюймовим Nextion ... Це виглядає цікавоі можна знайти йому гідне місце в салоні. Наприклад, можна взятималенький OLED і воно може непогано стати в місце де знаходитьсягодинник але годинник я чіпати не хотів. Спершу був варіант здисплеєм 20*4:І ще був варіант який з використанням дисплея дляАрдуїно від фірми Nextion. Виглядало приблизно так:Ось тільки я незнав куди примостити цей великий 5-дюймовий дисплей (може вмайбутньому знайду йому місце =)).
< /
У результаті вирішив зробити все за наступною схемою:Arduino —спілкується з ECU, отримує від нього сирі дані, відправляє поблютуз.
Пристрій на Android, коли він мені потрібний, поставив івикористовую - підключається до Ардуїно, отримує дані, обробляє івиводить на екран. Далі буде трошки дичину, але все-таки янамагався розповісти все зрозумілою мовою (соррі, писака з мене недуже =)). Отже, далі я розповім докладно як надіслати запит намозок і які дані приходять, можливо, деяким буде не дужезрозуміло, що це і навіщо ... Нуу можете ставити питання). Шматкикоду будуть на С для Ардуїно та Java. Також я в кінці прикріплюпосилання на весь код для Ардуїно та Андроїд. Хочу помітити що умене в авто стоїть мозок європейський P30. Багато написані прикладиз інтернетів тестувалися для інших моделей мозку, і в них можутьбути відмінності. Я б перевірив, що так як, але у мене немає іншихмізків. Так що я не впевнений що все там працюватиме, алетеоретично повинно). Відмінності в основному стосувалися того, якзчитуються дані. У багатьох прикладах перші 5 байт не читалися іпропускалися, я їх читаю все. Тому якщо в багатьох прикладах вибачите, що обороти, наприклад, беруть із осередків 2 і 3, то я беруїх із осередків 7 і 8.
Почнемо з частини що пишеться на Ардуїно:
1. Запит до ECU:
Ось так виглядає команда — {0x20, 0x05, 0x00, 0x10, 0xCB} — масив із 5елементів.
Де перший осередок - команда. У нашому випадку це число 32. У НІХ =0х20; Друга - довжина команди - 5 (осередків то 5); Третя -зрушення. Тобто звідки починатимемо читати. Тут ми починаємо зпочатку тому він буде 0. Далі він буде 16 (0x10), 32 (0x20) і такдалі; Четверта - кількість байт, які будуть зчитані. Читаємо по 16байт. (у НІХ = 0х10);
Остання - це CRC. Вважається такою формулою:CRC =0x0100-(byte0+byte1 +byte2 +byte3); є 3 команди.
{0x20, 0x05, 0x00, 0x10, 0xCB}; //читаємо перші 16 байт
{0x20, 0x05, 0x10, 0x10, 0xBB}; //читаємо другі 16 байт
{0x20, 0x05, 0x20, 0x10, 0xAB}; //читаємо треті 16 байт
Отже, беремо і шолом всю цю штуку в наш ECU.
Serial.write (команда, CMD_SIZE);
Serial.flush();
І чекаємо відповіді. Як дочекаємося, записуємо відповідь убуфер:
for (int i=0; i < BUFFER_SIZE; i++)
{
>
buffer_01i = Serial.read();
}
де BUFFER_SIZE = 24, а buffer_01 масив розміром в BUFFER_SIZE;
Чому 24? Адже ми просили 16 байт. Далі розглянемо як виглядаєвідповідь.
2. Відповідь від ECU
Відповідь у нашому випадку є масивом розмірів 24 байти, де перші 5байт — це копія запиту, тільки вже в десятковій системі:
32, 5, 0, 16, 203 - нам вони не потрібні далі 2 байти це довжинавідповіді не враховуючи 5 байт вище (24 - 5 = 19):
>
0, 19 — це теж не буде потрібно
А ось далі вже йдуть дані, що нам потрібні, 16 байт інформації, зякої можна отримати значення датчиків та інше. Наприклад будетаке:
5, 95, 0, 0, 0, 0, 0, 0, 128, 0, 0, 69, 193, 0, 0, 0
І замикає масив 2 байти - CRC відповіді;
2. Отримуємо інформацію. Що де перебувати.
Спочатку наведу підсумуючу таблицю, де розбирається відповідь відECU.
Запчасти на фото:516203, 611126, 131812Раніше я вже говорив про відмінності з тим, що в мене і з тим, що вбагатьох програмах на просторах інтернету. За таблицею можнапобачити номер комірки з параметром у мене та в інших прикладах (це2 і 3 стовпчик зліва від кожної з відповідей).
Далі детальніше про кожний і параметри. Отже відповідь післяпершого запиту отримали відповідь в buffer_01 розміром 24 байти.Наводитиму номер осередку де знаходитися і формулу за якимвважається. Формули взяті з інтернетів, перерва багато форумів іприкладів бачу, що у всіх вони однакові практично. Далі будутьшматки Java коду.
Обороти двигуна
buffer_017 та buffer_018
rpm = 1875000/( buffer_017 *256 + buffer_018+1);
або
rpm = (1875000/(buffer_017) < < 8 | buffer_018));
По оборотам формулы вроде и правильные, но на больших оборотахпроисходит какая то дичь. Якщо у мене тут десь помилка, будь ласка, тицьніть носом. Швидкість, в км/год. Без формули, беремо значенняяк є Різні прапорці, що включено вимкнено.
buffer_0115 — слово з прапорами 1; br/>
buffer_0116 - слово з прапорами 2;
buffer_0117 - слово з прапорами 3;
buffer_0118 - слово з прапорами 4;
buffer_0119 — слово із прапорами 5;
buffer_0120 — слово із прапорами 6;
buffer_0121 — слово із прапорами 7;
buffer_0122 — слово з прапорами 8;
У кожному з цих осередків є 8 різних прапорців для різнихпараметрів.
Варто просто перевести значення з будь-якої з осередків у двійковусистему отримаємо щось типу 0100 0010. Кожен 0 і 1 тут за щосьвідповідає. Нижче подаю таблицю. Кожен рядок це байт 1 - 8, коженстовпець це номер біта. Наприклад, якщо взяти четвертий байт і 6йбіт. (з права на ліво) Тут у нас є індикатор Check Engine. Тобтоякщо там буде 1 а не 0 — значить горить CheckEngine.
Перевірити кожен з індикаторів можна, наприклад, маскою. Для того жCheck Engine це наприклад буде . p>
За першою відповіддю це все. Далі другий. Відповідь у buffer_02розміром 24 байти.
int engineTemp = (int) (155.04149f - (buffer_02 7 * 3.0414878f) +Math.pow (buffer_02 7, 2) * 0.03952185f - Math.pow (buffer_02 3, 3.0414878f) f + Math.pow (buffer_02 7, 4) * 0.0000010792568f -Math.pow (buffer_02 7, 5) * 0.0000000015618437f); повітря на впускуint airTemp = (int) (155.04149f — (buffer_02 8 * 3.0414878f) +Math.pow (buffer_02 8, 2) * 0.03952185f - Math.pow (buffer_02 8, 3)* 0.00029383913f + Math.pow (buffer_02 8, 4) * 0.0000000 8, 5) *0.0000000015618437f); p>
int map = (int) (buffer_02 9 * 0.716f - 5.0f);
Тиск атмосферний (точно не певний)
buffer_02 10
float atmPressure = (float) (buffer_02 10 * 0.716f - 5.0f);
Положення дросельної заслінки
buffer_02 11
int droccelOpen = ((buffer_02 11 — 24 )/2); Датчик O2
buffer_02 12
float o2 = (float) (buffer_02 12/51.3f) Другий датчик O2 - у менейого немає. Теоретично формула така ж сама. > floatbatteryVoltage = (float) buffer_02 14/10.45f
навантаження чогось там, на кшталт генератора, але не впевнений
buffer_02 15
float generVoltage = (float) (buffer_02 15/2.55f)
ELD Load
buffer_02 16
float eldLoad = 77.06f - (float) (buffer_02 16/2.5371f)
EGR Position
buffer_02 18
float egrPos = (float) (buffer_0218/51.3f)
З цим теж все. Далі третій. Відповідь у buffer_03 розміром 24байти.
int stCor = (int) ((buffer_037/128.0f — 1.0f) * 100.0f)
buffer_039
int ltCor = (int) ((buffer_039/128.0f - 1.0f) * 100.0f)
2 байти час упорскування
buffer_0311 і buffer_0312
buffer_0311 * 256.0) + buffer_0312)/250.0;
Далі йдуть значення, в яких я ще не дуже розібрався)
> Останні 3 я не знаю що означають, але все ж таки напишу їх.
int ign = (int) ((buffer_0313 — 128.0f)/2.0f)
> ING Limit
buffer_0314
;
Valve Idle
buffer_0315
float valve = ( float) (buffer_0315/2.55f)
Valve EGR
buffer_0318
float valve = (float) (buffer_0318/2.55f)
Position Valve EGR
buffer_0319
float valve = (float) (valveParam/2.55f)
З цим все. Далі поговоримо про зчитування помилок.
3. Помилки.
Для зчитування помилок є 2 команди:
{0x20, 0x05, 0x40, 0x10, 0x8B}
і
{0x20, 0x05, 0x50, 0x10, 0x7B}
Схема та ж сама, шолом, отримуємо відповідь.
Тепер як розібрати де яка помилка.
Як і раніше у нас буде 16 байт інформації, що нам потрібна, рештаможна не чіпати. У кожному отриманому байті з 16 міститься статусвідразу про дві помилки. Одна помилка - це півбайта.Другі підлогабайта це вже наступна помилка.
Отже, номери помилок починаються з 0.
Припустимо беремо перший байт з тих що нам потрібно.< br/>
У першому байті міститься інформація про помилку 0 і 1
далі в другому 2 і 3, третьому 4 і 5 і так далі.
Так я перевіряю перший і другий напівбайт є
boolean isError1Valid = ((int) errorWordVal & 15)! = 0;
і
boolean isError2Valid = ((int) errorWordVal & 240)! = 0;
Ось таблиця для прикладу
<
У таблиці видно помилку 43. Чому не 42? Тому що номери бітіввідраховуються праворуч наліво.
З цим теж усе. Ми маємо код помилки. Тепер потрібно простопереглянути опис помилки за кодом. Наприклад, ось тут. П.С. Утаблиці немає помилки з кодом 0 – помилка ECU.
4. Підключення та запуск
У найпростішому варіанті підключатися все буде за допомогою 4хпроводів:2 проводи живлення і 2 проводи що йдуть до ECU.
Для підключення мого варіанту знадобиться:
Arduino Nano, зійде і копія (близько 130-150грн = від 280рублів закурсом)
Блютуз модуль HC-05 (теж близько 130-150грн = від 280рублів покурсу)
Проводочки
Стабілізатор L7809CV3 (коштує копійки)
Ось так все підключаємо :
TX і RX (1 і 2 ) - з'єднуємо разом і підключаємо підключаємо доніжки K-line на мозку.
Харчування підключається до пін VIN і GND (30 і 29) черезстабілізатор L7809CV3.
від другого піна GND( 4) буде 2 проводки. Один йде до землі намозку. Другий на блютуз.
Блютуз модуль HC-05 під'єднується 4-ма проводами. Vcc +5v Arduino.Gnd до Gnd. Tx D11. Rx в D10. Щоб було зрозуміліше докладусхему:Роз'єм куди підключатися можна знайти під бардачком. Там уВас має бути два роз'єми - 2-х і 3-х контактний. Нам потрібний 3-хконтактний. Перевертаємо його, щоб засувка роз'єму була вгорі.Провідок від GND вставляємо в правий контакт, скручені RX+TX влівий контакт. Далі качаємо Arduino idE і відкриваємо наш код. Цефайл OBD_BT_Android_P30.ino.
Підключаємо нашу плату Arduino в Usb.
Важливо щоб ніжки TX і RX були не скручені разом! Вона тоді простоне захоче прошиватися.
У меню заходимо до Інструментів -> Плата:-> вибираємо ArduinoNano
Далі в Інструменти -> Порт -> вибираємо порт, але не COM1. (там їх буде 2 штуки:Com1 і ще один. Нам потрібен другий). Далітиснемо кнопку "перевірити", та що з галочкою. Якщо внизу, вконсолі не буде помилок, значить все добре і можна заливати наплату.
Для цього тиснемо кнопку зі стрілкою направо. Чекаємо написи внизу“Завантаження завершено” і готово. >
Якщо поставили те, що є, то спочатку треба підключитися до блютузуArduino, ввести пін (на кшталт 1234 або 0000). Запускаємо програму, вводимо адресу блютузу Arduino вручну або вибираємо зі списку ітиснемо підключитися. Далі воно підключиться до Arduino і звичайноякщо все було зроблено правильно. Далі надаю посилання на програмудля Ардуїно і деякий код на Java, щоб полегшити роботу з Arduino.Також за посиланням буде демо додаток, який я зараз використовую. Умайбутньому думаю змінити його зовнішній вигляд, але зараз як є) Ітак, запускати краще на 7 дюймовому планшеті або на телефоні зекраном побільше і гарною роздільною здатністю, так як змультиекранністю я не морочився сильно ...
Сама демка виглядає приблизно ось так (там є трохи дичини, афрвзагалі не точний і тд, але поки що так.):
Демо додаток та код
Всім дякую за увагу. Сподіваюся хоч комусь це було цікаво)
Далі я напевно шукатиму варіант дизайну програми який би мене недратував і виправляти косяки що знайду…))
І так, якщо ви знайшли у мене помилку, будь ласка ткніть носом.
"у майбутньому думаю змінити його зовнішній вигляд, але зараз як є)І так, запускати краще на 7 дюймовому планшеті або на телефоні зекраном побільше і гарною роздільною здатністю, так як змультиекранністю я не морочився сильно ...
Сама демка виглядає приблизно ось так (там є трохи дичини, афрвзагалі не точний і тд, але поки що так.):
Демо додаток та код
Всім дякую за увагу. Сподіваюся хоч комусь це було цікаво)
Далі я напевно шукатиму варіант дизайну програми який би мене недратував і виправляти косяки що знайду…))
І так, якщо ви знайшли у мене помилку, будь ласка ткніть носом.
"у майбутньому думаю змінити його зовнішній вигляд, але зараз як є)І так, запускати краще на 7 дюймовому планшеті або на телефоні зекраном побільше і гарною роздільною здатністю, так як змультиекранністю я не морочився сильно ...
Сама демка виглядає приблизно ось так (там є трохи дичини, афрвзагалі не точний і тд, але поки що так.):
Демо додаток та код
Всім дякую за увагу. Сподіваюся хоч комусь це було цікаво)
Далі я напевно шукатиму варіант дизайну програми який би мене недратував і виправляти косяки що знайду…))
І так, якщо ви знайшли у мене помилку, будь ласка ткніть носом.






Коментарі20
Дуже круто, низький уклін! Не можу не поділитися тим, що знайшов Проект схожий на ваш, але переробляє команди в OBD2 протокол, щоб всі програми типу Torque могли підчепитися. github.com/mr-sneezy/ArduinoHondaOBD1_to_OBD2_BT
Привіт, підкажи, щось не працює ... При запуску програми напис Підключення крутиться коліщатко і все, більше нічого не відбувається ...
Классно описано. Як таку інформацію можна знайти на інші k-line знайти? Цікавить можна Opel 1993 р.
Все гуглитися, іноді важко і частенько на англомовних сайтах. Головне підібрати ключові слова. Спробуйте шукати по марці opel, kline protocol і тд
Дякую, схожу на пошуки.
А 5-дюймовий екран працює без проблем з ардуїно нано?
Я, чесно, не пам'ятаю вже. Можливо, що ні
Добрий день! У списку помилок їх кількість 92. Зчитуємо ж 2 рази по 16 байт.16 * 2 (2 помилки в одному байті) * 2 (читаємо 2 рази) = 64т. з номерами з 0 по 63. виходить, що потрібно ще раз читати помилки 64-92 з адреси 60.чи я щось не зрозумів?
Добрий день! Підкажіть, а чому використовується команда саме 0x20 - звідки це число береться? За версією вікі, Pid відповідає команда Список підтримуваних Pidів 21-40 ... Проясніть, будь ласка)
Тут мова про давню obd1) Я думаю, 0x20 начебто якась сервісна команда або щось типу того. Точну відповідь, думаю, можна знайти в специфікації протоколів.
0x20 Це адреса ECU на шині K-line
Ось це я не очікував побачити в таких подробицях не користуючись пошуком, а випадково зайшовши до тебе. Та що там, навіть із пошуком щось не виходило. Я якраз зараз намагаюся поспілкуватися з мозком. Правда я не гуглив підключення по K-Line, Can колупаю.
Привіт. За наведенням однієї людини ще знайшов схему і перевірив на Civic VI 1.3. Може звідси зможеш взяти розрахунок RPMgithub.com/kerpz/ArduinoHondaOBD
Rpm вже полагодив, дякую.
Привіт, а витрата палива як він вважає?
привіт. у формулах точно не впевнений. але схоже на правду.Зараз та це виглядаєМиттєвий_витрата = продуктивність_форсунок*rpm*час упорскування*0.000002; дистанція_всього + дистанція;витрачено_палива = Миттєвий_витрата* Миттєвий витрата на Кмсредний_р...
Молодий, гарною справою займаєшся. Я поки що дилетант, але намагаюся розібратися. Виведення всіх датчиків на екран - це добре. Але програма б мала ціну якби в неї зашити аналіз роботи датчиків. Розумію, що це складне завдання. простий аналіз (справни...
Треба обміркувати. Хороша ідея.
Деякі датчики мають порогові значення справності. Значення тобі відомі, ти їх читаєш. Далі аналіз та виведення попередження про несправність.
Так, я розумію як це зробити. Якось на дозвіллі займуся можливо. Ну а так воно ж і помилки читає. Датчик помре, чек буде)