ECUデータ読み出しその後

手が空いたときにちょこちょこと進めてきたRover Mini 1.3i のECUからどデータ読み出しプログラム,一段落しました。macOSで動かす IoT アプリを関数プログラミング言語Haskellで作るというかわった取り組みです。

これまでの経緯

もともとは,自分のMini 1.3i で出ている不具合の原因究明の参考情報をとりたいがためにはじめました。不具合は,具体的に はアイドリング中にエンジン停止する不具合が時々発生している他,アクセルを踏み込むと,特に上り坂で1800rps付近でエンジンが瞬停(?ノッキング?)するような現象が雨の日や標高の高い山間地でよく発生するような状況です。

  • 下記のCollin Bourassa氏のページで掲載されていた情報をもとに,自分のMini 1.3iに搭載されているECU接続用のUSB-シリアル変換ケーブルを作成した。変換チップ付きUSBケーブルは電子工作ではおなじみ秋月から購入し,自分で電線をはんだ付け。またECU側からの信号線はコネクタは通販で大垣の某事務用品店から購入,電線は大須の電気街で耐熱電線を購入して,自分ではんだ付け。
  • 上記接続ケーブルを使い,MacBook Airにのせてある仮想ソフト上のWindows XP/10 にてMEMS Gaugeを動作させることができた。
  • とりあえず,この環境で,しばらくログを取ってみた。上記の不具合との関連はわからないが,時々,各センサの値がおかしな値となるほか,バッテリ電圧も降下する様子。また,突然コネクトが切れ,再接続をしなければならない現象も発生。かなり電装系にトラブルを抱えている模様。
  • まずは,しばらくテスタを車内に持ち込み,シガレットプラグで電圧をモニタリング。当初は特に不具合はなかったが,そのうちエンジンの回転数に合わせて電圧が比例して変化する現象が発生。修理業者さんに見てもらったところ,発電機の定電圧化装置が壊れていたので修理。
  • エンジン停止が頻発したため,一時期,修理業者さんに長期入院させる。この頃,業者さんも発電機交換やECU点検・交換など様々な取り組みをしていただいたが,現象はおさまらなかった。鉄製の部品に穴の空いた場所を電線が走っており,その部分の被覆が剥けているのを見つけていただき,補修していただいた折はしばらく現象はおさまったが,その後復活。
  • また,ECUのコネクタ部分の接触が悪くなっているかもと爪をおこしていただいたりした後,やはりしばらく現象はおさまったが,その後復活。
  • 修理業者さんいわく,動力系に不具合はなく,この年式にしては状態が良いとのこと。
  • 毎回,車中にMBAを持ち込み,仮想ソフトを立ち上げ,Windowsを走らせ,USBポートをWindows側に接続し,MEMS Gaugeを立ち上げ,接続させ,ログをとる,という一連の作業をだんだんわずらわしく思うようになり,macOSのTerminal.appで直接動くものを作ることに。macOSで動けば,Raspberry Piに簡単に移植できるだろうから,気軽に使えるようになるだろうという目論見。
  • どうせやるなら新しいことに挑戦ということで,関数型言語Haskellで作ることにする。IoTと抽象化・遅延評価などというHaskellの特徴はあまり相性が良いというわけではないが,だからこそ誰もそんなにやらないだろうということで挑戦。
  • HaskellでUSB−シリアル変換ケーブルの通信をするのにOSのシステムコールを使うかとも思ったが,serialportというライブラリをHackageで見つけ,これを使うことに。まだHaskell環境に慣れていなかったため,当初はうまく自動で組み込めず,ソースを自分のプログラムのソースに移して動作させ始めた(その後,パッケージ管理の仕組みを学んで,外部ライブラリとして管理できるようになった)。
  • 時間の合間合間を見てMEMS Gaugeのソースを参考にしながら接続アプリを開発。当初は初期化コマンドは通ったが,コマンドに対する反応をうまく拾えなかった(4バイト読み込み指定でも2バイトしか拾えないなど。ECU側が数10MHzで動いているし,9600bpsという速度なので,タイムアウトの設定かといろいろ変えてみたが,結局,1バイトずつ読み込むことで解決)。
  • コマンド7Dで得られるデータ数が,ずいぶん少ない14バイトであることが判明(MEMS Gaugeは32バイトを設定している)。MEMS Gaugeのサイトはある程度年式の新しいモデルに対応していたが,こちらは1992年に買った,クーラー付きの日本モデルであり,別のサイトで見るとECUのモデル番号も桁数からして違っている(うちのMiniのECUモデルを表す4バイトの値は39 00 00 5Cという値であり,おそらく部品番号 MNE10078 の, Manual  SPI - Japan - Cooper 向け)。

ECUのログを見ると2016年4月3日のものが残っていたので,遅くともその頃から実際に試行錯誤していたはずだが,記事として出てくるのは2016年から。Amazonの注文履歴では2013年に入門Haskellを,2014年にはReal World Haskellを,2016年にはRaspberry Pi 2Bとディスプレイを発注した記録が残っている。MEMS Gaugeのタイムスタンプは2016年2月。また,非公開の書きかけ記事で関数型言語プログラミングのデザインパターンに関するものが2015年5月2日付けで見つかった。HaskellをECUデータ読み出し用に使おうとしだしたのは2015年から2016年にかけてか。

以下,魚野のサイト内ページです。

Androidで動くPDAのGeminiや,Windows10で動くGPD Pocket でありもののソフトを動かしてもよいのだけれど,ログを解析するのにやっぱりmacでやりたいのと,日本仕様ECUの対応を組み込むのが楽という点で,自作を続けます。

今後の予定

  • パフォーマンス計測と改善。現在は80と7Dのデータを読み込んで表示する1周期に400ミリ秒程度。非同期IO・マルチスレッドにしてもよいのだが,どうせデータを待っている間にmac側がすることもないので,シングルスレッドの基本線は変えない予定。改修はHaskellのチューニングの勉強として,読みづらい表現の変更や例外処理の改善(ByteStringでindexの指定を間違うとHaskellといえど実行時エラーで止まってしまう---止まってしまうのは黙って意図しない処理が行われるよりよっぽどマシなのだが---のでその対策をきちんとする)など。
  • 上記と関連するが,ちゃんとHaskellらしい構造に。今はファイルハンドル情報(を含んだSerialPort型の情報)をあちこち持ち回っているが,本来,カプセル化すべき。文字列の++演算も遅いだろうし,メモリリークの現状も把握できていない。たかだか1回あたり数十バイトの情報を保持するのにByteStringを多用してループをまわしているので,かなり効率の悪い構造になっていてガベージコレクションの時間もかなりとなれているのではと想像する。
  • 出力はcsv形式なので,これをもとに別途GUIを使った表示の仕組みを用意する。本体がHaskellなのでElmを活用?FRPを使ってGUIにもHaskellを使う?昔ながらのcursesなどにしてしまう?
  • Raspberry Pi と得体の知れない互換ワンボードが用意してあるので,そちらで動くようにHaskell環境,OS環境,ディスプレイ環境を整え,車内に常時備え付けられるようにする。ケーブルは今の半自作USBシリアル変換ケーブルをそのまま転用。
  • 広域低電力WANなどの利用で1992年式Miniをコネクティッドカーにする?
  • 関数型言語でのIoT対応について,何かしら発展の方向性を考えてみる(たくさんのセンサからいろんなデータが来て,それを処理していく。また,センサからデータを拾う頻度がまちまちになるだろう。そして,データの処理について,おそらくは柔軟にユーザーに変更できるようにしたくなるだろう。
  • モナドなどは概念をある程度理解し,使えるようにはなった(作れるまでには至っていない)ので,Haskellでのモナド,並行並列処理,GUI,DSL,FRPを使いこなせるように。
  • また,関数型言語プログラミングでの抽象化やモナドなどの考え方は,生物の意識という問題と何かしら関係がありそうな気がするので,それを検討してみる。

参考にした資料など

ECUとの情報のやりとりのプロトコル等

きっかけは忘れましたが,このプロジェクトを始めるに当たり,大いに参考になったのは,独自解析でRover MiniのECUからの情報を読み出すプログラムを公表していたColin Bourassa氏のページ。

  • Rover MEMS 1.6 diagnostic Protocol...以前はとある大学のサイトに掲載されていたColin Bourassa氏によるRover MEMSの診断プロトコルに関するページ。今はbearinghead.comというドメインに掲載されている(記事の掲載日時は2014-04-21となっているが,2015年6月と12月に追記されている)。オープンソースで無料の診断情報ソフト(MEMSGauge)やライブラリ(librosco)が紹介されている他,接続用のシリアルケーブルの作り方(利用するUSBシリアルチップやコネクタの規格・入手先情報を含む),ECUのプロトコルなどの詳細が紹介されている。このページがなければ,今回のプロジェクトはなかった。
  • MEMS Diagnostics (Google Group) ... 上記サイトからリンクされている。2015年に開設された模様。
  • MG Rover MEMS Modular Engine Management Explained (ビデオ)...最近見つけた,おそらく販売店向けなどのために作られた技術解説ビデオ。ECUがどんな情報をもとに何を制御しているかを簡単に解説している。
  • Display/diagnostics utility for Rover MEMS 1.6 ECU...github内にあるプロジェクト
  • MEMS 1.6/1.9 ECU diagnostics...android用の診断ソフトを紹介している。androidは興味の対象外なので一応あるということだけ知っておく。

シリアル通信について

かつて学生時代,パソコン通信華やかりし頃の1980年代後半,PC-9800シリーズなどのDOS上でTurbo Pascalや,Pascalを開発したWirthが後継として開発した言語,Modula-2を使って端末エミュレーションプログラムなどを作っていました。ですのでシリアル通信の大枠は理解しているのですが,今回はmacOSというUnix系のOSで,しかもUSBポートを通じてのシリアル通信ですので,いろいろよくわからない点があります。そこでまずはLinux Serial HOWTOなどであらためて基礎から勉強してみました。

その他見つけた情報

車のSNSサイトみんカラや自動車販売・修理業者さんのサイトに,Androidoのソフトと自作ケーブルを使った接続事例,市販されているらしい簡易モニタでの診断事例が時々紹介されている。

そろそろガソリンエンジン車の終焉も近いでしょうし,カーシェアリングなども東京ほどではないですが名古屋でも充実してきつつありますので,いつまでMiniを所有し続けるのかはわかりません。そもそもデータを吸い出しても400ミリ秒単位では,現在出ているような瞬停みたいな現象や前触れのない回転数の低下の原因究明に役立つものでもなさそうですが...。まぁ工学部出身の元エンジニアとしては,こういう技術探求がしたくなるのです。