RX-8リアルタイム情報をグラフを使ってもっと分かりやすく表示してみる

前回の動画でアイドリング時の燃費について動画にしたわけですが、アイドリング時ってことで信号待ちばかりで見ている人には退屈な動画になってしまいました^^;
そこで、きちんと走っているところを取り出して再編集。

ただ、単に再編集しても楽しくないのでグラフを一緒に載っけることにしました。これで、一瞬で数値が変わってしまうものでもいろいろ比較できます。

RX-8車載動画にリアルタイム燃費情報を表示して懐具合に思いを馳せる

というわけで、今度はRX-8の燃料消費状況をモニターして、リアルタイムの燃費情報を車載動画に重ね合わせてみました。

吹かしたときに燃料を消費するのは体感的にも理解できるのですが、信号待ちなどアイドリング時にこれほどまでに燃料を使うのかと驚きました。百聞は一見にしかず、ですね。

CANデータを見るプログラムを動画にしてみた

先般のエントリにてRX-8のCANデータをグラフにしてみましたが、リアルタイム情報を車載動画にピクチャインピクチャとして重ね合わせた動画をつくり、ニコニコ動画にアップロードしました。

今までは見る専門だったので、どの程度の方に見て頂けるかはまったく未知数でしたが、一日経たない間に300人以上の方に見て頂けたようで。 人気動画とは比べものになりませんが、場末のブログにひっそり置いておくよりはよっぽど見て頂けるので嬉しいです。

次はもう少し派手目に作ります。

CANUSBを使ってRX-8の各種データを取り出してみる

前回のエントリまで使っていたELM327チップですが、どうも全てのデータのログを取ろうとするとバッファが溢れてしまうようで…。ただせっかく乗りかかった船なので、CANUSBという代物を購入してRX-8のデータをリアルタイムに取り出してみることにしました。

上記の画像においてグラフの意味は以下の通りです。

  • 赤 線:車速
  • 青 線:エンジン回転数
  • 紫 線:ラジエータ水温
  • 水色線:エアインテーク温度
  • 黄色線:アクセル開度
  • 赤領域:フットブレーキを踏んでいる
  • 青領域:クラッチが切れている
  • 緑領域:(高さに合わせて)ギアポジション

CANはまぁここでは車内LANのようなものだと考えておけばいいと思います。自動車内のコンピュータとその他センサや計器類との間で情報をやり取りするときのプロトコルなのですが、特徴の一つはブロードキャストだということです。 なので、OBD-IIのようにポーリングしてデータを取り出すのと違い、ネットワーク内を流れているデータであれば「盗み聞き」することができるため、車内コンピュータへの負荷が(おそらく)ありません。 コンピュータに負荷がかかった場合にもおそらくフェイルセーフが働くとは思いますが、心理的な負担がこちらのほうが少ないですね。

CANUSBは、LAWICEL社が販売している、CANデータアクセス用のケーブルです。コンピュータからはFTDI社のUSBシリアル変換コネクタが刺さっているように認識され、実際にシリアル接続でデータを取り出すのでMac、Windows、Linuxのどれからでもデータを取り出すことができます(LAWICEL社のページにはWinとLinuxしかドライバへのリンクがありませんが…)。 日本ではcompass lab.で取り扱っているようで、海外で買うのと値段も変わらなかったためこちらを利用しました。

ただこのCANUSB、車へ接続する側のコネクタが、いわゆるシリアル通信で用いるD-SUB9ピンで、実際のOBD互換のコネクタと合いません。そのためコネクタを購入あるいは自作する必要があります。

OBD2CABLES.COMでは片側がOBD-II端子、片側がD-SUB9ピンのケーブルを売っています(たとえばこれとか)。 値段は10ドル程度で、一般的なシリアルケーブルなどとたいして変わらないのですが、これを日本へ送ってもらおうとすると送料が30ドルくらいかかってしまい馬鹿馬鹿しいです。

そのため、自分はこちらのページを参考に自作しました。ただ、こちらもなんだかんだいって2000円くらいかかってしまうので、複数本数を同時に買うのであれば海外から取り寄せた方が安いかもしれません。

さて、ケーブルをつなげば後はシリアル通信なのでデータを解析するだけの簡単なお仕事です。海外には奇特な方がいて、これらのデータを既に解析して公開してくださっている方がいました。 これを先に見つけていたので、ケーブルが自作できれば後は余裕だろうと思っていたのですが…。なんと、自分の車に流れているパケットと雰囲気が違う様子。向こうの車がAT車だからなのか、それとも海外仕様だからなのか分かりませんが、結局自分で全部解析する必要にかられました…。

ま、そんなこんなですが、一応上記のグラフのようなものが書き出せるまでになりました(3日かかってしまった…)。 なお、上記のうちギアに関しては、エンジン回転数と車速から割り出しているものです。こちらもデータが取れるだろうと思っていたのですが、どうも見当たらなかったため、計算によって推定しています。

以下、もしかして自作したい人がいるかもしれないのでメモ(ただし、当然ですがこれを参考に自作アプリを作って、最悪車が暴走しても自分は責任負いませんのであしからず…)。

  • RPMは、ID 0x201の(data[0] * 256 + data[1]) / 4
  • Vehicle Speedは、ID 0x201の(data[4] * 256 + data[5] – 10000) / 100
  • Accel Throttle Positionは、ID 0x201の data[6]
  • Hand Brakeは、ID 0x212の(data[4] & 0x40)
  • Foot Brakeは、ID 0x212の(data[5] & 0x08)
  • Declutchingは、ID 0x231の(data[0] & 0xf0) //4ビット全部立つ
  • Engine Coolant Tempは、ID 0x240の data[3] – 40
  • Intake Air Tempは、ID 0x250のdata[3] – 40

他にもハンドルの回転角度が分かったりすると面白いのですが(海外のものだと分かっているのですが)、右側に舵を切っているか、左側に舵を切っているかは分かりそうなのですがそれ以上に詳しい角度などはちょっと分かりません。あっても良さそうですけどねぇ。

上記の図だといまいち温度まわりの動きが分かりにくいかもしれませんが、エンジンをかけ始めてログをとり、ぐるっと走って戻ってくるまでのデータをグラフにすると、次のようになります(上の図は、その最後の部分)。

この図を見ると、水温がぐんぐん上がっていっているのが分かります。また、スピードを出すと微妙にエアインテークエアの温度が下がり、それによって水温もちょこっと下がることがある、というのも見て取れます。

はてさて、これをどのように加工して使うか、それが問題だ。

RX-8とOBD-IIでお話をする – シリアル接続プログラミング

前回のエントリでELM327デバイスが動作することを確認したので、今回は簡単なプログラミングをしてみようと思います。

Bluetooth版のデバイスを自分は選んだので、BluetoothのRFCOMMを利用することになります。今回はJavaでプログラミングをすることにし、BluetoothライブラリはBluecoveを利用します。

実際のプログラミングのフローは以下のようになるかと思います。

  1. Bluetoothデバイスを探索する
  2. 探索が完了したらそのデバイスをオープンする
  3. ELM327の初期化
  4. ELM327にリクエストを発行
  5. ELM327から受け取ったレスポンスをparseする
  6. 4に戻る

デバイス探索に関してははじめに一度だけ行い、二度目からはBluetoothアドレスなどを保持しておけば再度行う必要はありません。また、2以降はおおむね他のシリアルデバイスでも同じ手順になるはずです。

デバイスのオープンはBluetoothの場合は以下のようになります。

String url = "btspp://XXXXXXXXXXXX:1;authenticate=false;encrypt=false;master=false";
StreamConnection connection = (StreamConnection) Connector.open(url);

ここでのurlは、デバイス探索後にデバイスが提供可能なサービスを調べると得られるものです。サービス探索は、bluecoveのServices Searchにサンプルがあるので参考になります(ウェブページ中間)。

その後、ELM327へのInput / Output Streamを開きます。

OutputStream os = connection.openOutputStream();
PrintWriter pw=new PrintWriter(new OutputStreamWriter(os));

InputStream is = connection.openInputStream();
InputStreamReader isr = new InputStreamReader(is);
BufferedReader br = new BufferedReader(isr);

これでELM327とのお話ができるようになりました。 このPrintWriterに対して前回のエントリで紹介したようなコマンドを発行し、BufferedReaderからレスポンスを得ることになります。

pw.write("AT Z\r");
pw.flush();

のような感じでコマンドを発行します。そして、それに対してレスポンスは、

int data;
while((data = br.read()) != -1 && data != '>'){
    char ch = (char)data;
    System.out.print(ch);
}

このような感じで取り出せます。ELM327からの返答はプロンプト(”>”)で終わるので、それを終了判定に使えばよいです。BufferedReaderのreadLine()を使うこともできるかと思ったのですが、最後にEOFが来ないためかプロンプトが来たところでブロックしてしまうようです。

…基本的にはこれだけです。

3.のELM327の初期化は、たとえば”AT E0\r”を送ってエコーを切る(通信量を減らす)などそういったことです。

今回は単純に得られた文字を書き出しているだけですが、本来はこれを解析する必要があります。しかし単純なプログラミングなので、あとは特別問題ないかと思います。

“01 00\r”を送ると 0101から0120までのどのリクエストに応えられるかビット列で得られます、同様に”01 20\r”は0121から0140まで得られます。これらを使い、通信先の自動車がどのリクエストに反応するかを確認した上で値を取り出すことになります。
“03\r”を送ると現在その車が陥っているトラブルに関するコードが返ってきます。これらのデータが何を示しているかは、www.obd-codes.comなどを参考にすると良いと思います。

自分のRX-8とお話をしてみましたが、あまり応答スピードは速くないですね。リアルタイムにエンジン回転数を表示するというと結構カクカクするかもしれないです。なんとかせねば。

RX-8とOBD-IIでお話をする – 動作確認

ELM327の載ったデバイスを手に入れたので、今エントリでは実際に自動車に取り付けて動作確認をしたいと思います。

前回のエントリで自分はBluetooth版デバイスを買いましたが、基本的にデバイスとお話しする方法はシリアル通信となります。RS-232C接続(つまりシリアル接続)の場合には該当するデバイスとお話をすればいいですし、USBやBluetoothの場合、各OSで仮想的なシリアルデバイスを作成できます(WindowsだったらCOM1とか、Macだったら/dev/tty.*とか)。

MacだとBluetoothで仮想デバイスを使って常にお話しするのはどうも安定性に欠けるようなのですが(Snow Leopardは長く試してないので改善しているかもしれません)、いずれにせよ動作確認のためだけであれば問題ないでしょう。

普通だったらここで実際に配布されているソフトウェアを使って動作確認をするのでしょうが、自分の場合は(それだとつまらないので)実際にターミナル経由でデバイスと直接お話をしてみることにします。

プロトコル

ELM327は古き良きATコマンドを含む対話型のインタフェースを提供しています。詳細は前回のエントリでも紹介したELM327のデータシートに書かれているのでそれを参考に進めます。

ま、英語なので斜め読みして頂くとして、重要なのは5ページ目の “Communicating with the ELM327″からです。曰く、「>プロンプトが出てきたらコマンド入れてリターンすれば結果が返ってくる(超訳)」とのこと。ま、そのほかにも大文字小文字区別しないとか、スペースをどこに挿入しても関係ないとかいろいろ書いてありますが、ま、気にしないことにします。

で、そのコマンドですが7ページ下部からずずっと載っています。

AT Z とするとreset allです。デバイスが再起動します(車の情報をリセットする訳じゃありません)。このときにELM327チップのバージョンが分かります。

AT RVとすると、ELM327に届く電圧(≒バッテリの電圧)を測ることができます。定格12Vですが、実際にはもう少し余裕を持った値になっている可能性があります。

実際にバッテリの電圧を調べるということを22ページ目で示していますので、参考になります。

このコマンドがATで始まらない場合には、ELM327は入力されたコマンドをOBDコマンドと解釈します(23ページ)。24ページ以降に実際にOBDコマンドがいくつか紹介されていますが、WikipediaのOBD-II_PIDsを見た方が手っ取り早いかもしれません。

たとえば、01 05 と打てばEngine coolant temperatureがわかり、01 0Cと打てばエンジン回転数が分かります。

接続

ELM327は、数多くの車種に対応しています。さらには、それらの車種で使われている詳細なプロトコルを自動判別して差異を吸収してくれるすぐれものです(ELM326にはそのような機能はなく、CANを使うマツダ車などは対応していなかったようです)。

車によってコネクタの位置が違うのですが、これは他社さんのページで申し訳ないのですがBLITZなど、同じコネクタを使う製品を出されている会社の情報を参考にするとすぐに分かると思います。たとえば、こちらのページから参照できる車種別適合表などは参考になると思います。

ターミナル

シリアルな機器と(手っ取り早く)お話しするときには、ターミナルを利用します。ZTermとかいろいろありますが、自分はminicomを使いました(macportsからインストール)。まぁ、お好きな物を使えばよいと思います。

基本的にデフォルトで動きましたが、add linefeedはonにしないと全て同じ行に表示されてしまいました。実際の様子はこんな感じです。

いろいろ返事がもらえていますが、OBDコマンドの場合には3バイト目からが実際の値になります。

たとえば01 0Cの返事に

41 0C 0D 2F

が返ってきていますが、ここで大事なのは0D 2Fです。これを16進数から10進数に直すと3375です。この値はエンジン回転数の4倍の値が返ってきているので(wikipediaの該当部分参照)、実際の値は843.75rpmとなります。RX-8のアイドリング時(エンジンが暖まってきた後)はだいたいこんなものなので比較的正常な値が取れていることが分かります。

とまぁ、デバイスもきちんと動いているようなので、次回からは実際にプログラミングをして値を取り出すことにしてみます。

RX-8とOBD-IIでお話をする – 準備

久々の投稿です。

OBD-IIという自動車のコネクタを通した各社共通の診断プロトコルがあるのですが、そいつを日曜プログラマでも簡単に扱えるようにするELM327というチップが存在することを知りました。 そして、そのチップを使ってシリアルやらUSB、Bluetoothなどでパソコンからお話をするデバイスもいくつか売り出されているようです。これを使うと、エンジン回転数や速度などの基本情報、それにエンジン温度や瞬間燃費等の普通は知ることのない情報をリアルタイムに取得することができるようになります。

え、そういうのだったら既に売ってるって? ええ、BLITZ R-VITとかそうですよね。仕組みはまさに同じなのですが、自分でのプログラミングだと簡単にログをとったりいろいろ遊ぶことができます。逆にそういった加工をしないのであればこちらの製品のほうが手っ取り早いと思います。 自分の場合は、パソコンと連携していろいろやってみたかったってことと、どうせすぐに飽きるのに4万とか5万とか出せないので自作することにしました。OBD-IIから情報を取り出すだけなら5000円くらいのパーツだけで済んでしまいますので。

というわけで、この投稿から数回にわたってELM327を使って車とお話しするアプリ製作の備忘録を書いていこうと思います。

今回は、ELM327を搭載したデバイスを手に入れるフェーズに関して記載します。

デバイスの選択

ELM327は、(ちょっとプログラムを組むには面倒な)OBD-IIプロトコルを、シリアルコンソールを用いて容易に自動車とお話しすることができるようにするICチップです。 ELM Electronicsという会社が作っていて、オンライン上にはELM327 のデータシートクイックリファレンスシートなどもあります。これらはプログラム作成時に利用します。

このELM327を使ったデバイスであれば基本的にどのデバイスでもデータを読み出せます。実際にUSB、RS-232C接続、Bluetoothなど、多くのバリエーションが存在します。そんな中で、自分は以下の理由からBluetooth版を選択しました。

  • 出来るだけ車内に配線を這わせたくない
  • 自分の車(RX-8)の場合、運転席ハンドル下部に端子があるため、何らかの拍子にケーブルなどが外れた場合にアクセルやブレーキに巻き込まないか心配
  • Macを使っているので、USB版はドライバが存在しない可能性がある。それにひきかえBluetoothはSPP (Serial Port Protocol)経由でデータを読み込むためドライバは不要
  • Bluetoothの弱点は電気をよく食べることですが、それもダイナモが動いてるときしか食わないのでバッテリもあがらないはず
  • ELM327はECUのデータ書き換えなどの機能はないので、万が一(無線なので)外部からいじられても大した被害にはならない。

ただまぁ、プログラミングのし易さで言えば有線の方が簡単ですし安定するはずです。どれを選ぶかはオーナー次第ですね。

デバイスの購入

そんなわけで、自分はBluetooth版のものを購入することにしました。Googleでいろいろ調べたところ、deal extremeという会社で売っていたELM327 Bluetooth OBD-II Wireless Transceiver Dongleを見つけたので、これを購入することにしました。deal extremeはPayPalを使って決済が出来るので、海外のサイトにクレジットカード番号を教えたくない、という人でも安心だと思います(自分はあまり躊躇しないで買ってしまいますが)。 金額は55ドルほど。2009年末に注文をしたのですが、円高でしたので助かりました。PayPalはドル決済と円決済を選べるようですが、ドル-円レートはクレジットカード会社のもののほうがだいぶ良かったので、PayPalではドル決済を選びました。なお、送料は無料です。

この会社、倉庫は香港にあるようで、商品出荷時には国際郵便の追跡コードをメールで知らせてくれます。自分の場合、出荷してからだいたい一週間で届きました(出荷まで半月くらいかかってましたが…)。

この青い部分が本体です。CDにいろいろソフトが入っているようですが、今回は使いません。いきなりプログラミングです。 そのプログラミングは次回以降に。