Reputation: 13
I made an interface software using Delphi 7 to fetch data from arduino. Arduino has 3 sensors. Arduino will send 16 characters for sensor value. The example is :
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
I assign the string value from arduino to an editText called Edit1. After that I use string "Copy" to get the sensor value one by one. The sensor value then will be displayed one by one in a label. But it takes long time for label to change the value. First time, I think it caused by label that slow on update. Then I change the label with editText, but work the same way (still takes long time to update the value). So is there a way to make this things faster? or there's something wrong with string operation?
This is my code:
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;
Upvotes: 0
Views: 593
Reputation: 21033
The header of the procedure has an important parameter, Count
:
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
It tells you how many characters are received and ready for you to read. Mostly, with low comm speed there will be only one, but sometimes there could be two or more. If you only read 1 character as in
ComPort1.ReadStr(Str, 1);
the remaining characters will be lost or they will not be read before the next OnRxChar
occurs. For the last characters in a message, that will not take place before the next message triggers the event. That may explain why you percieve the process to be so slow. The cure is to read Count
characters instead of only one.
But there seems to be an error and you were not at all able to receive complete measurements. Let's look at the code:
Edit1.text := Edit1.text + Str;
if Str = 'm' then
Edit1.text := '';
if Length(Edit1.text) >= 15 then
Your intention is to wait for the m
flag, and clear Edit1.Text when you do receive it. That's fine. Then you receive and collect the rest of the message until you have 15 characters in Edit1.Text, which is also ok. But then, you overwrite the received message with a '2'
?
begin
Edit1.text := '2';
Of course the rest of the message parsing will then fail.
If you correct above two errors, I believe that your code might actually work.
Edit after comment
Replace these lines
Edit1.text := Edit1.text + Str;
if Str = 'm' then
Edit1.text := '';
with
for i := 1 to Length(Str) do
if Str[i] = 'm' then
Edit1.text := ''
else
Edit1.Text := Edit1.Text + Str[i];
And then you could also remove Buffer
as you are not using it as well as the superfluous begin .. end;
pair.
Upvotes: 5
Reputation: 80107
You read only one byte from comport and do a lot of unnecessary work with visual components. Short sketch:
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;
Upvotes: 3