Serielle Daten und Dialogbox mit Abbruch

Für Fragen von Einsteigern und Programmieranfängern...
Antworten
Theozh
Beiträge: 99
Registriert: So 1. Jul 2012, 10:56

Serielle Daten und Dialogbox mit Abbruch

Beitrag von Theozh »

Hallo,

über die serielle Schnittstelle möchte ich Daten von einem Messgerät einlesen.

Was ich mir als Benutzer wünschen würde:
1. Messung wird per Knopfdruck gestartet.
2. Eine Dialogbox poppt auf mit Titel "Messung läuft... bitte warten..." und einem Button "Abbruch"
3. Die Messung wird gestartet und auf Daten gewartet.
4. Wenn die Messung zulange dauert oder der Benutzer die Geduld verliert, soll er das abbrechen können.
5. Wenn nicht abgebrochen wurde und Daten bis zum entsprechenden Terminator-Zeichen empfangen worden sind, soll die Dialogbox von alleine wieder verschwinden und das Programm weiterlaufen.

Für die serielle Kommunikation verwende ich Synaser und
function RecvTerminated(Timeout: Integer; const Terminator: AnsiString): AnsiString; virtual;

Da man aber vorher nicht weiss, wie lange die Messung dauert, müsste man den Timeout sehr hoch setzen, damit das Programm nicht abbricht bevor Daten eingetroffen sind. In dieser Zeit kann aber der Benutzer nicht abbrechen.

Wie kann ich einen Benutzerabbruch realisieren?
Evtl. einen kürzeren Timeout (z.B. 10 sec.) abwarten und dann in einer Schleife alle Sekunde nochmals nachfragen bis entweder Daten kommen oder der Benutzer abbricht? Gibt's da was Schlaueres?

Und auch mit den "selbstverschwindenden" DialogBoxen komme ich da nicht weiter, da sie wohl immer auf eine Benutzereingabe warten. Oder habe ich da etwas übersehen?
Danke für Tipps.

mse
Beiträge: 2013
Registriert: Do 16. Okt 2008, 10:22
OS, Lazarus, FPC: Linux,Windows,FreeBSD,(MSEide+MSEgui 4.6,git master FPC 3.0.4,fixes_3_0)
CPU-Target: x86,x64,ARM

Re: Serielle Daten und Dialogbox mit Abbruch

Beitrag von mse »

Theozh hat geschrieben:Wie kann ich einen Benutzerabbruch realisieren?
Evtl. einen kürzeren Timeout (z.B. 10 sec.) abwarten und dann in einer Schleife alle Sekunde nochmals nachfragen bis entweder Daten kommen oder der Benutzer abbricht? Gibt's da was Schlaueres?

Entweder so oder die serielle Kommunikation in einem separaten thread abwickeln. In MSEgui läuft der Lesekanal von TAsynSercommChanel in einem separaten thread und es gibt die eventproperty OnResponse. OnResponse wird mit dem mainthread synchronisiert, so dass man in OnResponse auch GUI-Elemente ansprechen kann. Während der Übertragung läuft die GUI ganz normal weiter.
Problematisch könnte sein, wie man das Messgerät zum Abbruch bringt um die nächste Übertragung nicht zu stören.

Und auch mit den "selbstverschwindenden" DialogBoxen komme ich da nicht weiter, da sie wohl immer auf eine Benutzereingabe warten. Oder habe ich da etwas übersehen?

Wenn die Dialogbox eine von dir erstellte Form ist, kann sie auch wieder über die Instanzvariable geschlossen werden werden.

MAC
Beiträge: 770
Registriert: Sa 21. Feb 2009, 13:46
OS, Lazarus, FPC: Windows 7 (L 1.3 Built 43666 FPC 2.6.2)
CPU-Target: 32Bit

Re: Serielle Daten und Dialogbox mit Abbruch

Beitrag von MAC »

Ich würde sagen das spricht für einen weiteren Thread:
(Bei Threads immer die Warnung: Lasse nie 2 Threads gleichzeitig irgendwo hin schreiben oder lesen, sonnst kommt eventuell Datenmüll heraus)-

Im folgenden Beispiel kümmuf ert sich dein Thread vollkommen um das Lesegerät, nur die Funktion TLeseThread.Execute wird im Kontext eines weiteren Threads ausgeführt.
Nachdem dein Thread fertig ist wird das lesegerät gestoppt und die Main Methode über Syncronise benachrichtigt.
Willst du den Thread abbrechen ruft du Terminate aund wartest danach bis der Thread sich selbst beendet hat.
Das Intervall von einer Sekunde kannst du natürlich beliebig verkleinern.

Code: Alles auswählen

 
 TLeseThread = class(TThread)
 protected
   procedure Execute; override;
 public
   aDataStream:TStream;
 end;   
 
 procedure TLeseThread.Execute;
begin
// Initialisiere Lesegerät (wenn das initialisieren nicht lange dauert)
while (not Terminated) do
      begin
     // Lese für 1 Sekunde Daten
     aDataStream.Write(meineGelesenenDaten);
      end;
// Stoppe Lesegerät (wenn das stoppen nicht lange dauert)
Self.Synchronize(IchBinFertigMethode);
end;       
 
 
procedure ButtonStop.Click(Object: Sender)
begin
lesethread.Terminate; // startet den Abbruch, kann jetzt noch ca. 1 Sekunde dauern bis der Thread davon mitbekommt.
lesethread.WaitFor// Wartet im Hauptthread bis sich der LeseThread selbst geschlossen hat
end;


Edit:
Zu deinem Dialogbox Problem: Erstelle eine zweite Form und keine normale Dialogbox. Da setzt du dann einfach ein Start Stop Button drauf. Diese Form kannst du nämlich auch einfach wieder Schließen Form2.Close;

Code: Alles auswählen

Signatur := nil;

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

Re: Serielle Daten und Dialogbox mit Abbruch

Beitrag von Mathias »

Was willst du messen ?
Willst du eine ganze Folge von Messungen in ein Array speichern, oder ist dies nur eine Einzel-Messung ?
Dann kommt es darauf an, ob man dem Messgerät einen Steuer-Befehl geben muss, oder ob dieses Endlos sendet.

Ich bin auch gerade an einem Programm schreiben, welches von einem Arduino Endlos Daten empfangt, bis man Stop drückt.

Anstelle von Therads könnte man so ein Problem auch mit einem Timer lösen.
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot

Antworten