در قسمت قبل، با مقدماتی درباره پروتکلهای مختلف در رابط OBD-II آشنا شدیم. همچنین آموختیم که OBD2 صرفاً یک درگاه نیست، در واقع یک interface یا رابط 16 پین است که همهی پینهای آن همزمان استفاده نمیشود و در خودروهای مختلف با توجه به نوع پروتکل، سیمهای مورد استفاده مشخص میشود. مشخصات پنج پروتکلی که تحت OBD2 بودند را نیز بررسی کردیم. حال در این مقاله قصد داریم تا با جزئیات بیشتری از پروتکل K-Line آشنا شده و نحوه برقراری ارتباط، ارسال و دریافت اطلاعات در این پروتکل را بررسی کنیم.
با این آموزش همراه باشید.
هشدار: در برخی از کشورها، دستکاری دیاگو تغییر اطلاعات آن جرم بوده و پیگرد قانونی دارد. ما در این مقاله تنها اطلاعات عمومی در مورد دیاگ و خواندن اطلاعات از آن را به شما آموزش میدهیم.
هشدار: از آنجایی که قسمتهای زیادی از این مطلب بهصورت متن باز در دسترس عموم قرار نداشت، اطلاعات زیر از طریق منابع مختلف و تستهای مکرر جمع آوری شدهاند. با وجود اینکه عملکرد کدها تست شدهاند، اما ؟هیچگونه مسئولیتی در قبال صحت، عملکرد و… مطالب زیر ندارد. بهطور کلی مسئولیت هرگونه استفاده از مطالب، خسارت احتمالی و… به عهدهی خواننده میباشد.
CAN
در ایران، خودروهایی که مالتی پلکس شدهاند، مثل 206 و L90 از این نوع پروتکل استفاده میکنند. در مورد این پروتکل، قبلاً در سیسوگ به طور مفصل توضیح داده شده است، بنابراین توصیه میکنم برای مطالعه این پروتکل از مقاله آشنایی و راهاندازی پروتکل CAN با استفاده از STM32 استفاده کنید. در این مقاله، به بررسی پروتکل ارتباطی CAN، مختصری از نحوهی پیکربندی (کانفیگ) اولیه آن، فریمهای ارسالی، نحوه اولویت بندی پیامها، سیمکشی شبکهی CAN و… به زبان ساده توضیح داده شده است. سخت افزار مورد استفاده در این آموزش STM32 است. اما توضیحات پروتکل CAN در ابتدای مقاله، ارتباطی با این موضوع ندارد و شما بر روی هر نوع میکروکنترلری که کار میکنید، میتوانید این مقاله را مطالعه کنید.
پس از مطالعه اصول اولیه پروتکل CAN، مقاله آموزشی که در مورد توضیحات مربوط به حکمیت و خطاهای ارسال و دریافت در ارتباط CAN_BUS میباشد نیز میتواند به شما در درک بهتر لایه CAN کمک کند. حال با انجام پروژه عملی FMS READER شما تقریباً میتوانید یک دیاگ اختصاصی خودتان را برای این پروتکل بسازید! با خواندن اطلاعات ECU خودرو از درگاه CAN میتوانید به اطلاعات حیاتی خودرو مثل: وزن محور (کیلوگرم)، میزان کل مصرف سوخت (لیتر)، میزان سطح سوخت (درصد)، سرعت موتور، سرعت خودرو (مطابق با لاستیک خودرو) و… دست پیدا کنید.
نکته ای در مورد تراشه MCP2551 و tja1050
تراشه MCP2551 و tja1050 از معروفترین تراشهها برای استفاده در پروتکل CAN هستند. اما نکتهای که برای استفاده از این تراشهها وجود دارد و شاید ندانستن آن وقت و انرژی بسیاری را از شما بگیرد، این است که این تراشهها مبدل CAN BUS به UART نیستند! اگر به pinout این تراشه دقت کنید، یک طرف CAN H و CAN L است و طرف دیگر Tx و Rx. این موضوع باعث میشود که شما اشتباهاً فکر کنید این تراشه رابط سریال است! اما هر گردی گردو نیست! از آنجایی که لایه فیزیکی CAN BUS تفاضلی است، این تراشهها ولتاژ را به جریان تبدیل میکنند.
منظور از Tx و Rx در واقع CAN_TX و CAN_RX بوده است. بنابراین این تراشه فقط هنگامی در مدار استفاده میشود که خود میکرو شما نیز از CAN پشتیبانی کند. چون این قسمت از مدار به جریان بیشتری لازم داشته، به همین خاطر آن را در داخل خود میکرو جاسازی نکردهاند. البته ماژولهایی وجود دارند که کار تبدیل CAN به UART را انجام میدهند، اما بهتر است از میکرویی استفاده کنید که خود دارای CAN باشد.
K-Line
K-Line معمولاً در اکثر خودروهای ایرانی مثل پراید مورد استفاده قرار میگیرد. K-Line خود پروتکل مجزایی نیست، بلکه نام یکی از خطوط ارتباطی در دو پروتکل ISO 9141-2 و ISO 14230 KWP2000 میباشد. ارتباط این دو سیم، بسیار شبیه به Tx و Rx در انتقال سریال غیر همزمان است، اما تفاوتهایی نیز در سطح ولتاژ و دیگر ویژگیها با UART دارد. به پینها و ویژگیهای این دو پروتکل دقت کنید:
در هر دو پروتکل، K-Line پین شماره 7 میباشد و استفاده از L-line نیز در اکثر وسایل اختیاری میباشد. تراشههایی مثل L9637D، MC33660، MC33199، MC33290 و … به راحتی خطوط K-Line را در مدار شما به Tx و Rx تبدیل میکنند:
شروع ارتباط با ECU
حال که مسیر ارتباط را کامل کردیم، نوبت به نحوه برقراری ارتباط با K-LINE میرسد. برای برقراری ارتباط اولیه یا initialize، دو راه وجود دارد: شروع سریع و شروع کند.
شروع سریع
برای شروع سریع یا Fast init، شما ابتدا باید ECU را از خواب بیدار کنید و به او بگویید که با آن کار دارید! برای این کار شما میبایست یک سیگنال Wake up مربعی به فرم زیر روی خط Tx ارسال کنید:
300 میلی ثانیه سیگنال یک منطقی (High)
25 میلی ثانیه سیگنال صفر منطقی (Low)
مجدداً 25 میلی ثانیه یک منطقی (High)
حال، تنظیمات پورت سریال خود را به این صورت تغییر دهید:
10400 Baud, 8 Bit, No parity, 1 Stop
سپس بایت های زیر را روی خط Tx ارسال کنید:
{0xc1, 0x33, 0xf1, 0x81, 0x66}
0xc1 : آدرس ECU
0xf1 : آی دی وسیله ی ما
0x81 : شروع ارتباط
0x66: چک سام
سپس منتظر پاسخ ECU به فرم زیر بمانید:
{0x83, 0xf1, 0x01, 0xc1, 0xe9, 0x8f}
بایت سوم: 0x01 : آدرس لایه فیزیکی
بایت چهارم: 0xC1
نتیجه ارتباط است که شامل دو حالت دارد:
0x7f : شکست یا fail
0xc1: موفقیت یا response ok
بایت پنجم: 0xe9 نشانگر kb1
بایت ششم: 0x8f نشانگر kb2
شروع کُند
نحوه ارسال دیتا در شروع کند یا Slowinit در k Line بهصورت زیر است:
به مدت 300 میلی ثانیه Tx را یک کنید.
از طریق پورت سریال (Tx) و سرعت بسیار پایین 5 بادریت، بایت 0x33 را ارسال نمایید.
بهتر است بایت 0x33 را بدون استفاده از توابع کتابخانهای و به صورت دستی (صفر و یکی) را ارسال کنید، پس به شکل زیر عمل کنید:
بادریت 5، یعنی در هر ثانیه 5 بیت ارسال شود، پس هر بیت در 200 میلی ثانیه ارسال میشود. در ارتباط سریال، ابتدا بیت با ارزش کمتر ارسال میشود. همچنین در ارتباط سریال، شما یک استارت بیت، دیتا، بیت پریتی (در صورت لزوم) و یک بیت پایان ارسال میکنید. بنابراین:
ابتدا یک استارت بیت (Start Bit) با سطح منطقی 0 و به مدت 200 میلی ثانیه ارسال کنید.
سپس 0x33 را از کم ارزشترین بیت شروع به ارسال کنید. (0x33 = 0b00110011)
در انتها یک بیت پایان (Stop Bit) با سطح منطقی 1 و به مدت 200 میلی ثانیه ارسال کنید.
startbit: 200ms low databit0,1: 400ms high databit2,3: 400ms low databit4,5: 400ms high databit6,7: 400ms low stopbit+pause: 250ms high
حال، همانند شروع سریع، پورت سریال خود را پیکر بندی کرده و مابقی مراحل را انجام دهید. برخی خودروها از شروع سریع پشتیبانی نمیکنند، ولی همگی شروع کند را پشتیبانی میکنند. پس بهتر است همیشه از شروع کند استفاده کنید. پس از شروع اولیه، هیچ تفاوتی در دیگر مراحل وجود ندارد.
قالب بندی داده ها در K-Line
packet یا قالب دادهها برای ارسال به ECU از طریق پروتکل K-Line به شرح زیر است:
header: [0xc0+cmdlen] [destination=0x33] [source=0xf1] data: [cmd0] [cmd1] … [cmd(cmdlen-1)] checksum: [sum(header)+sum(data)]
cmd0 = service ID
cmd1 = PID
قالب دریافت دادهها از ECU (در صورتی که ارتباط موفقیت آمیز باشد):
header: [80+datalen] [destination=f1] [source=01] data: [40+cmd0] [cmd1] … [cmd(cmdlen-1)] [result0] [result1] … [result(datalen-cmdlen-1)] checksum: [sum(header)+sum(data)]
قالب دریافت داده ها از ECU (در صورتی که ارتباط با شکست مواجه شود) :
Received response packet on failure:
header: [80+datalen] [destination=f1] [source=01] data: [errorcode=7f] [cmd0] [Response Failure Code, see below] checksum: [sum(header)+sum(data)]
در اطلاعاتی که شامل چند بایت هستند، بایت های پر ارزش ابتدا ارسال می شوند. (دقت کنید: بایت، نه بیت!)
استفاده از شبیه ساز OBD2
قبل از اینکه به جان خودرو خود بیفتید و آزمایشهایتان را روی ECU بیچاره آن انجام دهید، بهتر است از یک شبیه ساز برای آزمایشات خود استفاده کنید تا به خودرو آسیبی نرسانید! به یاد داشته باشید آسیب زدن به ECU ممکن است برای شما خیلی گران تمام شود!! شبیه سازها در واقع یک درگاه DLC در اختیار شما قرار میدهند تا شما بتوانید همانند یک خودروی واقعی از طریق رابط OBD2 به آن متصل شوید. برخی از این شبیه سازها تنها برای یک پروتکل طراحی شدهاند، در حالی که برخی دیگر توانایی شبیه سازی چند پروتکل را دارند. شبیه سازهای زیادی وجود دارد. ما سعی میکنیم تعدادی از آنها معرفی کنیم.
شبیه ساز ECUsim 2000
این شبیه ساز ECU توسط شرکت ScanTool طراحی و ساخته شده است.
برای شروع کار با استفاده از این شبیه ساز، باید کارهای زیر را انجام دهید:
1- یک کابل USB را به شبیه ساز و رایانه وصل کنید. درایورهای لازم را نصب کنید.
2- کابل OBD-II را به شبیه ساز وصل کنید.
3- شبیه ساز خود را از منبع تغذیه 12 ولت قطع کنید.
4- شبیه ساز را بهوسیله کابل RS232 به پورت سریال کامپیوتر متصل کنید و در پنجره سریال تنظیمات را برروی (115200 bps, 8 bits, N, 1 stop) قرار بدهید.
5- شبیه ساز را در پروتکل مورد نظر برای آزمایش پیکربندی کنید.
6- به دستگاه ECU خود متصل شوید ( میتوانید از OBD-II board, CAN-Bus Shield, Raspberry Pi و… هم استفاده کنید.).
حالا ما یک ECU شبیه سازی شده داریم که به کامپیوتر متصل است.
دفترچه راهنمای برنامه نویسان که همراه با این محصول است، شامل کلیه دستوراتی است که میتوانید برای شبیه ساز استفاده کنید.
به عنوان مثال، اگر بخواهیم تعیین کنیم که شبیه ساز ما در حال حاضر برروی کدام پروتکل تنظیم شده است، از دستور SPI استفاده میکنیم. کافیست همانند تصویر زیر، در محیط ترمینال دستور را وارد کنیم:
این نشان میدهد که این شبیه ساز در حال حاضر بر روی پروتکل ISO 15765-4 یا همان CAN تنظیم شده است و با یک نوع شناسه 11 بیتی و با سرعت 500 کیلوبیت در ثانیه در حال کار است.
حالا فرض کنید میخواهید به دستگاه دیاگی که به وسیله رابط OBD-II به دستگاه متصل است، پیامی را ارسال کنید. در این حالت فرم دستوری به شکل زیر است:
SOMT <header>, <data>
به عنوان مثال، میخواهیم برای دیاگ فشار سوخت موتور 100kPa را ارسال کنیم. ما باید عبارت SOMT را به همراه شناسه پارامتر (PID) فشار سوخت که 0A است و مقدار هگز عدد 100 که 64 است، ارسال کنیم:
somt 0a, 64
دقت داشته باشید که اگر ارتباط بین دیاگ و شبیه ساز، از طریق کابل DLC محکم نکنید، ممکن است با پیام CAN ERROR مواجه شوید.
شبیه ساز OBD2 نرم افزاری
سورس های زیادی در اینترنت موجود هستند که شما به وسیله آنها میتوانید OBD2 را شبیه سازی کنید. به عنوان مثال، برای شبیه سازی CAN در آردوینو، سورس پروژه ECU CAN BUS SIMULATOR در گیت هاب و شبیه ساز K-Line بر روی آردوینو نیز وجود دارد. همچنین اگر در اینترنت جستجو کنید، نمونههای زیاد دیگری را نیز خواهید یافت. اما هر کدام از این شبیه سازها ممکن است ایرادات خاص خود را داشته باشد و نمیتوان روی آنها به عنوان یک تقلید کننده واقعی تکیه کرد. در واقع اکثر آنها به جای امولاتور (تقلیدکننده)، سمیلاتور (شبیه ساز) هستند.
در قسمتهای بعدی این مقاله قصد داریم تا با ساخت مدارهایی واسط، از طریق میکرو کنترلر به برخی از پروتکلهای OBD2 بهصورت مستقیم یا غیر مستقیم متصل شویم و اطلاعاتی را از ECU خودرو بخوانیم. امیدوارم این آموزش برای شما مفید بوده باشد.
منابع