CommXコンポーネントの応答速度を改善するには?

解決


eshter  2008-10-07 00:48:18  No: 32125

こんにちは。CommXコンポーネントの応答速度についての質問です。
センサ回路からのデータをPCに読み込むために、CommXコンポーネントを使っています。
環境はWindowsXPにDelphi7、シリアルケーブルをUSBに変換してデータをPCに送っています。

現在起こっている問題は、センサに入力を加えても、それがプログラム上で反映されるまでにラグがあるということです。
ソースは以下の通りです。
フォーム起動時にポート解放、データ受信時にChr関数でデータをコードから数字に戻しています。
Edit1、2はデータの監視用です。
センサからのデータは、秒間2-3回程度で送られて来ます。

procedure TForm1.FormActivate(Sender: TObject);
begin
  CommX1.PortOpen;
  i := 0;
end;

procedure TForm1.CommX1Receive(Sender: TObject; ReceiveSize: Integer);
begin
  PressData :=  Chr(Commx1.ReceiveChar);
  Edit1.Text := PressData;
  Edit2.Text := IntToStr(i);
  i := i + 1;
end;

この状態でセンサに入力を加えると、その数値の変動が反映されるのが、約2秒後くらいになってしまいます。
単純にデータを取るだけのソースで2秒くらいラグがあり、もう少し大きなプログラムに組み込むと5秒くらいラグが出てしまいます。
これを改善するのに何か良い方法はありませんか?


TS  2008-10-07 04:25:51  No: 32126

私はCommXコンポーネントを使っていませんので推測ですが

>センサからのデータは、秒間2-3回程度で送られて来ます。

上記の場合、表示は秒間で変わると思われますが
どの程度のデータか分かりませんが
バッファーが一杯になるまで実際のデータがCommX1Receivに
送られてこないとかではないですか。


eshter  2008-10-07 23:10:29  No: 32127

>>TSさん
少しこちらが書くべき情報を書き損ねていました。
センサ回路からのデータは、ハイパーターミナルで確認して秒間2-3回という意味でした。
また、

procedure TForm1.CommX1Receive(Sender: TObject; ReceiveSize: Integer);
begin
  PressData :=  Chr(Commx1.ReceiveChar);
  Edit1.Text := PressData;
  Edit2.Text := IntToStr(i);
  i := i + 1;
end;

で、Edit2はReceiveイベントが起こっているかの確認のために設置しており、
これはハイパーターミナルか送られてくるデータとほぼ同じ速度でカウントしています。
このため、Receiveイベント自体は、バッファがいっぱいになるまで、ではなく、
データが送られてくる毎に動作しています。
ちなみに、送信しているデータは1バイトの数字のみです。


TS  2008-10-08 03:24:22  No: 32128

>ちなみに、送信しているデータは1バイトの数字のみです。
目に止まらない状態で数値が変わっているとか。
Edit1.Text := Edit1.Text + PressData;
としたらどうなりますか。


どういうこと?  2008-10-08 10:25:48  No: 32129

>この状態でセンサに入力を加えると、その数値の変動が反映されるのが、約2秒後くらいになってしまいます。
>単純にデータを取るだけのソースで2秒くらいラグがあり、もう少し大きなプログラムに組み込むと5秒くらいラグが出てしまいます。
>これを改善するのに何か良い方法はありませんか?

ここでラグが発生するといってるけど

>で、Edit2はReceiveイベントが起こっているかの確認のために設置しており、
>これはハイパーターミナルか送られてくるデータとほぼ同じ速度でカウントしています。

ほぼ同じ速度でカウントしているって事はラグは発生してないんでは?


eshter  2008-10-09 18:57:06  No: 32130

>>TSさん
目に止まらない数値では変わってないです。
そもそも送信側自体が秒間2.5回くらいしか送ってないので。

>>どういうことさん
確かに、イベントの発生自体はセンサの出力のタイミングと同期しています。
ただ、センサの出力の中身が合わないのです。
出力を1から2に切り替えた時、ハイパーターミナル側ではすぐに2に切り替わるのですが、
Delphiで受けると5秒くらいしてから2に切り替わり、それまでは延々と1が出力されています。
1秒間だけセンサ出力を2に切り替え、1秒後に1に戻すと、
Delphiでは5秒後に2に切り替わり、そして約1秒後に1に戻る、というような感じです。


どういうこと?  2008-10-09 19:23:34  No: 32131

たとえばセンサーが 1 を 10個 送信して 2に切り替えた場合 
データ自体(1)が送信されてこないので 11個目 以降は 2に切り替わる
はずなんだけど

受信タイミングが異なるのならば

>Delphiで受けると5秒くらいしてから2に切り替わり、それまでは延々と1が出力されています

はありうると思うんだけど  

受信タイミングが同じでならば
DELPHI側は送信している数以上の 1 を受信している事になると思うんだけど

送信データ数と受信データ数は同じですか?


eshter  2008-10-09 20:22:13  No: 32132

>たとえばセンサーが 1 を 10個 送信して 2に切り替えた場合 
>データ自体(1)が送信されてこないので 11個目 以降は 2に切り替わる
>はずなんだけど

私もそうなると思っています。
だから不思議で仕方無いのです。データの数を考えるとすぐに切り替わるはずなのですが・・・
イベントが呼び出されるたびに毎回データも取得しなおしています。

>送信データ数と受信データ数は同じですか?

センサはPICで制御しているのですが、あまり詳しくなく内部で適当にディレイをかけて2秒で5個のデータが送信されるようにしているだけです。
ただ間違いなく、5個以上のデータは出力されていません。
BitRateの設定も送信・受信ともに一致させてあります。
Delphi側でも、Edit2のカウントは2秒で5個増えているのでイベント自体はきちんと呼び出されているのですが・・・

一度Editだけで確認するのではなくハイパーターミナルっぽいものをDelphiで作って確認してみます。


eshter  2008-10-09 21:30:48  No: 32133

ハイパーターミナルなるっぽいものを作って確認したところ、1秒未満のラグはあったものの十分な応答速度でした。
ただ、目的のプログラムに組み込むと、なぜか余分な1が出力されてしまい、結果として反応が遅れています。
同時に発生しうるイベントは他には特にないのですが、別フォームを作って、そちらはデータ取得専門にし、メインフォームで処理だけを行うようにしてみます。

はっきりとした原因が分からないので、一度解決としておきます。
返答をくださった方々、ありがとうございました。


eshter  2008-10-09 21:31:18  No: 32134

押し忘れでした。失礼。


TS  2008-10-10 00:39:53  No: 32135

>procedure TForm1.CommX1Receive(Sender: TObject; ReceiveSize: 
ReceiveSizeを表示して見る。
Commx1.ReceiveCharの型はなんですか。
送られて来るデータが1バイトのデータでないなら
1バイトだけ表示しても意味がない様な気がしますが。
Edit1.Text := Edit1.Text + PressData;
とするとどうなりますか。


TS  2008-10-10 00:47:03  No: 32136

1111222のバッファがあふれて次の222が出現するまで
表示が変更しないという事ではないでしょうか。


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加