字符串操作太慢
String Operation so Slow
我用Delphi7做了一个接口软件,用来从arduino中获取数据。 Arduino 有 3 个传感器。 Arduino 将发送 16 个字符作为传感器值。例子是:
m 0 0 . 0 1 0 0 . 0 2 0 0 . 0 3
[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16]
[1] Flag for Start value
[2],[7],[12] are sensors status (0=disconnected, 1=connected)
[3][4][5][6] first sensor value
[8][9][10][11] second sensor value
[13][14][15][16] third sensor value
我将来自 arduino 的字符串值分配给名为 Edit1 的 editText。之后我使用字符串 "Copy" 一个一个地获取传感器值。然后传感器值将在标签中一一显示。但是标签改变值需要很长时间。第一次,我认为它是由更新缓慢的标签引起的。然后我用 editText 更改标签,但工作方式相同(更新值仍然需要很长时间)。那么有没有办法让这件事变得更快?还是字符串操作有问题?
这是我的代码:
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
Str,Buffer,Rstatus,Sstatus,Tstatus: String;
arus : real;
i : integer;
begin
DecimalSeparator:='.';
ComPort1.ReadStr(Str, 1);
begin
Buffer:=Buffer + Str;
Edit1.Text:=Edit1.Text+Str;
if Str='m' then
edit1.Text:='';
if Length(Edit1.Text) >=15 then
begin
Rstatus:=copy(Edit1.Text,1,1);
Sstatus:=copy(Edit1.Text,6,1);
Tstatus:=copy(Edit1.Text,11,1);
if Rstatus='0' then
begin
Label1.Caption:='0 A';
Label1.Update
end
else
begin
Label1.Caption:=copy(Edit1.Text,2,4)+' A';
Label1.Update
end;
if Sstatus='0' then
begin
Label2.Caption:='0 A';
Label2.Update
end
else
begin
Label2.Caption:=copy(Edit1.Text,7,4)+' A';
Label2.Update;
end;
if Tstatus='0' then
begin
Label3.Caption:='0 A';
Label3.Update
end
else
begin
Label3.Caption:=copy(Edit1.Text,12,4)+' A';
Label3.Update;
end;
end;
end;
end;
您只从 comport 中读取了一个字节,并且对可视化组件做了很多不必要的工作。小草图:
ComPort1.ReadStr(Str); // read out all data
Buffer:=Buffer + Str;
//ensure that buffer starts with right value
pm := Pos('m', Buffer);
if pm > 1 then
Delete(Buffer, 1, pm - 1);
if pm < 0 then
Buffer := '';
if Length(Buffer) >= 16 then begin
if Buffer[2] = '0' then begin
//do something for zero rstatus
end else begin
//do something for nonzero rstatus
end;
//and so on
Delete(Buffer, 1, 16);//erase treated data
end;
程序的头部有一个重要的参数,Count
:
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
它告诉您收到了多少个字符并准备好供您阅读。大多数情况下,通信速度较低时只有一个,但有时可能有两个或更多。如果您只读取 1 个字符,如
ComPort1.ReadStr(Str, 1);
在下一个 OnRxChar
发生之前,剩余的字符将丢失或无法读取。对于消息中的最后一个字符,在下一条消息触发事件之前不会发生。这或许可以解释为什么您认为该过程如此缓慢。解决办法是阅读 Count
个字符,而不是只读一个。
但是似乎出现了错误,您根本无法接收到完整的测量数据。我们看代码:
Edit1.text := Edit1.text + Str;
if Str = 'm' then
Edit1.text := '';
if Length(Edit1.text) >= 15 then
您的意图是等待 m
标志,并在收到后清除 Edit1.Text。没关系。然后你接收并收集剩余的消息,直到你在Edit1.Text中有15个字符,这也是可以的。但是,您用 '2'
?
覆盖收到的消息
begin
Edit1.text := '2';
当然,其余的消息解析将失败。
如果您更正了以上两个错误,我相信您的代码可能确实有效。
评论后编辑
替换这些行
Edit1.text := Edit1.text + Str;
if Str = 'm' then
Edit1.text := '';
和
for i := 1 to Length(Str) do
if Str[i] = 'm' then
Edit1.text := ''
else
Edit1.Text := Edit1.Text + Str[i];
然后你也可以删除 Buffer
因为你没有使用它以及多余的 begin .. end;
对。
我用Delphi7做了一个接口软件,用来从arduino中获取数据。 Arduino 有 3 个传感器。 Arduino 将发送 16 个字符作为传感器值。例子是:
m 0 0 . 0 1 0 0 . 0 2 0 0 . 0 3
[1][2][3][4][5][6][7][8][9][10][11][12][13][14][15][16]
[1] Flag for Start value
[2],[7],[12] are sensors status (0=disconnected, 1=connected)
[3][4][5][6] first sensor value
[8][9][10][11] second sensor value
[13][14][15][16] third sensor value
我将来自 arduino 的字符串值分配给名为 Edit1 的 editText。之后我使用字符串 "Copy" 一个一个地获取传感器值。然后传感器值将在标签中一一显示。但是标签改变值需要很长时间。第一次,我认为它是由更新缓慢的标签引起的。然后我用 editText 更改标签,但工作方式相同(更新值仍然需要很长时间)。那么有没有办法让这件事变得更快?还是字符串操作有问题?
这是我的代码:
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
Str,Buffer,Rstatus,Sstatus,Tstatus: String;
arus : real;
i : integer;
begin
DecimalSeparator:='.';
ComPort1.ReadStr(Str, 1);
begin
Buffer:=Buffer + Str;
Edit1.Text:=Edit1.Text+Str;
if Str='m' then
edit1.Text:='';
if Length(Edit1.Text) >=15 then
begin
Rstatus:=copy(Edit1.Text,1,1);
Sstatus:=copy(Edit1.Text,6,1);
Tstatus:=copy(Edit1.Text,11,1);
if Rstatus='0' then
begin
Label1.Caption:='0 A';
Label1.Update
end
else
begin
Label1.Caption:=copy(Edit1.Text,2,4)+' A';
Label1.Update
end;
if Sstatus='0' then
begin
Label2.Caption:='0 A';
Label2.Update
end
else
begin
Label2.Caption:=copy(Edit1.Text,7,4)+' A';
Label2.Update;
end;
if Tstatus='0' then
begin
Label3.Caption:='0 A';
Label3.Update
end
else
begin
Label3.Caption:=copy(Edit1.Text,12,4)+' A';
Label3.Update;
end;
end;
end;
end;
您只从 comport 中读取了一个字节,并且对可视化组件做了很多不必要的工作。小草图:
ComPort1.ReadStr(Str); // read out all data
Buffer:=Buffer + Str;
//ensure that buffer starts with right value
pm := Pos('m', Buffer);
if pm > 1 then
Delete(Buffer, 1, pm - 1);
if pm < 0 then
Buffer := '';
if Length(Buffer) >= 16 then begin
if Buffer[2] = '0' then begin
//do something for zero rstatus
end else begin
//do something for nonzero rstatus
end;
//and so on
Delete(Buffer, 1, 16);//erase treated data
end;
程序的头部有一个重要的参数,Count
:
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
它告诉您收到了多少个字符并准备好供您阅读。大多数情况下,通信速度较低时只有一个,但有时可能有两个或更多。如果您只读取 1 个字符,如
ComPort1.ReadStr(Str, 1);
在下一个 OnRxChar
发生之前,剩余的字符将丢失或无法读取。对于消息中的最后一个字符,在下一条消息触发事件之前不会发生。这或许可以解释为什么您认为该过程如此缓慢。解决办法是阅读 Count
个字符,而不是只读一个。
但是似乎出现了错误,您根本无法接收到完整的测量数据。我们看代码:
Edit1.text := Edit1.text + Str;
if Str = 'm' then
Edit1.text := '';
if Length(Edit1.text) >= 15 then
您的意图是等待 m
标志,并在收到后清除 Edit1.Text。没关系。然后你接收并收集剩余的消息,直到你在Edit1.Text中有15个字符,这也是可以的。但是,您用 '2'
?
begin
Edit1.text := '2';
当然,其余的消息解析将失败。
如果您更正了以上两个错误,我相信您的代码可能确实有效。
评论后编辑
替换这些行
Edit1.text := Edit1.text + Str;
if Str = 'm' then
Edit1.text := '';
和
for i := 1 to Length(Str) do
if Str[i] = 'm' then
Edit1.text := ''
else
Edit1.Text := Edit1.Text + Str[i];
然后你也可以删除 Buffer
因为你没有使用它以及多余的 begin .. end;
对。