我想通过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;问题是“伯爵”是不对的。例如,当我发送"Backspace“时,这是输出:
Bac
kspace但是在arduino系列监视器上它工作得很好。有谁知道为什么“伯爵”是不正确的,以及如何修正它?
发布于 2015-04-12 01:41:38
正如雷米所说,在串行通信中接收数据时,同一字符串可能会有许多事件触发器。事实上,每个字节都是一个事件,但是驱动程序通常会缓冲数据。
要知道消息的结尾,您应该在消息的末尾添加一些char序列。如果您使用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)。
发布于 2015-04-11 19:58:15
假设完整的数据和事件之间存在1比1的关系.没有这样的保证。接收完整数据可能需要多个事件。这一事件只是简单地报告了当时有一些可用的数据。在您的示例中,您可能收到一个包含3个字符的事件,然后收到其余6个字符的第二个事件。您调用了两次Add(),一次针对数据的每一部分,而不是一次针对完整的数据。
因此,您必须分析正在接收的数据,根据需要在事件之间缓存数据,然后只有在需要显示完整数据时才调用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;https://stackoverflow.com/questions/29581576
复制相似问题