前回記事ではECUから起動時のコードの受信はするものの、ECUへのコマンドリクエストに応答しない場合があることか分かりました。原因と推察される時間精度の確認と向上を行います。
Windows(汎用OS)の特性
知らない方は全く知らないハナシですが、Windows等の汎用コンピュータ上のOSは大量の処理を行うのは得意ですが、1/1000秒単位で細かい時間を守ることができません。厳密に1/1000秒、1/1000000秒 のタイミングを計るには、マイコンを使用する必要があります。Win32API、.NET、Java、VBAの各Sleep系APIは1/1000秒単位を指定できるようになっていますが、それは保証されていません。OSの実行状況によって早まったり遅くなったりします。もしくは全く効いていない。PC機種や個体によっても変わってきます。画面操作によって遅延する場合もあります。
よってPCだけで時間精度の高い計測システムは構築は難しいのです。よってこのようなアプリは疑いを持つ必要があります。現物合せで Sleepをたたいていると最悪です。(機械メーカが作っているアプリではかなり多く見受けられます) なお VGAKKL に搭載されている FT232R はそこをコントロールする機能もインターフェイスもありません。
現状の確認
IAW_SCAN2 では、Sleepによって以下のタイミングが使用されています。少なくともmsec 2桁台は厳しいです。
- 4 msec
- 5 msec
- 15 msec
- 20 msec
- 110 msec
- 150 msec
- 550 msec
- 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が課題なのでしょうか?