注意。 ほとんどのCOMポートコンポーネントは、所有者に報告するときにヒントを得ません。通常、ポートからバイトを収集する責任を負うスレッドには、1つ以上のバイトが処理可能な状態であることがOSによって通知されます。この情報はあなたのレベルまで単純に表示されます。だからあなたは、メッセージが転送されることを期待すると、あなたはOSがあなたに与えているものを得る。
すべての受信文字をグローバルバッファにバッファリングする必要があります。メッセージ文字列の最後の文字を取得したら、メッセージを処理します。
ここでは、メッセージ開始が特殊文字で識別され、メッセージの末尾が別の文字で識別される例を示します。
あなたのメッセージが別の方法で構築されている場合は、コードをどのように適応させるかを理解できます。
var
finalBuf: AnsiString;
{- Checking message }
Function ParseAndCheckMessage(const parseS: AnsiString) : Integer;
begin
Result := 0; // Assume ok
{- Make tests to confirm a valid message }
...
end;
procedure TMainForm.ComPortRxChar(Sender: TObject; Count: Integer);
var
i,err: Integer;
strBuf: AnsiString;
begin
ComPort.ReadStr(strBuf, Count);
for i := 1 to Length(strBuf) do
case strBuf[i] of
'$' :
finalBuf := '$'; // Start of package
#10 :
begin
if (finalBuf <> '') and (finalBuf[1] = '$') then // Simple validate check
begin
SetLength(finalBuf, Length(finalBuf) - 1); // Strips CR
err := ParseAndCheckMessage(finalBuf);
if (err = 0) then
{- Handle validated string }
else
{- Handle error }
end;
finalBuf := '';
end;
else
finalBuf := finalBuf + strBuf[i];
end;
end;
は、これは既知の問題です。より多くの環境でそれを持っていた。データ・イベント・トリガーは実際に続くデータよりも速い。読書の前に少し待っているのに加えて、他に何かがあるかどうかはわかりません。 – pritaeas
これはかなり正常です。文字をバッファに格納し、タイマーをリセットするだけです。その後、タイマーを使用して実際のアクティビティをトリガーします。タイマーはかなりタイトになる可能性があります。あなたは "状態マシン"で終わり、イベントのためのトリガーを持っています。 – mj2008
Djean CrnilaのTComport(いくつかのコンポーネントは「TComport」と呼ばれています)を使用するとします。この問題は、データイベントのトリガに関連している可能性がありますが、シリアルデバイスのボーレートが、コンポート制御のレートとは異なるレートに設定されている可能性もあります。デバイスが数msごとにパケットを送信する場合、パケットが適切な長さであれば、データパケット全体を簡単にキャプチャして解析できます。デバイスはパケット制御文字の終わりを送信しますか?それはより簡単になります。あなたがデバイスに関する詳細情報を提供し、パケットなどを受信した場合、誰かがヘルプを提供できる可能性があります。 – SteveJG