はじめに
前回記事、おうちでできるCAN通信(Arduino+MCP2515+sigrok)に続き、今回は、MCP2515 MCP_CAN_lib に含まれるOBD_Simを用い、実車を使わず、ELM327アダプターとスマホアプリにより、OBD2スキャンツールをテストできる環境を構築します。
準備するもの
ハードウエア
- Arduino Unoマイコンボード (または、互換ボード)
- MCP2515 CAN通信モジュール (Amazonで1個あたり500円程度で入手できます)
- ELM327 OBD2インターフェース (Bluetooth接続タイプがAmazonで1500円程度で入手できます)
- 12Vが出力できる電源(ACアダプター等)
- ジャンパー線(ELM327とMCP2515、Arduinoと結線します)
ソフトウエア
- Arduino IDE
- MCP_CAN_lib Arduino MCP2515ライブラリ
- ELM327 OBD2スキャンアプリ Torque Lite(OBD2&Car) for Andoroidなど
ハードウエアの結線
- ArduinoとMCP2515モジュール、ELM327 OBD2インターフェースをジャンパー線などで接続します。
- あまりお勧めできませんが、ELM327のコネクタピンが、Arduinoなどのピンよりも太いため、今回はジャンパー線のメスコネクタ穴を拡げて挿入しています。
- ELM327は、自動車のOBDコネクタから12V電源を供給して動作するため、12VのACアダプタ等から供給します。
** OBD2コネクタピン**
ピン番号 | 機能 | 接続先 |
---|---|---|
4 | シャーシアース | 12V電源 GND |
5 | 信号アース | Arduino GND |
6 | CAN High | MCP2515 CAN H |
14 | CAN Low | MCP2515 CAN L |
16 | バッテリー電圧 | 12V電源 + |
動作確認
サンプルコードのビルド
- MCP_CAN_libのExampleにあるOBD_Sim.inoを使います。
OBD_Sim.ino 50行のMCP2515のクロック周波数を8MHzに修正します。
qiita.rb
if(CAN0.begin(MCP_STDEXT, CAN_500KBPS, MCP_8MHZ) == CAN_OK)
Serial.println("MCP2515 Initialized Successfully!");
else
Serial.println("Error Initializing MCP2515...");
Arduino IDEでビルド後、MCP2515との接続が正常に動作すると、シリアルモニタに表示されます。
OBD2スキャンアプリの接続
- スマホのOBD2スキャンアプリを起動し、BluetoothやWifi等でELM327と接続します。
- OBD2の通信プロトコルがいくつかあり、Arduinoで動作している仮想ECUが自動的に認識されます。(サンプルプログラムでは、ISO15765 500Kbps)
エンジン回転数の確認
エンジン回転数の値を変化させるため、OBD_Sim.ino 169行 Engine RPM レスポンス値(2bytes)を修正します。(0→7000rpmを繰り返します)
OBD_Sim.ino
else if(pid == 0x0C){ // Engine RPM
txData[0] = 0x04;
unsigned int rpm = (unsigned int)(millis() % 7000) * 4; // RPM:0->7000
txData[3] = (unsigned char)(rpm >> 8);//RPM A //0x9C;
txData[4] = (unsigned char)(rpm - ((rpm >> 8) << 8));//RPM B //0x00;
tx = true;
}
else if(pid == 0x0D){ // Vehicle speed
故障コードの表示と消去
OBD_Sim.ino 33行 DTCコード用変数を追加します。
OBD_Sim.ino
//Current Diagnostic Trouble Code
byte DTC[] = { 0x05, 0xA0, 0x09, 0x00, 0x13, 0x80, 0x14, 0x90, 0x45, 0xA0, 0x36};
// CAN RX Variables
unsigned long rxId;
byte dlc;
byte rxBuf[8];
OBD_Sim.ino 525行 DTCコードの表示とクリア処理を行うよう修正します。
OBD_Sim.ino
//=============================================================================
// MODE $03 - Show stored DTCs
//=============================================================================
else if(mode == 0x03){
//byte DTCs[] = {(0x40 | mode), 0x05, 0xC0, 0xBA, 0x00, 0x11, 0x80, 0x13, 0x90, 0x45, 0xA0, 0x31};
byte DTCs[] = {(0x40 | mode), DTC[0], DTC[1], DTC[2], DTC[3], DTC[4], DTC[5], DTC[6], DTC[7], DTC[8], DTC[9],DTC[10]};
iso_tp(mode, pid, 12, DTCs);
}
//=============================================================================
// MODE $04 - Clear DTCs and stored values
//=============================================================================
else if(mode == 0x04){
// Need to cleat DTCs. We just acknowledge the command for now.
for(int i = 0; i < =10; i++){
DTC[i] = 0;
}
txData[0] = 0x01;
tx = true;
}
参考 OBD2データフレームに関する情報
- WikiPedia OBD-II PIDs https://en.wikipedia.org/wiki/OBD-II_PIDs
- CAN Multiple Frame Transmission https://happilyembedded.wordpress.com/tag/can/