VC++ CLIでよく忘れていること【随時更新中】

たまにVC++ CLI (.NETのC++) を使うと忘れているこのメモです。

「ライブラリ」でなく「追加の依存ファイル」と記述されている。Windows標準ライブラリなら「追加のライブラリディレクトリ」は設定しなくてよい。

win32APIやMFC特有の型WORDDWORDは、CLIでは追加includeが必要。

オブジェクトの頭^

Java、C#の感覚で書いてしまうとBuildエラーになり悩む。new でなく gcnew もであることもお忘れなく。

以下を選択。Publicメソッドを普通に書けば、C#等からも利用が可能。MFC ActiveX Controlのように特別な設定はいらない。

.NETクラスライブラリを使うとき

C#等から、CLIで生成したの.dllを使用時に「間違ったプログラムのフォーマットを読み込もうとしました。」とエラーが発生する場合、x86、x64を指定する。C#単体だと「Any CPU」でWindows上で動作するが、、、

以降、随時追加中...

2000年以前用FIATダイアグツールを日本語化+αを試す4: FT232Rで7812bpsを生成可能か?

前記事では時間精度を向上させましたが、ECUから常に応答をえられるようにはなりませんでした。今回は特殊な通信速度7812bpsが生成できているか検証します。

実は、ディスククトップ機などPCに搭載されたリアルRS232Cでは通信速度は、4800,9600,19200,38400 … と定められた数値しか指定できません。Win32APIに数値は指定できますが作用しません。

しかしFT232Rなど仮想COMタイプではそれが可能な場合があります。FTDI社のドキュメント:AN232B-05_BaudRates をみると通信速度の計算式が記載されており、特に定まった通信速度ではないようですが具体例は未記載でよくわかりません。試してみるしかないようです。

まず IAW-SCAN2 のコードに記載されていた 7680bps を試します。手法は弊方のシリアル通信汎用アプリ(いちおうms storeで公開中)から 0x00 を送信し、オシロスコープでK-LINEの信号幅を計測します。

下図(小さくて分かりにくいですが)は 7680bps0x00 を送信し、その幅を計測した結果です。 0x00 は信号上はLowとなりStopBitとあわせると9bitの幅となり、通信速度から1bit幅を乗じると期待値は1,152msとなります。実測は1,170ms なので、指定通信速度は生成できているようです。


ECUメーカの指定値 7812bps も試してみます。こちらはFT232Rの内部分周的に変わらないかとおもいましたが、実測は1,158ms となり期待値に近づきました。しかしながら 7680bps 時の実測1,170ms でも誤差1%なので通信するには問題ないハズです。


以上のようにBaudRateは正しく生成できていますが、未だECUから常時応答が得られません。何か特殊なセキュリティがあるのでしょうか? 次記事につづきます。

2000年以前用FIATダイアグツールを日本語化+αを試す3:時間精度の確認と向上

前回記事ではECUから起動時のコードの受信はするものの、ECUへのコマンドリクエストに応答しない場合があることか分かりました。原因と推察される時間精度の確認と向上を行います。

知らない方は全く知らないハナシですが、Windows等の汎用コンピュータ上のOSは大量の処理を行うのは得意ですが、1/1000秒単位で細かい時間を守ることができません。厳密に1/1000秒、1/1000000秒 のタイミングを計るには、マイコンを使用する必要があります。Win32API、.NET、Java、VBAの各SleepAPIは1/1000秒単位を指定できるようになっていますが、それは保証されていません。OSの実行状況によって早まったり遅くなったりします。もしくは全く効いていない。PC機種や個体によっても変わってきます。画面操作によって遅延する場合もあります。

よってPCだけで時間精度の高い計測システムは構築は難しいのです。よってこのようなアプリは疑いを持つ必要があります。現物合せで Sleepをたたいていると最悪です。(機械メーカが作っているアプリではかなり多く見受けられます) なお VGAKKL に搭載されている FT232R はそこをコントロールする機能もインターフェイスもありません。

IAW_SCAN2 では、Sleepによって以下のタイミングが使用されています。少なくともmsec 2桁台は厳しいです。

  1. 4 msec
  2. 5 msec
  3. 15 msec
  4. 20 msec
  5. 110 msec
  6. 150 msec
  7. 550 msec
  8. 1,000 mse

Windows上で高精度タイマとして有名なのがマルチメディアタイマーです。(Window上では事務処理や通信より、音楽動画再生が重要というでしょうか?) 同タイマは別スレッドで動作するため画面操作の影響も受けにくく、別の用途でも使用しても問題ないです。計測用アプリのリアルタイム性を向上させめことが可能です。しかし絶対保障はあるわけではありません。

たたオブジェクト指向言語には組込み難いです。弊方では計測アプリケーション用にオブジェクト背ライブラリ化したものを.NETライブラリ、MFCやVB6/VBA用にActiveXを用意しています。 こちらを適用てます。その中の以下 WaitSleep methodを使います。

public ref class Moto4DiagTimer
{
 ・・・中 略・・・
	public :
   /////////////////////////////////
   // 名称:      指定時間待つ。
   // 特記事項:  CPUを回さず。
   /////////////////////////////////
   bool	Moto4DiagTimer::WaitSleep(
	   	UInt32 millsecond		// i : 待ち時間、単位ms
   );

一見Sleepと同じですが中身は以下のようなシーケンスです。

コード実装は以下のような感じです。時間の確認ができるように計測も入れます。

#define USE_MMTIMER

			diagTimer.StartCountMillsecond( );
#if USE_MMTIMER
			diagTimer.WaitSleep(110);
#else
      Thread.Sleep(110);
#endif
     addTrace( "Wait time after 0x0F: " + diagTimer.GetCountMillsecond( ) + "ms" );

トレース結果ではタイミングは守れているようになりました。しかし110ms程度であれば、処理能力の高いPC(Win11 corei5)で定常時であれば、.NET の Thread.Sleep でもそん色ないようでした。

上記はOSの認識値なので、オシロで実タイミングを確認します。5msec ィレイがあります。通信仕様書の許容範囲は±10msec なので収まってはいます。


これで実車確認をおこないましたが未だECUから応答が得られません。やはり特殊な通信速度7812bpsが課題なのでしょうか? 次の記事で調査します。

2000年以前用FIATダイアグツールを日本語化+αを試す2:仕様と具体的事象の確認

前回は同ダイアグツールの基本接続と実車疎通接続を行いました。しかし連続モニタリングと再接続性に課題があり、そもそもの仕様と具体的にどのような事象が発生しているか調査します。

まず通信仕様を理解する必要があります。通常はサプライヤ以外には非公開ですが検索するとpdfが見つかります。No.07223 と No. 3.00608 のFIAT公式資料がでてきます。No. 3.00608 の方が具体的内容のようです。No.07223は2000年以降の仕様のようであまり参考にならないです。公式か不明の”IAW 16F Technical Information”という資料に100%の内容が記載されているようです。

  • ECU接続時にSeedkey等はない。
  • 実際の通信ではチェックサムは無い。
  • ダイアグツール 接続時 1200bps、データ通信時7,812bps (コード内はクロック分周の都合か7,680bps)となっており一般と異なる。
  • 接続後は、ECUへのリクエストは1Byte。
  • 初期接続時に、110msec±10% という順守するにはPCだけでは厳しい条件あり。
  • 切断コマンドは見当たらず。

通信自体は、ダイアグツールは大体あっている感じです。


車両側ダイアグコネクタには、L_LINE が来ていたので配線を確認しました。K-LINEと合成されているだけようです。


組込み機器と通信するWindowsアプリを作る場合、以下の課題があります。

  • msec単位の処理に対して、正確にリクエスト/応答できない。0.1秒が限度。
  • 画面操作なと介入により通信は遅延する。
  • .NETは、C++&Win32APIより数倍遅い。

当アプリは配慮はされていますが万全とは言えないようです。ここは様子見ですね。

  • ECU通信部は別スレッド化されている。(これはOK)
  • 通信リトライが無い。(UARTではハード層はリトライしないので実施が常識)
  • 不正確な Thread.Sleep を多用している。
  • 通信は1byte単位で実施している。(length指定より遅れが出やすい、.NETならなおさら)
  • エコーバックの一致チェックはしていない。(一線式のKLINEおよびLINではエコーバックが不一致だとBUS競合したと判断できる)
  • 必須かは不明だが、使用者に切断操作時に、ECUへ切断コマンドは送信していない


まずECUとの通信内容をリアルタイム表示する機能が必要です。専用のアナライザ装置がベストですが、通信コンソール画面を追加します。これは別スレッドでメイン画面スレッドとPostMessageさせる取りするので処理遅延は最小です。以下アプリが受信待機していて、IG-ONしたとき、ECUから型番等が送られるのがわかります。

以下は、ダイアグツール側がECU型番を覚えているときのシーケンスで、失敗したときです。

見解としては、ECUとツールのどちらかが遅れているか、タイムアウト時間が適正でないといえそうです。ECUへのリクエストのタイミングか、ツール側の取りこぼしが疑わしいそうです。微妙なBaudrateも確かWindowsでは作りだせなかった記憶があります。FTDIでは作り出せるかもしれません。もろもろクロック周期の影響を受け7,812bpsジャストにはできないはずです。


モニタログのパスは変更できるようにしました。

その他、昔の勢いで使いにくい部分はどんどん直してしまいました。

  • 接続時の通信リクエストにリトライ3回を追加。
  • ウインドウサイズやグラフ幅を覚えうるように処理を追加。
  • try – catch もれも一か所あり、そこに行着くと落ちるので修正。
  • メッセージ表示中にメイン画面の操作無効されているが、× ボタンも押せないのでそこは操作できるように修正。
  • USBケーブル抜き取り時に、DISCONNECTを実行。
  • USBケーブル挿入時にCOMを自動オープンする。
  • tooptipが表示されなくなる事象を修正。
  • グラフ画面で、項目名とグラフの比率をスライダで変更できるようにした。

リポジトリ本流に戻しにくくなってしまいました。次記事につづきます。

2000年以前用FIATダイアグツールを日本語化+αを試す1:初期接続まで

GWお休みいただいていますが個人的には自動車整備を遂行しないといけません。弊方の’93型FIATがシリンダーヘッドをOHした後、アイドリング途中でエンジンが停止する事象が発生し続けています。

’80年以降のFI車なら通常ISC:Idle Speed Contorl によりアイドリング回転数はECUにより制御されています。ソレノイド(デューティ信号制御)ステッパーモータ制御(モータ専用信号制御)の2種類があり、後者の方が応答性が早いが制御が複雑になりハード面もコストUPになります。当FIATは後者です。

ここはダイアグ (故障診断もしくはスキャン)ツールで状態を確認したいところです。しかし他メーカにも同じく、FIATの2000年以前は通信プロトコルが車両メーカ固有で市販品は使えません。メーカ専用はディーラ以外では持っていないし、購入ルートがありません。

C#でのこの種のアプリ学習もかねて、オープンソースWindowsアプリのIAW_SCAN2:ダイアグ ツールを準備しました。機能を理解するため、当Project貢献のため日本語化をしました。これまでの記事は以下です。

その後、2024.1月の実車で試し、再開できていませんでした。まずその時の結果を整理します。


PC側は市販のFT232R搭載のUSB→K-LINEケーブル (自費)を使います。UART( 全二重2線式5V非同期クロックシリアル通信 )をK-LINE( 半二重1線式ISO9141/BATT電圧の非同期クロックシリアル通信 )に変換するものです。K-LINE は変換には専用ICを使いますが電気的に電圧レベルを変換してUART送受信ラインを接続しているだけでロジックは載ってません。L-LINEという信号もありますが使わないシステムもあります。

USB→K-LINEケーブルの仮想COMは、デフォルトで1回の送信で16msecディレイがあるので最小にしておきます。これはPC側は細かい通信インターバルを刻めないため、ここで調整できるようにしてあるのだと思います。

ODBII→FIAT用コネクタ はAmazon掲載品を購入(自費)。 そのままでは使えませんでした。2点加工が必要です。

  • PINの幅が実写より幅太でした。削って細くする。
  • OBDII側コネクタが、KLINE変換側よりRが大きいので、削って小さくする。
  • 後々確認すると、車両側 L-Line とOBDII側 L-Line の導通がありません。仕様か断線かはよくわかりません。しかもコネクタがモールド成型なので点検も修理もできません。

結局のところ、コネクタ自体は取り換えた方がいいようです。当方実験によるとこのIAWシステムL-Line も必須でした。前述のL-Line導通無しは仕様ではなく故障のようです。コネクタはAMP製の防水3極汎用コネクタです。入手性は良好、オスメスセットを入手(自費)しました。

汎用コネクタなのに何故オリジナルはモールド型を作ってまで不具合を生んでいるのか不思議です。オリジナルはカットして、AMPコネクタに組替えます。これではL-Line も導通OKです。

しかしながらこのIAWシステムはOBDIIのコネクタは不要なので、このAMPコネクタだけで車両側ゲーブルは手作りできそうです。次回は常時モニタ用にBluetooth版でも作ろうかと思います。


エンジンルーム内の以下のダイアグコネクタと接続します。

一般的にダイアグコネクタよりBATTが来ているですが当FIATは来ないようです。ODBII→FIAT用コネクタ のワニ口をバッテリとボディアースに接続します。


割とすんなりECUと接続でき、ECU機種を認識しました。ECU機種は自動判別です。

ケーブル接触が微妙なのか通信が断線時は以下のようになります。

ケーブル接触不良を物理的に見るため、ケーブル内に接続中LEDを追加します。出力はFT232Rのオプションポートを使います。

LEDを観察しつつ電気的に接続している最中でもよく接続が切れます。一度切れると次に接続しにくくなり、下図のように約20secでタイムアウトします。ECU機種は自動判別をしない方が調子いいようです。


アイドル維持できない場合、アイドル時のスロットル開度が怪しいです。基本ECUが学習するのですが規定値を外れすぎていると学習しません。アイドル時スロットル開度の規定値が何Voltかは、メーカ整備書にも、ヘインズのマニュアルにも未記載で、ダイアグツールを使うようにとしが記載がないです。

スロットル開度は確認できました。このままではまずそうですしかし一瞬モニタはできるのですがすぐ切れ、その後再接続できません。モニタしながな調整ができないですね。一晩待つと接続できる傾向がみられます。アプリの問題か、ECUが接続解除命令を受けとれておらず、新しい接続を拒否しているのかも、、、


一瞬見えた故障表示ですが、FAILが立っていました。

一応、FAILをクリアしました。


実施しなければならない機能項目がないかみてみました。本ツールは、アクティブテスト市場調整機能までサポートしているようです。なかなかです。なおこれらの項目は車両毎に変わってきます。


以上、割と使えそうですが、連続モニタリングと再接続性に課題があります。次記事では、それを解析していきます。しかしこの種のアプリを開発していた時期もあり懐かしいです。