Serial Monitor hängt sich in Win auf.

Rund um die LCL und andere Komponenten
Antworten
Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

Ich bin für dieses Projekt https://www.lazarusforum.de/viewtopic.p ... &hilit=avr eine Serial-Monitor am bauen.
Unter Linux funktioniert dies wunderbar, aber unter Windows hängt es sich auf.
Ich kann Senden drücken, die Daten werden geschickt, und die Antwort kommt auch im Memo zurück, so wie erwartet.
Ich kann das Fenster maximieren, verkleinern, minimieren. Kann es auch mit einem anderem Fenster überdecken, funktioniert alles einwandfrei.
Aber sobald ich das Fenster verschieben oder die Grösse ändern will, hängt sich Windows komplett auf.
Einzig was dann noch geht ist Crtr-Alt-Del und anschliessend mit dem Taskmanger mein Projekt zu beenden.

Aus diesem Grund habe ich den Serial-Monitor auf ein Minimum abgespeckt, siehe Anhang.
Der Fehler ist da weithin vorhanden.
Egel ab er am Empfangen ist oder nicht.

Hat jemand einen Rat ?
Kann das sonst noch jemand nachvollziehen.

Getestet mit einem nativem Win 8.1
Und in einer VB mit Win10.
Dateianhänge
Serial_Monitor_abgespeckt.zip
(127.02 KiB) 112-mal heruntergeladen
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
h-elsner
Lazarusforum e. V.
Beiträge: 259
Registriert: Di 24. Jul 2012, 15:42
OS, Lazarus, FPC: LINUX Mint21.1, Win10, Lazarus 2.2.4, FPC3.2.2
CPU-Target: X86-64; arm 32bit
Wohnort: Illertissen
Kontaktdaten:

Re: Serial Monitor hängt sich in Win auf.

Beitrag von h-elsner »

Im Timer Event hast du While Timer1.Enabled do begin... Warum? Das schreit geradezu nach einer Endlosschleife, da die Bedingung ja immer erfüllt ist.
Wenn ich if Timer1.Enabled then begin nehme, tritt der Fehler nicht mehr auf. Damit wird ja auch bei jedem Event abgefragt, ob der Timer noch läuft.

Gruß HE

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

Vielen Dank, Dank deiner Hilfe ist das Problem gelöst. :wink:
Manchmal sieht man den Wald vor lauter Bäume nicht.

Im Timer Event hast du While Timer1.Enabled do begin... Warum? Das schreit geradezu nach einer Endlosschleife
Ursprünglich hatte es mal so ausgesehen, als ich noch synaser verwendete:

Code: Alles auswählen

while Timer1.Enabled and (ser.CanRead(10)) do begin

Ich habe die wihle Schleife ganz entfernt.
Jetzt läuft es unter Linux und Windows.

Code: Alles auswählen

var
  i: integer;
  buf: array[0..4096] of byte;
  Count: integer;
begin
 
//  while Timer1.Enabled do begin
    Count := SerReadTimeout(SerialHandle, buf, Length(buf), 10);
    for i := 0 to Count - 1 do begin
      Memo1.Text := Memo1.Text + char(buf[i]);
    end;
 
    Memo1.SelStart := -2;
    Application.ProcessMessages;
//  end;
end;
 
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

Ich habe es mal auf ein Minimum reduziert.

Code: Alles auswählen

procedure TSerial_Monitor_Form.Timer1Timer(Sender: TObject);
begin
  while Timer1.Enabled do begin
    Application.ProcessMessages;
  end;
end;

Dabei kann ich die gleichen Eigenschaften nachvollziehen.

Das interessanteste dabei, wieso läuft es unter Linux, wie wen nicht wäre ?
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Serial Monitor hängt sich in Win auf.

Beitrag von af0815 »

Es würde nur dann nicht in eine Loop kommen, wenn das BS innerhalb des TimerEvents den Timer automatisch deaktiviert.

BTW: Ich deaktiviere den jeweiligen Timer IMMER beim Einstieg in die Timerroutine und aktiviere den Timer erst wieder am Ende der Timerroutine - quasi als letzten Befehl. Ich hatte vor Jahren das Problem, das der Timer - aus welchen Grund auch immer - nochmals gefeuert hat. Damals war die Laufzeit der Routine knapp an dem TimerWert. Kann mich aber nicht erinnern ob das Lazaruzs oder D7 war :-) Seit damals habe ich habe ich keine Probleme mit dem Timer, egal welches BS.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

Ich habe in meinem Programm noch was gefunden, was es ausbremsen könnte, das Abfüllen der Memo.
Bis jetzt habe ich immer den ganzen Text eingelesen und wieder beschrieben.
Im Grunde reicht es, dies immer nur mir der letzen Zeile zu machen.

Code: Alles auswählen

procedure TSerial_Monitor_Form.Timer1Timer(Sender: TObject);
var
  i: integer;
  buf: array[0..4096] of byte;
  Count: integer;
  c: integer;
begin
  Timer1.Enabled := False;
  Count := SerReadTimeout(SerialHandle, buf, Length(buf), 10);
  for i := 0 to Count - 1 do begin
    //      Memo1.Text := Memo1.Text + char(buf[i]); // alt
    c := Memo1.Lines.Count - 1;
    Memo1.Lines[c] := Memo1.Lines[c] + char(buf[i]); // neu
  end;
 
  Memo1.SelStart := -2;
  Timer1.Enabled := True;
end;   


Noch besser, wen man es so ähnlich machen könnte:

Code: Alles auswählen

  Memo1.Lines[c] := Memo1.Lines[c] + buf;
Zuletzt geändert von Mathias am Sa 25. Apr 2020, 13:55, insgesamt 1-mal geändert.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6198
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Serial Monitor hängt sich in Win auf.

Beitrag von af0815 »

das Diable/Enable solltest du mit try/finally umgrenzen, damit ist sichergestellt, das bei einem Fehler der Timer noch funktioniert.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

das Diable/Enable solltest du mit try/finally umgrenzen, damit ist sichergestellt, das bei einem Fehler der Timer noch funktioniert.

Hast recht, wen es mal Probleme beim Einlesen gibt, wird der Timer nie mehr angeworfen.

Meinst du so ist besser ? :wink:

Code: Alles auswählen

procedure TSerial_Monitor_Form.Timer1Timer(Sender: TObject);
var
  buf: array[0..4095] of byte;
  bufCount, SLCount: integer;
begin
  Timer1.Enabled := False;
  try
    bufCount := SerRead(SerialHandle, buf, Length(buf) - 1);
    if (bufCount > 0) or (bufCount < 4095) then begin
      buf[bufCount] := 0;
 
      SLCount := Memo1.Lines.Count - 1;
      Memo1.Lines[SLCount] := Memo1.Lines[SLCount] + StrPas(PChar(@buf[0]));
 
      Memo1.SelStart := -2;
    end;
  finally
    Timer1.Enabled := True;
  end;
end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Benutzeravatar
fliegermichl
Lazarusforum e. V.
Beiträge: 1432
Registriert: Do 9. Jun 2011, 09:42
OS, Lazarus, FPC: Lazarus Fixes FPC Stable
CPU-Target: 32/64Bit
Wohnort: Echzell

Re: Serial Monitor hängt sich in Win auf.

Beitrag von fliegermichl »

Mathias hat geschrieben:
das Diable/Enable solltest du mit try/finally umgrenzen, damit ist sichergestellt, das bei einem Fehler der Timer noch funktioniert.

Hast recht, wen es mal Probleme beim Einlesen gibt, wird der Timer nie mehr angeworfen.

Meinst du so ist besser ? :wink:

Code: Alles auswählen

procedure TSerial_Monitor_Form.Timer1Timer(Sender: TObject);
...
 


Besser als ohne den Timer zu deaktivieren ist es allemal. Ich würde solchen Code aber trotzdem nicht in einem TimerEvent verarbeiten.
Ich denke, für TimerEvents sollte das gleiche gelten wie für Interrupthandler. Schnell nur ein, zwei Flags setzen und wieder raus.

Wenn Du den Timer z.B. verwendest, um damit Hardware getaktet anzusteuern, dann kommt das durcheinander weil die "Zeit" nicht mehr stimmt. Du hast ja schliesslich den Timer angehalten.

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

Ich würde solchen Code aber trotzdem nicht in einem TimerEvent verarbeiten.

Wie würdest du es denn machen ?
Mit welchen Event würdest du dann in Memo schreiben ?

Wenn Du den Timer z.B. verwendest, um damit Hardware getaktet anzusteuern, dann kommt das durcheinander weil die "Zeit" nicht mehr stimmt. Du hast ja schliesslich den Timer angehalten.
Das wäre in diesem Fall nicht so tragisch, wen der Timer mal ein bisschen später kommt, hätte es einfach ein paar Zeichen mehr im Puffer.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Serial Monitor hängt sich in Win auf.

Beitrag von sstvmaster »

Mathias hat geschrieben:Wie würdest du es denn machen ?
Mit welchen Event würdest du dann in Memo schreiben ?

Ich würde LazSerial nehmen anstatt serial.pp. LazSerial hätten dann auch einen "OnRxData" Event.

Ist dann auch zumindest Windows und Linux kompatibel.
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

Genau das will ich vermeiden, das man eine zusätzliche Package von dritt Anbietern verwenden muss.
Daher habe ich mich für die Unit Serial entschieden.

Aber du hast schon recht, LazSerial ist flexibler, da es synaser enthält, so wie das auch bei synapse der Fall ist.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

sstvmaster
Beiträge: 575
Registriert: Sa 22. Okt 2016, 23:12
OS, Lazarus, FPC: W10, L 2.2.6
CPU-Target: 32+64bit
Wohnort: Dresden

Re: Serial Monitor hängt sich in Win auf.

Beitrag von sstvmaster »

Oder du kannst eventuell auch DataPort (OPM) nehmen, basiert auch auf synapse. Und hat auch eine speziellen Seriellen Modus für FTDI USB->Seriell Chipsätze, siehe: https://github.com/serbod/dataport
Ist auch für Windows und Linux.

Edit:
Oder das TComPort. Siehe Anhang.
Dateianhänge
cport.rar
(80.95 KiB) 113-mal heruntergeladen
LG Maik

Windows 10,
- Lazarus 2.2.6 (stable) + fpc 3.2.2 (stable)
- Lazarus 2.2.7 (fixes) + fpc 3.3.1 (main/trunk)

Mathias
Beiträge: 6164
Registriert: Do 2. Jan 2014, 17:21
OS, Lazarus, FPC: Linux (die neusten Trunk)
CPU-Target: 64Bit
Wohnort: Schweiz

Re: Serial Monitor hängt sich in Win auf.

Beitrag von Mathias »

Da hat es auf einmal Serial Packages wie Sand am Meer.
Dies ist sicher interessant, wen man Exotisches ansteuern will.
Solche Packagen wären früher intetessant gewesen, wen man exotische CNC Maschinen an den PC anschliessen wollte.

Mein Ziel ist momentan nur ein einfacher Serial Monitor, welcher ich in meine Ebedded GUI einbauen will.
Und wen andere die Ebedded GUI installieren wollen, will ich denen nicht zumuten das man sich noch mit Fremd Packagen rumschlagen muss. :wink:
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten