Delphi来自使用Cport的硬件的不一致数据

时间:2016-09-05 09:55:01

标签: delphi tcomport

我无法从设备获取串口数据。 以下是预期结果的图像:

欲望结果:

enter image description here

不需要的结果:

enter image description here

我使用Ttimer,因此我可以自动获取数据并将其放入备忘录。

我需要在备忘录中逐行放置数据。

这是源代码:

{{1}}

我的问题是什么问题?对此有什么解决方案。

1 个答案:

答案 0 :(得分:3)

TMemo.Lines.Add()添加。您添加的文本将在其末尾插入换行符。很明显,您正在接收硬件数据,并且您将在备忘录中单独添加每个部分作为其自己的行。

要做你正在尝试的事情,你需要:

  1. 从硬件中读取这些部分并缓存它们,直到您检测到完整消息的结束,然后Add()仅向备忘录发送消息。如何执行此操作取决于硬件用于向您发送数据的特定协议。它是否将数据包装在STX / ETX标记中?是否划分邮件?我们不知道,您尚未提供任何相关信息。并且你的代码正在尝试(不成功)修剪大量数据,它可能根本不应该丢弃。

  2. 根本不要使用Add()。您可以使用SelText属性来避免插入任何您不想要的换行符。

    memo1.SelStart := memo1.GetTextLen;
    memo1.SelLength := 0;
    memo1.SelText := str;
    
  3. 话虽这么说,你的计时器代码正在做一些奇怪的事情。 InBuffer填充空格,然后(未成功)修剪,然后完全忽略。您正在将未初始化的k值传递给ReadStr()。在添加到备忘录之前,您读取的str值未成功修剪。您要将str分配给S,然后忽略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;
    

    或者(假设您使用的TComPort事件为OnRxChar):

    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;