Home >OBDii
何が出来るか
・故障診断コネクタにポン付けで燃費計が動作可能
・車両の故障コードが表示できる(故障箇所の特定とかメ ンテにいいかも)
・吸気温度、水温、バッテリー電圧、スロットル開度がわかる
・間違って点灯させたエンジンエラーを消去できる
・インプレッサなんかはOpenECUでロム書き換えなんてことができます。
・PCで長時間ロギング
※CAN通信とか日産の通信では高速にデータが収集できますが、ISO(K,Lライン使用)では1項目サンプリン グに100MS程度必要ですので、高速という程ではありません。このためRBオデッセイでは吸気温度、水温 、バッテリー電圧、スロットル開度はODBでデータを取り込み、その他はECUから直接電圧データを取り込 むのが理想という結論になりました。
最近はやりの故障診断コネクタにポンつけが売りの商品はこの特性を理解しないと、ガッカリなんてことに なってしまいます。ご自身の車がCAN通信対応なら、リアルタイムに変化するのが体感できるかもしれませ ん。ホンダではオデッセイRBの後からCANに移行しているみたいです。
・エンジンクーラント(水温)監視で余計な暖機運転も必要なし!!結構便利です。
資料はどこで手に入るか(これが一番の問題)
ネットにはなぜか日本語OBDの関連ページはなかなか見つけられません。
ELM327
PICを使用したOBD
OBD関連記事(PDFは有料)
ALLPRO
LINとは(富士通) ECUとのレベル変換IC
ODB ISO1941-2のネゴシエーションとC++ソース
ODB2のイニシャライズ方法
LINの製作記事(日本)
車載ネットワーク
日産車両はここ
ヨーロッパでは結構メジャーなんですけど。最近の車両はCAN通信ですが、ISO1941-2(K-LINE,L-LINE)を使用した り、難しいのもあるんでしょうか。特に最近は各社から故障診断コネクタを利用した燃費計とか出ているみたいです。
有名なのはCANP2、ピボットの製品かな。
製作してみる
(1)PICと
ELM327 を組み合わせて作成する。
(2)PIC単独で作成する
(3)
ELM327 にPC側からRS232Cにてコマンドを送信する
ここで問題となるのが、ECUとの通信でプロトコル変換(英語を日本語に翻訳するみたいな感じ)が問題になるみた
いですので、一番簡単なELM327にプロトコル変換を任せてPIC側はコマンドを送信する方法で実験してみましょう。
では、プロジェクト手始めに(1)の方法で作成してみます。
部品の入手
ELM327はELM Electronics社で入手します。 (カナダ)
OBDのコネクタはここで入手します。
ガレージ インテーク (北海道 富良野)
回路図はELM Electronics社の
ELM327リファレンスの回路 を使用します
PICに使用する
Cソースはここ 。
ホームページはここ
その他の部品は秋月電子で手に入ります。
リファレンスの回路はこのようになってるみたいです。
※オデッセイはISOでのインターフェースなのでCANとJ1962は使用しません。
※今回のプロジェクトはCAN,J1962プロトコルは使用しません。実験車両がないのであしからず。
※トランジスタは2SC1815で代用かな??
上記の回路RS232C部分の回路はADM3202に変更します。
Q6,Q7は2SC1815で動作します。
MCP2551は
ELM Electronics社で手に入ります
+5Vは秋月電子の3端子レギュレータで代用します
LoggingSystemとはDSUB9Pinケーブルで接続する仕様とします。(クロス接続です。pcはストレート)
回路を見ると、車両側ISO,J1962プロトコルはオープンコレクタみたいです。(スイッチみたいなもん)
信号にはバッテリ電圧がかかるので、しっかり作らないと、ECU、パソコンを最悪壊します!!
下記の図は最近の車両に使われるJ1962故障診断コネクタです
今回のプロジェクトではRBオデッセイを対象とするため(ISOですので)下記の端子から信号を取ります。
プログラムを考えてみる.
PICに使用する
サンプルCソース(www.blafusel.de ) を使用すると簡単に実現できるみたいです。
記述はドイツ語で、AVR用ですが、PICに転用は簡単と思います
ELM237チップはATコマンドと言うものを採用してると、英文には書いてあります。
う〜ん昔のモデム制御みたいなことをするみたいですね(笑)
初期化処理はこれだけです
void elm327_init()
{
long timeout;
puts ("\n\r");
delay_ms (1000);
puts ("AT Z");
timeout=0;
while(!kbhit()&&(++timeout<50000)) // 1/2 second
delay_us(26);
if(kbhit() )
{
}
else
{
return -1;
}
delay_ms (1000);
puts ("AT E0\r");
delay_ms (1000);
puts ("AT L0\r");
while (getch() != '>');
puts ("01 00\r");
elm327_get ();
}
このように使います
printf(lcd_data, "LINC START");
elm327_init();
for (i=1; i <= 128; i++)
{
if(elm_value==-1)
elm327_init();
}
if(pid_value!=-1)
{
//ledとブザー
}
void elm327_get ()
{
char RS232C;
int j=0;
ei=0;
do
{
RS232C = getc();
if (RS232C != 13 && RS232C != '>')
{
values[ei]=RS232C;
ei=ei+1;
}
} while (RS232C != '>');
values[ei]='\0';
elm_value=ei;
if (values[ei-4]=='D' && values[ei-3]=='A' &&
values[ei-2]=='T' && values[ei-1]=='A')
{
printf(lcd_data, "No Data");
elm_value=-1;
}
else if (values[ei-5]=='E' && values[ei-4]=='R' &&
values[ei-3]=='R' && values[ei-2]=='O' && values[ei-1]=='R')
{
printf(lcd_data, "Bus-Init ERROR");
elm_value=-1;
}
else if (values[ei-7]=='S'&&values[ei-6]=='T'&&values[ei-5]=='O'&&values[ei-4]=='P')
{
printf(lcd_data, "Bus-STOPED");
elm_value=-1;
}
else
elm_value=0;
values[ei-1]='\0';//文字列終了判定のためnull挿入
}
データの取得
picの設定
#include <18f8720.h>
#fuses H4,NOWDT,NOPROTECT,PUT,BROWNOUT,NOLVP
#device ADC=10//A/D変換10ビットモード
#USE DELAY(CLOCK=40MHZ, CRYSTAL=10MHZ)
#use RS232(BAUD=38400, XMIT=PIN_C6,RCV=PIN_C7,parity=N,bits=8,ERRORS)
#use fast_io(c)
#include <stdlib.h>
#include <string.h>
・
・
・
・
・
・
・
割り込み
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_割り込み_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_
//rs232c
#INT_RDA //RS232 receive data available
void rs_receive()
{
/*
ハードウェアUART を使う場合
は1bit 分のパルス幅の10 倍まで設定することが可能です(9600 ボーで1000μs)。
1000*1000/9600*10=1041
1000*1000/38400*10=260
*/
char rscara;
while(kbhit() == 0) //RXピンがLowになるまでLOOP
{
}
delay_us(60);
rscara = getc();
if (rscara != 13 && rscara != '>')
{
values[rs_i]=rscara;
rs_i++;
}
if (rscara == '>')
{
rs_complete=0;
values[rs_i]='\0';
if (values[rs_i-4]=='D' && values[rs_i-3]=='A' &&
values[rs_i-2]=='T' && values[rs_i-1]=='A')
{
pid_value=-1;
}
else if (values[rs_i-5]=='E' && values[rs_i-4]=='R'
&& values[rs_i-3]=='R' && values[rs_i-2]=='O' &&
values[rs_i-1]=='R')
{
pid_value=-1;
}
else if (values[rs_i-7]=='S'&&values[rs_i-6]=='T'&&values[rs_i-5]=='O'&&values[rs_i-4]=='P')
{
pid_value=-1;
}
else
{
pid_value=0;
}
values[rs_i-1]='\0';//文字列終了判定のためnull挿入
if(pid_value==0)
{
res_i=5; //ELMから帰ってくる = "41 05 xx xx"の"xx"を16進数に変換
es_cnt=0;
while (values[res_i] != '\0')
{
res_i++;
res_dummy[0]=values[res_i];
res_dummy[1]=values[res_i+1];
res_dummy[2]='\0';
rsdata=strtol(res_dummy,&res_ptr,16);//2文字を基底16で16進数に変換
res_value_mem[res_cnt]=rsdata;
res_cnt++;
res_i += 2;
}
if (res_cnt == 1) // 1 Byte OR 2Byteの計算
value=res_value_mem[0];
else
value= res_value_mem[0]*256+res_value_mem[1];
}
else
{
value=0;
}
rs_complete=1;
}
}
データの読み出し
if(obd_f==0)
{
delay_ms(20);
puts ("0105");
obd_f=1;
}
if(rs_complete==1&&obd_f==1)
{
if(position[8]==2)
lcd_pos(8,2);
if(position[8]==3)
lcd_pos(8,3);
if(pid_value==0)
printf(lcd_data,"Eg%3lu ",value-40);//エンジンクーラントの温度
rs_i=0;
rs_complete=0;
obd_f=0;
}
フリーズフレーム・故障コードの読み出し
printf(lcd_data, "-----Now Check----"); //表示
elm327_init();
for (i=1; i <= 128; i++)
{
if(pid_value==-1)
elm327_init();
}
puts ("0101");
elm327_get ();
//故障コードのデータ数取得
if(value!=-1)
{
DTC_number = response_DTCNumber(mem);
if(DTC_number>0&&DTC_number<4)
{
lcd_pos(0,1);
printf(lcd_data, "DTC:%dData",DTC_number); //表ヲ
puts ("03");
lcd_pos(0,2);
elm327_get ();
for (i=1; i <= DTC_number; i++)
{
DTC_code = response_DTCcode(mem,i);
printf(lcd_data, "%lx",DTC_code);
}
}
}
//freez flame
puts ("02 02 00");
elm327_get ();
if(pid_value!=-1)
{
DTC_code = response_FR_Ccode(mem);
lcd_pos(0,3);
printf(lcd_data, "Fleez:P%lx",DTC_code); //
}
・
・
・
・
・
・
・
////////////////////////////////////////////////////////////////////////////////////
#separate
int response_DTCNumber (int *value_mem)
{
int i=5; //ELMから帰ってくる = "41 05 xx xx"の"xx"を16進数に変換
int cnt=1;
int rsdata;
char dummy[4];
char *ptr;
i++;
dummy[0]=values[6];
dummy[1]=values[7];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[0]=rsdata;
return 1;
}
#separate
long response_DTCcode (int *value_mem,int number)
{
/*43 01 33 00 00 00 00
上記の返信データ「43」は、モード03リクエストに対する返信であることを示します。
その他の6バイトについてはトラブルコードを示すレスポンスの中にペアでコードを読まなければなりません
(上記のは0133、0000および0000として解釈します)。
*/
int i=5; //ELMから帰ってくる = "41 xx xx"の"xx"を16進数に変換
int cnt=1;
int rsdata;
char dummy[4];
char *ptr;
i++;
if(number==0)
return;
if(number==1)
{
dummy[0]='0';
dummy[1]=values[3];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
}
if(number==2)
{
dummy[0]='0';
dummy[1]=values[9];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
}
if(number==3)
{
dummy[0]='0';
dummy[1]=values[15];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
}
if(rsdata==0)
printf(lcd_data, "P0");
else if(rsdata==1)
printf(lcd_data, "P1");
else if(rsdata==2)
printf(lcd_data, "P2");
else if(rsdata==3)
printf(lcd_data, "P3");
else if(rsdata==4)
printf(lcd_data, "C0");
else if(rsdata==5)
printf(lcd_data, "C1");
else if(rsdata==6)
printf(lcd_data, "C2");
else if(rsdata==7)
printf(lcd_data, "C3");
else if(rsdata==8)
printf(lcd_data, "B0");
else if(rsdata==9)
printf(lcd_data, "B1");
else if(rsdata==10)
printf(lcd_data, "B2");
else if(rsdata==11)
printf(lcd_data, "B3");
else if(rsdata==12)
printf(lcd_data, "U0");
else if(rsdata==13)
printf(lcd_data, "U1");
else if(rsdata==14)
printf(lcd_data, "U2");
else if(rsdata==15)
printf(lcd_data, "U3");
if(number==1)
{
dummy[0]='0';//values[3];
dummy[1]=values[4];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[0]=rsdata;
dummy[0]=values[6];
dummy[1]=values[7];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[1]=rsdata;
}
if(number==2)
{
dummy[0]='0';//values[3];
dummy[1]=values[10];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[0]=rsdata;
dummy[0]=values[12];
dummy[1]=values[13];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[1]=rsdata;
}
if(number==3)
{
dummy[0]='0';//values[3];
dummy[1]=values[15];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[0]=rsdata;
dummy[0]=values[17];
dummy[1]=values[18];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[1]=rsdata;
}
return value_mem[0]*256+value_mem[1];
}
#separate
long response_FR_Ccode (int *value_mem)
{
/*43 01 33 00 00 00 00
上記の「43」は、モード03リクエストに対する反応であることを示します。
(コードは0133、0000および0000として分離します)。
*/
int i=5; //ELMから帰ってくる = "41 xx xx"の"xx"を16進数に変換
int cnt=1;
int rsdata;
char dummy[4];
char *ptr;
i++;
dummy[0]=values[3];
dummy[1]=values[4];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[0]=rsdata;
dummy[0]=values[6];
dummy[1]=values[7];
dummy[2]='\0';
rsdata=strtol(dummy,&ptr,16);//2文字を基底16で16進数に変換
value_mem[1]=rsdata;
return value_mem[0]*256+value_mem[1];
}
燃費を求める.
ECUがMAFを取得出来ることが必要です。オデッセイは表示出来ませんでした。
基本的には以下の式で算出出来ます。
MAFはPID0110で取得できます。
取得したデータXに0.01を掛けるとMAFになりますので
MIL/gallon = (14.7 * 6.17 * 4.54 * VSS * 0.621371) / (3600 * MAF /
100)
= 710.7 * VSS / MAF
で燃費になります。
14.7 grams of air to 1 gram of gasoline - ideal air/fuel ratio
6.17 pounds per gallon - density of gasoline
4.54 grams per pound - conversion
VSS - vehicle speed in kilometers per hour
0.621371 miles per hour/kilometers per hour - conversion
3600 seconds per hour - conversion
MAF - mass air flow rate in 100 grams per second
100 - to correct MAF to give grams per second
注意すること
割り込みを使用している場合、ISOプロトコルは
0.5秒毎のデータ取得が限界 です(余裕代を見積もって)そもそもオ ープンコレクタによる信号のやりとりですので(ELM<->ECU)通信速度の高速化は望めません(10400BPS)
ということは、燃料噴射量の推定がかなり大雑把になるので、補完推定となるかもしれません。インジェクタからダイ レクトに信号を拾ったほうが、正確にかつ簡単という結論になるかも・・・・・・(CAN通信対応ECUなら高速通信が可能 なので正確に算出できると思います)
テレビを見るとき人間の目は1秒に30コマが自然に見えるようになってます。ワンセグ携帯がコマ送りに見えるのは 15コマで描画しているからです。ISOプロトコルを使用した場合(割り込み処理多用した場合)1秒に2コマしかデータ 更新が出来ないことになります。補完処理をして1秒に30コマは可能ですが、積算などの演算には誤差が累積され てしまいます。
さらに悪いことに割り込みを使用している場合、RS232Cの
受信エラー判定が必須 です。かなりエラーが頻発します 。 これで10日くらいハマりました・・・・・
RS232Cのエラー対策設定は以下のようにします。
UARTの設定は
#use RS232(BAUD=38400, XMIT=PIN_C6,RCV=PIN_C7,parity=N,bits=8,
ERRORS )
とします。エラーリセットの
ERRORSは必須 です
ELM327の主要コマンド(ELM327ドキュメントの翻訳)
※
PIDの意味はここを参照
AT コマンド要約(翻訳)
1.主要な Commands
<CR>
最後のコマンドを繰り返し
BRD hh
通信速度を除数hhにて試す
BRT hh
通信速度Timeoutを設定
D
全ての設定をデフォルトにする
E0, E1
Echo Offもしくは Onに設定0がオフ 1がオン
I
バージョンIDをRS232Cに出力
L0, L1
ラインフィード Off, On
※ラインフィードとはカーソルを次の行に送ること。ELMとの対話はDOS画面のように返事がコンピュータから
返ってくるイメージのため
M0, M1
Memory Off, or On
WS
ウォームリセット(ソフトウェア)
Z
オールリセット
@1
機器説明を表示
@2
機器識別子を表示
@3 cccccccccccc
機器識別子を書き込み
2.プログラム化可能なパラメータコマンド
PP xx
OFF disable プログラム Parameter xx
PP FF OFF
all プログラム Parameters Off
PP xx ON
enable Prog Parameter xx
PP FF ON
all プログラム Parameters On
PP xx SV yy
for PP xx, Set the Value to yy
PPS
PPの要約表示
3.Voltage Reading Commands
CV dddd
電圧読み値をdd.ddとしてキャリブレート設定
4.ATコマンド要約
OBD コマンド
AL
変更メッセージ数 (>7 byte) 通常メッセージ
通常メッセージ7バイト以上にする
AR
自動受信
AT0, 1, 2
適応性のあるタイミング, Auto1*, Auto2に変更
※詳細参照
BD
バッファー・ダンプを行ないます。
BI
イニシャライズシーケンスを行わない
DP
現在のプロトコルについて記述。
DPN
現在のプロトコルについて数値で記述。
H0, H1
ヘッダー Off*, or On
MA
全てモニターする
MR hh
hh受信をモニター
MT hh
hh送信をモニター
NL
通常の長さバイトのメッセージに変更*
PC
プロトコルクローズ
R0, R1
レスポンス Off, or On*
RA hh
hhに受信アドレスをセット
S0, S1
スペース表示 Off, or On*
SH xyz
xyzにヘッダーをセット
SH xxyyzz
xxyyzzにヘッダーをセット
SP h
hにプロトコルをセットし保存
SP Ah
hに自動プロトコル設定し保存
SR hh
hhへ受信アドレスセット
ST hh
hh x 4 msecにタイムアウトせっと
TP h
hにプロトコルを試行
TP Ah
hに自動プロトコル設定サーチ
5.ISO 専用コマンド (protocols 3 to 5)
IB 10
Set the ISOボーレート 10400*にセット
IB 96
ISO ボーレート 9600セット
IIA hh
hhへイニシャライズアドレスを変更。ISOプロトコルにセット(5BPS含む)
KW
キーワードを表示
KW0, KW1
キーワードチェック Off, or On*
SW hh
ウェークアップインターバルをhh x 20 msecにセット
WM [1 - 6 bytes]
ウェークアップメッセージをセット Wakeup Message
AL [ Allow Long messages ]
以下は、 ELM327がサポートする現在のバージョンコマンド です。それぞれについて説明します。
標準のOBDIIプロトコルはメッセージのデータバイト数を7に限定しています。このコマンドによってELM327は、データバイトを7バイト以上にします(両方の送受信のために)。
もしALを選択するならば、ELM327は、長い間データ送信(8データバイト)し、データを
受け取るのを許容します(無限です)。
デフォルトはオフのALです(NLが選ばれています)。
AR [ 受信アドレス自動セット ]
もしその内部で設定された受信アドレスが、アドレスと一致し、メッセージが送信されているならば、車両ECUからの反応はELM327により認識されて、表示されます。
オート受信モードによって実際には、受信アドレスのために使われた値は、現在のヘッダーバイトに基づいて選ばれて、ヘッダーバイトが変更される時には、いつでも自動的にアップデートされます。
受信アドレスのために使われる値は、最初のヘッダーバイトの内容およびメッセージが、物質的なアドレス、機能的なアドレッシングを使うか、または、ユーザーが値をSRまたはRAコマンドに設定した内容に基づいて決定されます。
オート受信はデフォルトでつけられて、J1939フォーマットには使用しません。
AT0、AT1、およびAT2
[順応的なタイミングのコントロール]
車両から反応を受け取る時、ELM327は、[AT ST hh]により、規定された時間を待機するために設定します。
ICが多種多様な車両で動作することを保証するために、デフォルト値は遅い時間に設定しています。
通常イミングのコントロールは調整可能でしたが、多くの人々が、よりよい値を決定するための試験設備もしくは経験を持っていませんでした。
順応的なタイミング調整は、自動的に、あなたの車両のECUの実際のレスポンスに基づく値に基づきタイムアウト値をセットします。
データバスをロードするような条件が変わっても、ELM内部アルゴリズムは学習し、適切な調節を行います。
通常使用するELM327タイミングのコントロールを、最大とする場合[AT ST hh]を使い、現在の設定より長いものを選ばないことに注意してください。
使用に利用可能な3つのタイミング・セッティングがあります。
デフォルトは、適応性のあるタイミング・オプション1(AT1)、推奨されたセッティングです。
AT2がAT1(結果は非常に遅い接続のため注目してしまいます。より速いOBDシステムを備えた違いを見てはなりません。)よりagressiveなバージョンである間、AT0は適応性のあるタイミング(通常使用)を使用不能にするために使用されます。
BD[OBDバッファー・ダンプを実行する]
ELM327によって送られ受け取られたメッセージはすべて、OBDバッファーと呼ばれる1セットの12のメモリ記憶ロケーションに一時的に格納されます。
なぜイニシャライズが失敗したか確かめるには、最後のメッセージでヘッダー・バイトを見るか、あるいはOBDメッセージの構造を学習するためにこのバッファーの内容を時々見ることは役に立つかもしれません。
「ダンプ結果出力」(印刷)によって、このバッファーの内容をいつでも問い合わせることができます。
あなたがBD[OBDバッファー・ダンプを実行する]を行う場合、ELM327は、12のOBDバッファー位置すべての内容が後続する長さバイト(バッファーの中でメッセージの長さを表わして)を送ります。
それらがOBDバッファーに入っても入らなくても、長さバイトは受け取られたバイトの実数を表わします。
数として、長いデータ流れ(AT ALを備えた)を正確に見ることが、受け取られたバイトの数を表わす場合、これは有用かもしれません、モダンな256.
受け取られた最初の12バイトだけがバッファーに格納されることに注意してください。
BI[初期化シーケンスを回避する]
このコマンドは注意して使用してください。
それは、OBDプロトコルがどんな種類のイニシャライズも要求せず、なおかつ、ハンドシェークせずにアクティブになることを可能にします。
イニシャライズプロセスはプロトコルを有効にするために通常使用されます。また、それなしで、ハンドシェークは、予想することが困難かもしれません。
BIは規定通りのOBD使用のために使用してはならないし、ECUシミュレータおよびトレーニングの構築をするために単に提供しているだけです。
BRD hh[試行ボーレート÷hh]
このコマンドは、RS232ボーレート除数を、hhにより提供されたHEX形式の値に変更するために用いられます。
実際のボーレート(kbpsの中の)はこの除数で割られて、4000でしょう。
例えば、115.2kbpsのセッティングは、4000/115.2または35の除数を要求するでしょう。
16進表記では、35が23として書かれています。したがって、送られる必要のある実際のコマンドはAT BRD 23でしょう。
ELM327が、いくつかのインタフェースがサポートできるよりずっと高いレートで動作することができるかもしれないので、動作することを決定する前に、BRDコマンドは、要求されたレートがテストすることを可能にします(もし問題があるならば前のボーレートにオートマチックで落とします)。
使用すると、ボーレートを変更するリクエストおよびELM327が「OK」で答えるとともに、コマンドは送られます。
それ後に、内部タイマーは、コントロールコンピュータに、それらのボーレートと同じレートに変更することについて十分な時間があることを保証するために待ちはじめます。
その後、ELM327は新しいボーレートでpoweronメッセージを送り、何が受け取られたかコントロールするコンピューターが評価している一方、待ち始めます。
私がメッセージとして送るATがエラーなしで受け取られた場合、コントロールするコンピューターは送信回路類をテストするためにキャリッジリターン文字を送ります。
もしELM327によってコマンドが正確に受け取られれば、新しい通信レートが保持されます。
しかしながら、万一コントロールするコンピューターがエラーとして見た場合、ECU1はレスポンスを送りません、ELM327は、AT
BRTによってセットされた時間待ちます、またレスポンスが検知されない場合、前のボーレートに戻ります。
「より高いRS232ボーレートを使用すること」を記載したセクションの48および49ページの中に詳細な説明があります。
最初にデフォルト(AT D)をセットした場合、要求をキャンセルします。この方法で設定された新しいボーレートもおよびウォームスタート(AT
WS)では保持されますが、ハードウェアリセット(a power off/on or a call to
AT Z)では保持しません。
あなたが、コード中のAT Zを呼ぶ習慣にしていたとしたら、AT WSを代わりに使用することを推奨します。
BRT hh[hhはボーレート・タイムアウトセット値]
このコマンドは、ボーレートを変える場合、ハンドシェーク(つまりAT BRD)までのタイムアウトを許可します。
hhが16進法の値である場合、タイムアウトはhh x5.0ミリセカンドで与えられます。
このセッティングに対するデフォルト価値は75ミリセカンドの0Fです。
00の値が0ミリセカンドにならないことに注意してください。00は最大の時間256
x5.0ミリセカンド、あるいは1.28秒を供給します。
CV dddd[測定電圧dd.ddボルトへ内部計数を変更する]
ELM327がAT RVリクエストによる電圧を計測する場合、このコマンドでキャリブレーションすることができます。
アーギュメント(「dddd」)は、小数点(小数位が第2と第3の数字の間にあると仮定します)を、4つの数字として必ずしも提供されるとは限りませんので注意して下さい。
この機能を使用するには、実際の入力電圧を読み、次に、正確な電圧メーターを使用し実際の電圧と内部測定(スケーリング)係数を変更するCVコマンドを使用して調整してください。
例えば、11.99ボルトの実際の電圧がある場合、ELM327が12.2Vとして電圧を示しているなら、CV
1199をコマンドで送ってください。ELM327はその電圧で自身を再設定します(実際は四捨五入のため12.0Vと読みます)。
電圧を測定を実行する方法についての詳細は、22ページを参照してください。
D[デフォルトにすべてセット]
最初に電源パワーが供給される時には、このコマンドによって、オプションをデフォルト(工場)設定にセットするために用いられます。
以前に保存したプロトコルは、メモリーから戻され、現在の設定になります(アクティブな他のプロトコルを閉じます)。
カスタム・ヘッダー、フィルタあるいはマスクのためにユーザが作った全てのセッティングも、デフォルト値に戻されるます。また、タイマー・セッティングもすべてデフォルトに戻されます。
DP[現在のプロトコルについて記述する]
ELM327は、接続される車両ごとに適切なOBDプロトコルを自動的に決定することができます。
しかしELM327ICを車両と接続する時、要求されたデータだけを戻し、見つけられたプロトコルを報告しません。
DPコマンドはELM327が(それが接続されなくても)選んだ、現在のプロトコルを表示するために使用されます。
自動オプションを選択されている場合、プロトコル表示はタイプされたコマンドの後に続けて「AUTO」を示します。
プロトコルセットコマンドにより使われた数値ではなく実際のプロトコル名が表示されることに注意してください。
DPN[別表に記載の数値によってプロトコルを指定記述する]
このコマンドはDPコマンドに似ていますが、現在のプロトコルを表わす数を返すことに注意して下さい。
自動的な探索機能が有効な場合、文字 A が数値の前に付きます。
数値は、セット・プロトコルおよびテストプロトコル・コマンドと共に使用されるのと同じ数値です。
E0 and E1 [ Echo off (0) or on (1) ]
RS232ポートにおいて文字が受け取ったかどうかにかかわらずこれらのコマンドはホスト・コンピュータにエコーコントロールします
、 。文字エコーはELM327に送られた文字が正確に受け取られたことを確認するために使用することができます。
デフォルトはE1(Echo on)です。
FC SM h [ Set Mode h へフローコントロール]
このコマンドは、自動的なフロー制御反応が可能な時にどのようにELM327が1番目フレームメッセージに反応するかを設定します。
提供される1桁は完全に自動レスポンス用の「0」(デフォルト)です。あるいは、ユーザのための「1」はレスポンスを定義します。ユーザのための「2」はレスポンスにデータ・バイトを定義します。
より多くの詳細例は、フローコントロールメッセージ・セクション(40ページ)で見つけることができます。
I [ 自身の識別 ]
このコマンドにより、チップはバージョンIDストリング(現在はELM327 v1.3)の表示を行います。
あなたが作成するソフトウェアは、ICをリセットする必要なしに、どのようなバージョンの集積回路とコミュニケートしているか正確に決めるため使用することができます。
IB 10 [ISO 用Baud rate 10400 にセット]
このコマンドはISO 9141-2およびISO 14230-4デフォルト値10400にボーレートを戻します。
IB 96 [ ISO 用Baud rate 9600 にセット ]
数人のユーザがこのコマンドを要求しました。
それは9141-2でISOのために使われるボーレートとISO 14230-4プロトコル(番号3、4と5)を9600ボーに変えるのに用いられます、その一方で、開始バイト移動の必要条件のいくらかを緩和させます。
IIA hh[hhにISO initアドレスをセットする]
ISO 9141-2およびISO 14230-4基準は、1ECUでセッションを始める場合特定のアドレス($33)に開始シーケンスが向けられることになっていると記述されてます。
もし遅い5ボーシーケンスを別のアドレスに向けて実験に使用するならば、このコマンドによって実現されます。
たとえば、あなたが開始がアドレス$7AでECUで実行されるのを望むならば、単にこのコマンドを送ってください:
例 >AT IIA 7A
また、そうするために(プロトコル3あるいは4)呼ばれた時、ELM327はそのアドレスを使用するでしょう。
提供された通りに、十分な8ビットの価値は正確に使用されます。変更はそれ(パリティー・ビットなどのつまり、加えないこと)に行なわれません、この値のセットがヘッダー・バイトで使用されるアドレス価値に影響しないことに注目します。
デフォルト(すなわちELM327)がリセットされる場合は常に、ISO initアドレスは33に復帰されます。
KWは[キーワードを表示します]
ISO9141-2とISO14230-4 protocolsareが初期設定される時、特別な2バイト(キーワード)はELM327に渡されます(値は、ELM327のため特定のプロトコルバリエーションがサポートできるかどうかを決定するために、内部で用いられます)。
もし見ることを望むならば、これらのバイト値であったものかを問わずAT Kwコマンドを単に送ってください。
以降まだ未訳
6.車両との会話方法
OBDの基準は、車両へ送られるリクエスト毎にセット・フォーマットであることを明示します。
第1のバイト(「モード」として知られている)は、常に要求されているデータのタイプについて記述します、一方、第2、第3のバイトは要求された(「パラメーター識別」あるいはPID番号によって与えられた)実際の情報を指定します。
これらのモードおよびPIDは、SAE J1979(すなわちISO 15031-5基準)のようなドキュメントに詳細に記述され、車両メーカーによって詳述されるているかもしれません。
通常は、J1979(より多くの準備があるが)によって記述された、9つの診断の試験モードに関係があります。
これらのモードのすべてはすべての車両に支援されるために要求されるとは限らず、多くの場合このモードがあるとは限りません。
以下に9モードを示します
01 ―現在のデータを示します。
02 ―フリーズデータを示します。
03 ―診断のトラブルコードを示します。
04 ―明瞭なトラブルコードおよび格納された値。
05 ―検査結果(酸素センサー)。
06 ―非連続的にモニターされた検査結果。
07 ―保持しているトラブルコードを示す
08 ―特別のコントロール・モード
09 ―車両情報のリクエスト
個々のモード内には、PID 00は、普通、どのPIDsがそのモードによってサポートされるかを示すために確保されます。
モード01、すべての乗り物はPID 00を支援しなければならず、以下のようにアクセスすることができます。
あなたのELM327インターフェースが車両に適切に接続され、動力が供給されることを確認してください。
ほとんどの車両はイングニッションキーON位置にしないと答えません、従って、イングニッションをオンに変えてください。エンジンは始動させません。
プロンプトでは、モード01 PID 00コマンドを出してください:
>01 00
ECUバスにはじめてアクセスした時、レスポンスの後に続けて、バス初期化メッセージを見ることができます。一般には以下のとおりかもしれません:
41 00 BE 1F B8 10
41は、モード01リクエスト(01+40の=41)からの応答を示します、一方、第2の番号((00))PID番号が要求を単に繰り返します。モード02、リクエストは42、43などを備えたモード03で答えられます。次の4バイト(BE、1F、B8および10)は、要求されたデータがあることを表わします、このモード(1=supported,
0=not)に支援されるPIDを示すビット・パタン。この情報は一時的ユーザにあまり役立ちませんが、それは接続が働いていることを証明します。
次の例は現在のエンジン冷却水温度(ECT)を要求します。これはモード01におけるPID
05で、以下のように要求することができます:
>01 05
車両からの反応はフォーマットを持っていて
41 05 7B
41 05は、これがPID 05のモード1要請に対する反応です。その一方で7Bが希望のデータであることを示します。16進法の7Bを10進に変換して、一つは7×16+11=123を得ます。これは、摂氏度ですのでサブゼロ温度のためにゼロオフセットで現在のエミュレートを表わします。実際の冷却水温度変換するためにに、値から40を引く必要があります。この場合、冷却水温度は123
-40で83°Cとなります。最終例は、エンジンrpmの要請を示します。これはPID
0Cのモード01です、したがって、迅速なタイプで:
>01 0C
典型的な反応は下記に示します
41 0C 1A F8
返された値(1A F8)は10進数に変換することが必要な2バイト値です。
10進数変換すると、6904の値を得ます。エンジンrpmは非常に高い値であるように見えます。
その理由はrpmが1/4rpmのインクリメントで送られているからです。
実際のエンジン回転速度に変換するために、6904 ÷ 4にする必要があります。
この場合、rpmは1726となります。
ELM327がリクエストを送る場合、ELM327ICがレスポンス(AT STコマンドでこのタイマーを調節することができます)を待つ時間を制限するタイマーをセットします。
レスポンスが設定時間得られない場合、NO DATAメッセージを表示します。また、レスポンスが受け取られる場合、上記のように、それが表示されるでしょう。
第1のレスポンスが受け取られ表示された後、タイマーはリセットされます。また、ELM327は、別のレスポンスが来るかどうか確かめるのを待ちます。しかしながら、何も到着しない場合、既に返されたデータがあったので、NO
DATAレスポンスを表示しないでしょう。そのようなタイムアウトにおいては、ICがプロンプトを表示し、PCからの次のコマンドを待つでしょう。
ELM327がそれもの長い間ほとんど二回とるかもしれないこのタイムアウトアプローチ手段は、その時まで、1つの一回の答えを得るために、注意への復帰を必要とします。
不運にも、これに関してこのICの初期のバージョンをやめることができるものはほとんどありませんでした。
あなたがどれだけのレスポンスを期待するべきか知っていれば、ELM327のバージョン1.3は情報の検索を促進する1つの方法を導入します。迅速な状態に直ちに返る前にどれだけのレスポンスを得るべきであるか今ELM327に伝えることができます。
例として、以前に議論されたエンジン温度リクエストのために1つのレスポンスだけが来ていることを知っていれば、今送ることができます:
>01 05 1
また、ELM327は単に1つのレスポンスを得た直後に返るでしょう。
それは、リクエストを送った後にまだ内部タイマーをセットします。しかし、それは1つのレスポンスを単に待ちます。それはタイマーをセットせず、別のレスポンス(それは相当な時間(可能になっている適応性のあるタイミングのないデフォルト時間は200ミリセカンドです)を節約してもよい)を待ちません。
あなたが提供する反応の数は、どんな一つの16進数(Fへの価値0の)でもありえます。
それは提供されることを要求されません(それをする古い方法は、すばらしいです - それは、ほんの少しより遅いです)。
AT R0セッティングがOBD要請を備えているどんな数でも越えることに注意すべきです。
あなたがECUが提供することができるより多くの反応を得ようとするならば、前にのように、ELM327は時外へそうします、そして、される不都合がありません。
最終的な例は車両シリアル番号の要請です。そして、それは来たるべきセクションで論じられます。PIDが02である間、シリアル番号のためのモードは09です。あなたが反応が長く5本の線であることであるということを知っているならば、時間は送ることによって節約されることができます:
>09 02 5
データ検索のこの新しい方法を使用する前に、必ずどれくらいの反応が質問に答えてあなたの車両で通常送られるかトラブルを学習してからにしてください。
他を無視して短い時間で要請するならば、結果車両データバスの渋滞を引き起こすかもしれません。
例えば、J1850 PWMプロトコルは、すべての反応が、『フレーム内反応』(IFR)として答えらることを必要とします。
このIFRが車両で受け取られないならば、それはデータ(しばしば)を送信しようとします。そして、結局IFRを受けることを要求します。あなたが1つの反応だけを求めるならば、しかし、車両は5を送ろうとしています、あなたは問題を引き起こすかもしれません。
明らかに、どれくらいの反応を予想するべきかについて経過を追う方法である必要があります、それから、この情報に基づく適当な要請をしてください。2、3のトラブルコードを得ようとしている人のために、貯金はトラブル(要請をする古い方法を使用することは、たぶん最も簡単です)の価値がありません、しかし、できるだけ速く車両情報を得ようとしているプログラマーのために、とられる時間はたぶん非常に価値があります。
我々は、あなたが車両についてたずねるこの方法を使用する方法について非常に慎重であるために、もう一つの警告をここで提示しなければなりません。
より速く、リクエストをすることから帰っているELM327の1つの直接的なメリットは、次のリクエストがそれからより速く始まることができるということです。
SAE J1979標準の初期のバージョンが、しかし、あらゆる100ミリ秒よりしばしば要請を送るのを禁ずることに注意してください、そして、走査ツールが猶予なく次の要請を送るのをついに許可されたのはAPR2002最新版だけででした。
更に、レスポンスがすべて受け取られたことが決意する場合、リクエストはすぐに単に送ることができます。
より古い乗り物に接続されれば、要求している古い方法を使用するべきです。
うまくいけば、これは典型的要請がどのようにELM327を使っているようにされるかについて示しました。
それはISO(http://www.iso.org/)、あるいはウェブ上の様々な他の出所からあなたの乗り物(SAE(http://www.sae.org/))のメーカーからこの情報が得させることができるモードおよびPID_上の決定的なガイドであるとはいうつもりではありませんでした。
DTCコードサーチ.
車両に発生している故障をコードとして検出します。
また故障発生からの時間を調べることも可能です。
表に示すのは故障診断コードDTCコードの体系です。
[ELM327マニュアル翻訳]
下記参考資料
出展:ELM Electronics
http://www.elmelectronics.com/
STEP1
最初に、どれくらいのトラブルコードが現在格納されるかについて調べます。以下の通りにモード01 PID 01を送信します
>01 01
ECUからデータが返されます
41 01 81 07 65 04
41 01は、リクエストに対する反応を示します。また、次のデータ・バイト(81)は現在のトラブルコードの数です。
車両が少しでも使用可能であるなら、81(16進法)または129の(BCD 10進数の)トラブルコードの送信はないでしょう。
このバイトは最上位ビットで、二つの役目をします。このバイトは、故障インジケータランプ(MIL、または、『Engine Lightをチェック』)があることを示し(1以上であるならば)
STEP2
MILがオンの場合に、格納されたコードの数を計算するためには、単に数から128(あるいは80のhex)を差し引きます。
例:81-80=1 1つの格納されたのトラブルコードがあることが分かります。
レスポンスの残りのバイトは、特にそのモジュールに支援されたテストタイプについての情報です(さらに詳しい情報に関してはSAEドキュメントJ1979を参照)。
この実例では、レスポンスに1つの格納されたデータがありました。しかし、もし他のモジュールに格納されたコードがあれば、それらは各々レスポンスのモジュールデータ提供をします。
どのモジュールが問題コードを送信しているか決定するために、ヘッダーをつけなければならないし(AT H1)、次に、情報を送ったモジュールのアドレス用の3バイトのヘッダーの第3バイトを見なければなりません。
格納されたコードの数を決定して、次のステップはモード03リクエスト(PIDは必要ではありません)を備えた実際の問題コードを要求することで、次のとおり送信します
>03
このようなコードがレスポンスで帰ってきます
43 01 33 00 00 00 00
上記の「43」は、モード03リクエストに対する反応であることを示します。
他6バイトのデータはペアで読まなければなりません(上記のものは0133、0000および0000として解釈します)。レスポンスが00の場合SAE基準によって、0000はトラブルコードがないことを表します。
格納されたコードの数を要求するときと同じように、各トラブルコードの最多の有意ビットはさらに補足情報を含んでいます。
第1の数字中の余分なビットを解釈するために次のテーブルを使用することが最も簡単です:
例としてトラブルコード(0133)が送信された場合、最初の桁(0)はそれからP0と入れ替えられます、そして、0133はP0133(反応遅れている酸素センサー回路のコードです)になります。
ISO
15765-4(CAN)プロトコルが非常に類似していることに注意してください。しかし、それはどれだけのデータ・アイテム(DTC)が次のとおりか示して、余分なデータ・バイト(第2の位置中の)を加えます。
もし受信コードがD016ならば、DをU1に読み替えて下さい。トラブルコードはU1016となります
同様に、1131を受信したならば、コードP1131になります。
PIDコードサーチ.
P0が皆さんが知りたいエンジン関係のデータで、クーラント温度、エンジン負荷等々を表すコードで、P1がメーカー独自のコードとなります。
例えばP0104はエンジン負荷率を表し、取得したデータは
x*100.0/255で計算できます。以下が計算方法です。
01 04 -> xx Calculated Load Value % x*100.0/255
01 05 -> xx Engine Coolant Temperature C x-40
01 06 -> xx Short term fuel trim Bank 1 % x*(100.0/128)-100
01 07 -> xx Long term fuel trim Bank 1 % x*(100.0/128)-100
01 08 -> Short term fuel trim Bank 2 % x*(100.0/128)-100
01 09 -> Long term fuel trim Bank 2 % x*(100.0/128)-100
01 0a -> Fuel Pressure kPaG x*3
01 0b -> xx Intake Manifold Pressure kPaA x
01 0c -> xx xx Engine RPM RPM x*0.25
01 0d -> xx Vehicle Speed km/h x
01 0e -> xx Ignition timing advance Cyl #1 deg X*0.5-64
01 0f -> xx Intake Air Temperature C X-40
01 10 -> xx xx Air Flow Rate gm/s X*0.01
01 11 -> xx Absolute Throttle Position % X*(100.0/255)
01 12 -> xx Commanded secondary air status
01 13 -> xx Oxygen sensor locations bitmap b0=sensor1, b1=sensor2, ..., b7=sensor8
01 14 -> xx yy Bank 1 Sensor 1 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 15 -> xx yy Bank 1 Sensor 2 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 16 -> Bank 1 Sensor 3 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 17 -> Bank 1 Sensor 4 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 18 -> Bank 2 Sensor 1 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 19 -> Bank 2 Sensor 2 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 1a -> Bank 2 Sensor 3 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 1b -> Bank 2 Sensor 4 Voltage/Trim V, % x*0.005, if y!=ff then y*(100.0/128)-100)
01 1c -> xx Auxiliary Input Status bitmap b0:PTO Active
01 20 -> xx xx xx xx capabilities
01 21 -> xx xx
02 00 00 -> xx xx xx xx capabilites SMART: 2 3 4 5 6 7 b c d
02 02 00 -> [dtc1h] [dtc1l] DTC that caused freezeframe
03 -> [dtc1h] [dtc1l] 00 00 00 00
05 00 00 -> xx xx xx xx capabilites
06 00 -> xx xx xx xx capabilites
06 yy -> [max=01,min=81] [valH] [valL] [limitH] [limitL] example 01 00 23 01 2c is value 23 (=35 dec)
with limit maximum 12c (=300 dec)
06 01 -> xx xx xx xx xx ncms
06 02 -> xx xx xx xx xx ncms
06 09 -> 01 xx xx xx xx -> 81 xx xx xx xx ncms
07 -> 00 00 00 00 00 00 cms
08 00 00 00 00 00 00 -> xx xx xx xx capabilites SMART: none
09 00 -> 01 30 00 00 00 capabilites 5 bytes???
Resetting Trouble Codes
これがモード04コマンドを出すことを単に要求するので、ELM327は診断の問題コードを全くリセットすることができます。
しかしながら、MILを越えるもの(あるいはCheckエンジンLight)がリセットされるので、結果はそれを送る前に常に考慮されるべきです。実際、モード04を出すことは以下のことをするでしょう:
―問題コードの数をリセットする―どんな診断の問題コードも削除する―どんな格納された凍結フレーム・データも削除する―凍結フレームを始めたDTCを削除する―酸素センサーテスト・データをすべて削除する―モード06と07情報を削除する。
― 問題コードの数をリセットします。
― 任意の診断の問題コードを削除してください。
― 任意の格納された凍結構造データを削除してください。
― 凍結フレームを始めたDTCを削除してください。
― 酸素センサーテスト・データをすべて削除してください。
― モード06と07情報を削除してください。
このデータのすべてのクリーニングはELM327_に特有ではありません、コードをリセットするためにどんなスキャンツールも使用される場合は常に、それが生じます。
このデータを失うことに関する最も大きな問題は、それが再測定を実行している一方、あなたの乗り物が貧弱に短い間走るかもしれないということです。
格納された情報を不注意に削除することを回避するために、SAEは次のことを明示します、ツールを走査する、モードが送られる場合すべての問題コード情報として、乗り物へ現実にそれを送ることが、直ちに失われる前に、モード04が意図される(「いいですか?are
you sure?」)ことを確認するに違いありません。
ELM327がメッセージの内容をモニターしないことを思い出す、したがって、それはこれが持つモード・リクエスト_の確認を求めるためには知りません、1つが書かれている場合、ソフトウェア・インターフェースの義務です。
現実に診断の問題コードを削除するために、述べたように、一つはモード04コマンドを単に出す必要があります。
乗り物からの44の応答は、モード・リクエストが行なわれたことを示します。情報は削除しました。また、MILは別れました。
いくつかの乗り物は、それらがモード04コマンドに応答する前に生じる(例えば、点火、の上で、しかし走っていないエンジン)特別の条件を要求するかもしれません。
それはすべてそこにあります、撤去問題コードにあります。
もう一度、偶然に04コードを送らないでください!
Reading Trouble Codes
もししばらくの間ELM327を使わないならば、結局『チェックエンジン』ライトが来る時には、この全体のデータシートは、概説するために大いに似ているようでしょう、
私たちは必要とする基本に迅速なガイドとしてこのセクションを提示します。
始めて、あなたのPCかPDAにELM327回路を接続し、それとHyperTerminal、ZTerm、ptelnetあるいは同様のプログラムのようなターミナルのプログラムを使用して通信することために。
それは、一方の9600あるいは38400ボーに通常セットされるべきです、8データ・ビットで、またパリティーまたはhanndシェークはない。
右の図表は、何を次に行うべきかについての迅速な手続きを提供します:
Ignition Key to ON,
but vehicle not running
イングニッションkey on
走ってはいけません
↓
>0101
いくつかのコードを確かめること
(3バイト目の2デジット)
↓
>03
コード(第1のバイトを無視し、ペア中の他のものを読む)を見ること
↓
FIX THE VEHICLE !
↓
>04
to reset the codes
CANはまたの機会にでも
実験車両がないので未だ開発未定