TMemo.Lines.Add()
ajoute un ligne. Le texte que vous ajoutez aura un saut de ligne inséré à la fin de celui-ci. Il est clair que vous recevez les données matérielles en morceaux, et vous ajoutez chaque pièce séparément comme sa propre ligne dans le mémo.
Pour faire ce que vous essayez, vous devez soit:
Lire les pièces du matériel et les mettre en cache jusqu'à ce que vous détectez la fin d'un message complet, puis Add()
messages uniquement complets au Note. La manière de procéder dépend du protocole utilisé par le matériel pour vous envoyer des données. Enveloppe-t-il les données dans les marqueurs STX
/ETX
? Est-ce qu'il délimite les messages? Nous ne savons pas, vous n'avez fourni aucune information à ce sujet. Et votre code essaye (sans succès) de couper beaucoup de données qu'il ne devrait probablement pas jeter du tout. Ne pas utiliser Add()
du tout. Vous pouvez utiliser la propriété SelText
à la place pour éviter d'insérer des sauts de ligne inutiles.
memo1.SelStart := memo1.GetTextLen;
memo1.SelLength := 0;
memo1.SelText := str;
Cela dit, votre code de minuterie est en train de faire des choses bizarres. InBuffer
est rempli avec des espaces, puis (sans succès) coupé, puis complètement ignoré. Vous transmettez une valeur k
non initialisée à ReadStr()
. La valeur str
que vous lisez est tronquée sans succès avant d'être ajoutée au mémo. Vous affectez str
à S
et en ignorant S
.
Essayez ceci:
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;
Sinon (en supposant que vous utilisez TComPort
qui a un événement 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;
Modifier sur la base de nouvelles informations fournies dans les commentaires, essayez quelque chose comme ceci:
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;
Il serait plus facile de lire votre code si vous utilisiez une indentation. –
Supprimez CR (# 13) et LF (# 10) de votre chaîne. Il y a aussi un problème de synchronisation, car vous devez savoir quand l'équipement a fini d'envoyer la chaîne. –
note de côté: si les paquets du hw ont SOP et EOP (il devrait), vous pouvez tamponner les données pour éviter le traitement des paquets fragmentés et utiliser S/EOP pour extraire, puis formater comme vous s'il vous plaît – ComputerSaysNo