きれいに制御されている

Rover MEMSからのデータの読み出し,ちょこちょこと作り込みの甘い部分はあるものの,データは収集できるようになったので,今日の遠出の往復の際のデータを記録し,手作業で視覚化してみた。

これは豊田から名古屋へ移動した際のデータの抜粋。

灰色の幅ひろいデータは酸素濃度センサ値。数値で見たときはかなりばらついているんじゃないかと思ったが,グラフ化してみたらきれいに一定幅に収まっている。青はエンジン回転数,橙色は蓄電池電圧。一箇所,異常値(20V)がある。定電圧装置が故障しかかっているのかなと思ったが,その瞬間のエンジン回転数は863rpmなので,発電電圧がそれほど上がっているとも思えない。コイルタイムなるものも記録をとったが,みると,蓄電池電圧の上下に反比例して変動している。MEMSの解説文書によれば,インジェクタ方式の制御ではエンジン回転数とバッテリ電圧に応じて点火装置の通電時間を制御しているとのことなので,このことなのだろう。但し,その文書では3.0から3.5ミリ秒の範囲で制御しているとのことであったが,手元のデータでは4.58から6.17ミリ秒となっている。謎。

ちなみにエンジンルームでのコネクタと電線はこんな処理。

車内側は基盤むき出しです。

ひっかけて短絡しないようエポキシ樹脂で適当にかばってあります。

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ミリ秒単位では,現在出ているような瞬停みたいな現象や前触れのない回転数の低下の原因究明に役立つものでもなさそうですが…。まぁ工学部出身の元エンジニアとしては,こういう技術探求がしたくなるのです。

 

 

Haskellメモ というか,High Sierra と FTDI USB Serial メモ

以前からぼちぼち開発しているRoverMiniコンピュータデータ取扱用のプログラム,ので本日はその原因究明と対策実施。

現象

  • macOS X を High Sierra にしたら,FTDIのUSBシリアル変換機がマック上ではttyデバイスとして認識されなくなった。
  • 同じハードで仮想マシン上のWindows10では同変換器を検出し,正常にECUと通信できるので,マック上のドライバの問題と想定。
  • メーカー(FTDI社)の最新ドライバなどをインストールしてみたが,状況は変わらなかった。
  • High Sierra ではセキュリティ強化のため,場合によっては「システム環境設定」のセキュリティとプライバシー設定で,明示的に権限許可を与えないと動作しない機能拡張があるが,現時点では許可催促の表示は出ていない(ただし,当該催促は最初にその機能拡張が動作しようとしてから一定の時間以内にのみ表示され,その後は消えてしまうとのことなので,OSアップデート後にケーブルを初めて挿入した際,これを見逃した可能性はある)。

原因探索

ネットで検索した所,以下のことがわかり,ドライバが複数あって,衝突して不具合となっている可能性があるものと思われた。

  • Appleは,しばらく前(少なくとも Marverics )から,自社のFTDIチップ用ドライバを mac OS に含めて提供している。
  • 幾つかのサイトでは,FTDI社のドライバとApple社のドライバの切り替えを行って問題が解決したことを報告している。(例1例2例3例4
  • 両ドライバとも,kext形式で提供されている。
  • kextとは,加除可能なOS機能追加モジュールであり,sudo kextstatで現在使われているモジュールの確認ができる他,sudo kextload xx.kext でモジュールを追加することができる。
  • 当該ハードには,OSバージョンアップ前からFTDI社のドライバが入れてあり,機能していたが,こうした場合,High Sierraのインストールでは,(クリーンインストールであっても?)サードパーティー提供のドライバが新たな権限許可を与えずとも動作するようになっている模様。

対策

ドライバを一つにする。Apple社提供のものでまずは実験してみて,その上で,FTDI社のものを実験してみるかを判断することにした。実際の作業としては,以下の通り。

  • 存在しているドライバの確認。→/System/Library/Extentions にAppleUSBFTDI.kext 2017/08/25 14:20 6.0.0 がある。また,Library/Extentions に FTDI社のドライバ D2xxHelper.kext 2015/11/09 2.0.0 があった。
  • kextstat | grep FTDI で動作している機能拡張を確認。今回の場合はなかった(両方共読み込み失敗の様子)。
  • FTDI社のドライバを削除の上,マックを再起動。
  • 手動でAppleのドライバを読み込み(cd /System/Library/Extentions  -> sudo kextload AppleUSBFTDI.kext)
  • kextstat で機能拡張が読み込まれているかを確認。この時点では読み込まれていない。
  • ケーブルを接続。kextstatで状況確認→ドライバが読み込まれている。
  • /dev/ を確認。無事,認識され,/dev/tty.usbserial-DJ0… として表示された。

まとめ

  • 今回のトラブルの原因は複数の機能拡張(ドライバ)を設置したことによる競合。
  • 純正とメーカー製の二種類のドライバで機能・性能が違いそうなので,今後,機能・性能で不審な点があった場合,ドライバを変えてみるという策をとってみる必要がある。

以上