Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Delphi Probleme beim ComPort auslesen (https://www.delphipraxis.net/152201-probleme-beim-comport-auslesen.html)

Orko 14. Jun 2010 22:01


Probleme beim ComPort auslesen
 
Einen schönen guten Abend,

ich hab ein kleines Projekt wo ich zwischen einem Mikrocontroller und einem PC Daten austausche z.B. Akku Status, Zeiten und so was. Der Controller arbeitet einwandfrei hab die Daten über ein Terminal ausgelesen. Das Prinzip meiner Programmierung auf dem Controller war so gedacht das die ersten beiden Zeichen eine Art Befehls Codierung ist damit das PC Programm weiß was für Nutzdaten folgen z.B. steht "7F" dafür das jetzt Daten kommen die den Zustand des Akkus darstellen. Auf dem Terminal würde das dann wie folgt aussehen "7F456" die Zahl 456 ist in diesem beispiel jetzt der Wert des AD Wandlers (Akku Stand). In diesem Zuge habe ich mich mit der ComPort Library http://sourceforge.net/projects/comport/ beschäftigt und folgenden code geschrieben:
Delphi-Quellcode:
procedure TForm1.ComPort1RxChar(Sender: TObject; Count: Integer);
var
command: string;
Temp_in_string:string;
power: integer;
lange: integer;
begin

  sleep(300);

  comport1.ReadStr(temp_in_string,count);

  temp_in_string := trim(temp_in_string);

  temp_in_string := copy(temp_in_string,length(temp_in_string) -4,20);

  command := copy(temp_in_string,1,2);

  comport1.ClearBuffer(true,true);

  if command = '00' then
  begin

  timer1.Enabled := true;

  label7.Caption := 'Messung';

  end;

  if command = '7F' then
  begin

  lange := length(temp_in_string) - 2;

  Power := strtoint(copy(temp_in_string,3,lange));

  power := trunc(power * 0.204);

  label5.Caption := inttostr(power) + '%';

  end;

  if command = 'FF' then
  begin

  timer1.Enabled := false;

  lange := length(temp_in_string) - 2;

  edit1.Text := copy(temp_in_string,3,lange);

  label7.Caption := 'Bereit';

  end;

  if command = 'F7' then
  begin
  label7.Caption := 'Bereit';
  end;

  temp_in_string :='';

end;
Nun habe ich ein paar fragen: Springt das Ereignis "RxChar" an wenn der erste Charakter in den Buffer gelangt?
Was bedeutet "#$D#$A"?

Hab jetzt das Problem das es manchmal geht und manchmal nicht. (mehr nicht!!) :shock:
Hat jemand eine Idee wie man das sauber Programmieren kann? Ich hab keine Ahnung wie die Daten im Buffer gespeichert sind.
Wenn ich mir im Debug die Variable "temp_in_string" ansehe dann sieht das so aus "'7F456'#$D#$A'7F456'#$D#$A'7F456'#$D#$A" hab versucht es aus zuschneiden aber irgendwas haut nicht hin. Hoffe ihr könnt mir helfen. MfG Orko

Klaus01 15. Jun 2010 07:43

AW: Probleme beim ComPort auslesen
 
Guten Morgen,

da Du die Daten mit ComPort1.ReadString einlist
wird die Routine noch $D und $A einfügen.
Das sind die Zeichen für das Zeilenende unter Windows.


Grüße
Klaus

oki 15. Jun 2010 10:44

AW: Probleme beim ComPort auslesen
 
Hi,

erst einmal würde ich das Sleep raus nehmen. Ich wüßte nicht, welchen Grund es dafür gibt.

Dann solltest du daran denken, dass auch mal nur ein Zeichen empfangen wird. Das heist nicht, dass dein Controller nur ein Zeichen sendet, sondern dass das Ereignis erst ein Zeichen liefert und dann das nächste oder den Rest.
Somit solltest du deine empfangenen Daten in einen "globalen" Zwischenspeicher puffern. Dann prüfen, ob darin mindestens erwartete Anzahl Zeichen enthalten sind, den betrefenden Part vorne rauskopieren und im Puffer löschen. Dann die Auswertung. Das alles idealer weise in entsprechende Methoden auslagern.

Ich denke, da stecken deine Probleme.

Gruß oki

LargoD 15. Jun 2010 13:37

AW: Probleme beim ComPort auslesen
 
Hallo Orko,

das RxChar Event liefert Dir ein oder mehrere Zeichen vom Mikrocontroller ab, das ist abhängig vom Timing des MC und von Deinen Timeout-Einstellungen für TComPort. Du müsstest Dir, wie Oki schreibt, den String selbst zusammensetzen und dann auswerten.
Da der MC anscheinend immer am Ende eines String $0d$0a sendet, gibt es eine einfachere Lösung.
TComPort bietet eine Paket-Erkennung an. Du kannst als Paket-Ende $D$A definieren und bekommst dann im OnPaket-Event genau den gewünschten String zurück. Sieh Dir das in der Doku oder im Beispiel von TComPort mal an, ist einfach und zuverlässig.

Gruß
Erich


Alle Zeitangaben in WEZ +1. Es ist jetzt 09:26 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz