2016-09-05 4 views
-2

機器からのシリアルポートデータの取得に問題があります。 以下は期待される結果の画像です:Delphi Cportを使用したハードウェアからの一貫性のないデータ

欲望結果:

enter image description here

不要な結果:

enter image description here

私はので、私は自動的にデータを取得して置くことができTTIMERを使用それはメモに。

メモには、行単位でデータを配置する必要があります。

これは、ソースコードである:

procedure TForm3.Timer1Timer(Sender: TObject); 
var 
k: Integer; 
InBuffer: array[1..500] of char; 

begin 

for k:=1 to 500 do 
InBuffer[k]:=' '; 
Trim(InBuffer); 

if cport.Connected = true then 
begin 
ComLed1.Kind := lkGreenLight; 
cport.ReadStr(str,k); 
Trim(str); 
S:=str; 

if str = '' then 
begin 

end 
else 
begin 
memo1.lines.Add(str); 
end; 
end 
else 
begin 
ComLed1.Kind := lkredLight; 
txt_com_status1.Caption := 'Connected'; 
end; 
end; 

私の質問は、問題は何かということですか?そして、これのための解決策は何ですか。

+0

インデントを使用した場合、コードを読みやすくなります。 –

+1

文字列からCR(#13)とLF(#10)を削除します。また、装置が文字列の送信を完了したことを知らなければならないので、タイミングの問題もあります。 –

+0

side note:hwからのパケットにSOPとEOPがある場合は、フラグメント化されたパケットの処理を避けるためにデータをバッファし、S/EOPを使用して抽出し、フォーマットしてください。 – ComputerSaysNo

答えて

3

TMemo.Lines.Add()は、ラインを追加します。追加するテキストには、行末に改行が挿入されます。ハードウェアデータを分割して受け取っていることは明らかです。メモには、それぞれの行を別々の行として追加しています。あなたがしようとしている何をすべきか

、あなたはどちらかを行う必要があります。

  1. がに、ハードウェアからの作品を読んで、あなたは完全なメッセージの終了を検出するまで、それらをキャッシュし、その後、Add()唯一の完全なメッセージメモ。これを行う方法は、ハードウェアがデータを送信するために使用している特定のプロトコルに依存します。 STX/ETXマーカーにデータをラッピングしますか?それはメッセージを区切りますか?私たちは知らない、あなたはそれに関する情報を提供していない。そして、あなたのコードは、大量のデータを整理しようと試みている(失敗している)のです。

  2. Add()はまったく使用しないでください。代わりに不要な改行を挿入しないように、SelTextプロパティを使用することができます。

    memo1.SelStart := memo1.GetTextLen; 
    memo1.SelLength := 0; 
    memo1.SelText := str; 
    

、あなたのタイマーコードはいくつかの奇妙なことをやっている言われていること。 InBufferは空白で埋められ、その後、(失敗した)トリムされ、完全に無視されます。初期化されていないkの値をReadStr()に渡しています。あなたが読んだstrの値はメモに追加される前にうまく整えられません。 strSに割り当ててから、Sを無視します。

は、代わりにこれを試してみてください:

procedure TForm3.Timer1Timer(Sender: TObject); 
var 
    str: AnsiString; 
begin 
    if cport.Connected then 
    begin 
    ComLed1.Kind := lkGreenLight; 
    txt_com_status1.Caption := 'Connected'; 
    cport.ReadStr(str, 256); 
    str := Trim(str);  
    if str <> '' then 
    begin 
     memo1.SelStart := memo1.GetTextLen; 
     memo1.SelLength := 0; 
     memo1.SelText := str; 
    end; 
    end 
    else 
    begin 
    ComLed1.Kind := lkredLight; 
    txt_com_status1.Caption := 'Disconnected'; 
    end; 
end; 

。あるいは(あなたがOnRxCharイベントがありTComPortを使用していると仮定します):

procedure TForm3.Timer1Timer(Sender: TObject); 
begin 
    if cport.Connected then 
    begin 
    ComLed1.Kind := lkGreenLight; 
    txt_com_status1.Caption := 'Connected'; 
    end 
    else 
    begin 
    ComLed1.Kind := lkredLight; 
    txt_com_status1.Caption := 'Disconnected'; 
    end; 
end; 

procedure TForm3.cportRxChar(Sender: TObject; Count: Integer); 
var 
    str: AnsiString; 
begin 
    cport.ReadStr(str, Count); 
    str := Trim(str);  
    if str <> '' then 
    begin 
    memo1.SelStart := memo1.GetTextLen; 
    memo1.SelLength := 0; 
    memo1.SelText := str; 
    end; 
end; 

編集コメントで提供された新しい情報に基づいて、次のように試してみてください:

private 
    buffer: AnsiString; 
    portConnected: boolean; 

procedure TForm3.Timer1Timer(Sender: TObject); 
begin 
    if cport.Connected then 
    begin 
    if not portConnected then 
    begin 
     portConnected := true; 
     buffer := ''; 
     ComLed1.Kind := lkGreenLight; 
     txt_com_status1.Caption := 'Connected'; 
    end; 
    end 
    else 
    begin 
    if portConnected then 
    begin 
     portConnected := false; 
     ComLed1.Kind := lkredLight; 
     txt_com_status1.Caption := 'Disconnected'; 
    end; 
    end; 
end; 

procedure TForm3.cportRxChar(Sender: TObject; Count: Integer); 
var 
    str: AnsiString; 
    i: integer; 
begin 
    cport.ReadStr(str, Count); 
    buffer := buffer + str; 
    repeat 
    i := Pos(#10, buffer); 
    if i = 0 then Exit; 
    str := Copy(buffer, 1, i-1); 
    Delete(buffer, 1, i); 
    memo1.Lines.Add(str); 
    until buffer = ''; 
end; 
+0

sir Remyハードウェアdoesnt私はハードウェアからすべてのデータを取得し、有用なデータだけを取得する必要があります。 –

+0

私は接頭語とサフィックスをハードウェアデータに置き、それらの間のデータだけを読み込むことは可能ですか?ハードウェアは自動的に送信するプログラムなので、タイマーを使用する必要がありますか?それをどうやるの?ありがとうございました。 :) –

+0

@ YeojsonBarceloは、ほとんどのプロトコルと同様に、送信される各メッセージには、ハードウェア信号であれ、ソフトウェアデリミタであれ、定義された開始と終了が必要です。 1つのメッセージが終了し、次のメッセージが始まるシリアルポート上でハードウェアがどのくらい正確に表示されますか?何かがあるはずです。どんな種類のデバイスと通信していますか?シリアルプロトコルが使用されていることについて、そのドキュメンテーションは何を言っていますか? –

関連する問題