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.
Serielle Daten und Dialogbox mit Abbruch
-
- 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
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.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?
Problematisch könnte sein, wie man das Messgerät zum Abbruch bringt um die nächste Übertragung nicht zu stören.
Wenn die Dialogbox eine von dir erstellte Form ist, kann sie auch wieder über die Instanzvariable geschlossen werden werden.
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?
-
- 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
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.
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;
(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;
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;
-
- Beiträge: 6911
- 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
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.
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
Mit Java und C/C++ sehe ich rot