Delphi-xe7 arduino tpapro ApdComPort 读取

Delphi-xe7 arduino tpapro ApdComPort read

我想通过 USB(串行)从我的 Arduino 读取一个字符串。 我制作了这个脚本,但它有问题:

procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
var
msg:string;
I:word;
C:ansichar;
begin
msg := '';
for I := 1 to count do
begin
C := apdComPort1.GetChar;
if C = #7 = false then
begin
if C in [#32..#126] then
begin
  msg := msg + C;
end;
end;
end;
listbox1.Items.Add(msg);
msg := '';
end;

问题是 "count" 不正确。 例如,当我发送 "Backspace" 时,这是输出:

Bac
kspace

但是在arduino串口监视器上它工作正常。 有谁知道为什么 "count" 不正确以及如何解决它?

您假设 完整 数据与事件之间存在一对一的关系。没有这样的保证。可能需要多个事件才能接收到 complete 数据。该事件只是报告 一些 数据可用在那一刻。在您的示例中,您可能收到了 3 个字符的事件,然后收到了剩余 6 个字符的第二个事件。您调用了 Add() 两次,一次针对数据的每个部分,而不是一次针对 complete 数据。

因此,您必须分析接收到的数据,根据需要在事件之间缓存它,然后仅当您有 完整 数据时才调用 Add()展示。例如:

var
  msg: string;

procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
var
  I: Word;
  C: AnsiChar;
begin
  for I := 1 to Count do
  begin
    C := apdComPort1.GetChar;
    if C <> #7 then
    begin
      if C in [#32..#126] then
      begin
        msg := msg + C;
      end;
    end else
    begin
      ListBox1.Items.Add(msg);
      msg := '';
    end;
  end;
end;

正如 Remy 所说,在串行通信中接收数据时,您可能会为同一字符串触发许多事件。事实上每个字节一个事件,但驱动程序通常缓冲数据。

要知道消息的结尾,您应该在此消息的末尾添加一些字符序列。如果您使用 Serial.println() 而不是 Serial.print() 从 Arduino 发送字符串,那么它将在文本后添加一个新的行标记。这样你只需要将字符添加到 ListBox1.Items.Text 属性 而不是使用 Add 函数。您需要允许字符 #10 和 #13 才能完成这项工作。

procedure TForm1.ApdComPort1TriggerAvail(CP: TObject; Count: Word);
var
  C: AnsiChar;
begin
  while Count > 0 do
  begin
    Dec(Count);
    C := apdComPort1.GetChar;
    if C in [#32..#126, #10, #13] then
    begin
      ListBox1.Items.Text := ListBox1.Items.Text + C;
    end;
  end;
end;

此外,如果您这样做,则无需发送响铃字符 (#7)。