[gelöst] Consolenanwendung in Gui wandeln
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
[gelöst] Consolenanwendung in Gui wandeln
Guten Abend zusammen,
ich versuche gerade verzweifelt eine Konsolenanwendung
in ein Gui Programm umzubauen.
Die Hardware ist von Tinkerforge und dafür gibt's
Bindings für Delphi/Lazarus und Beispiele.
Problem, die Beispiele sind alle nur für Konsolenanwendungen.
Ich krieg das nicht in eine primitive Guianwendung gepackt.
hier das Beispiel: https://www.tinkerforge.com/de/doc/Soft ... elphi.html
Die Hardware besteht u.a. aus 4 digitalen Eingänge.
Man kann laut Beispiel hier einen Callback registrieren und da hörts leider auf.
Kann mir jemand zeigen wie das zu händeln ist?
Im unteren Beispiel vom Link "Interrupt" ist das für Apptype Console beschrieben und funktioniert auch.
Aber wie registriere ich einen Interrupt Callback in einer Guianwendung?
Der soll aufgerufen werden wenn sich einer der 4 Eingänge ändert.
Versuchshalber hab ich nur einen Button auf dem Formular gelegt, der Off bzw. On anzeigen soll.
Je nach Logiklevel vom digitalen Eingang.
Für Hilfe wäre ich dankbar
Grüße und Danke im Vorraus
NoCee
ich versuche gerade verzweifelt eine Konsolenanwendung
in ein Gui Programm umzubauen.
Die Hardware ist von Tinkerforge und dafür gibt's
Bindings für Delphi/Lazarus und Beispiele.
Problem, die Beispiele sind alle nur für Konsolenanwendungen.
Ich krieg das nicht in eine primitive Guianwendung gepackt.
hier das Beispiel: https://www.tinkerforge.com/de/doc/Soft ... elphi.html
Die Hardware besteht u.a. aus 4 digitalen Eingänge.
Man kann laut Beispiel hier einen Callback registrieren und da hörts leider auf.
Kann mir jemand zeigen wie das zu händeln ist?
Im unteren Beispiel vom Link "Interrupt" ist das für Apptype Console beschrieben und funktioniert auch.
Aber wie registriere ich einen Interrupt Callback in einer Guianwendung?
Der soll aufgerufen werden wenn sich einer der 4 Eingänge ändert.
Versuchshalber hab ich nur einen Button auf dem Formular gelegt, der Off bzw. On anzeigen soll.
Je nach Logiklevel vom digitalen Eingang.
Für Hilfe wäre ich dankbar
Grüße und Danke im Vorraus
NoCee
Zuletzt geändert von NoCee am Fr 15. Jun 2018, 21:25, insgesamt 2-mal geändert.
-
- Beiträge: 6918
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Consolenanwendung in Gui wandeln
Meist du so was ?
Beim Klicken auf den Button, wird eine Ausgabe auf das Label ausgegeben.
Beim Klicken auf den Button, wird eine Ausgabe auf das Label ausgegeben.
Code: Alles auswählen
procedure TForm1.Button1Click(Sender: TObject);
var
valueMask: word;
begin
{ Create IP connection }
ipcon := TIPConnection.Create;
{ Create device object }
idi4 := TBrickletIndustrialDigitalIn4.Create(UID, ipcon);
{ Connect to brickd }
ipcon.Connect(HOST, PORT);
{ Don't use device before ipcon is connected }
{ Get current value as bitmask }
valueMask := idi4.GetValue;
Label1.Caption := Format('Value Mask: %d', [valueMask]);
// WriteLn(Format('Value Mask: %d', [valueMask]));
// WriteLn('Press key to exit');
// ReadLn;
ipcon.Destroy; { Calls ipcon.Disconnect internally }
end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Re: Consolenanwendung in Gui wandeln
Ne,
die Abfrage soll ja automatisch laufen.
So wie du es geschrieben hast, wäre es vom Link das obere Beispiel.
Als Einzelabfrage.
Das müßte ich dann ständig pollen. Oder über einen Timer machen.
Das geht aber irgendwie mit Registrierung eines Callbacks.
Wenn sich einer der Eingänge ändert wird dieser ohne mein Zutun aufgerufen.
Den Button hab ich nur um darauf entweder Off oder On anzuzeigen.
Auf dem Formular wird der Button nicht betätigt (reine Anzeige).
So wie ich das verstanden habe, kann ich irgendwie der Firmware sagen
melde dich erst wenn du einen Wechsel der Zustände am Eingang erkennst.
Dann ruft es den Callback "InterruptCB" auf mit dem ich dann was anfangen kann.
Tinkerforge beschreibt das über den Callback zum machen als den besseren Weg.
Was ich noch nachvollziehen kann.
Aber die paar Zeilen in ein Gui zu bekommen halt nicht mehr.
Gruß
NoCee
die Abfrage soll ja automatisch laufen.
So wie du es geschrieben hast, wäre es vom Link das obere Beispiel.
Als Einzelabfrage.
Das müßte ich dann ständig pollen. Oder über einen Timer machen.
Das geht aber irgendwie mit Registrierung eines Callbacks.
Wenn sich einer der Eingänge ändert wird dieser ohne mein Zutun aufgerufen.
Den Button hab ich nur um darauf entweder Off oder On anzuzeigen.
Auf dem Formular wird der Button nicht betätigt (reine Anzeige).
Code: Alles auswählen
{ Callback procedure for interrupt callback }
procedure TExample.InterruptCB(sender: TBrickletIndustrialDigitalIn4;
const interruptMask: word; const valueMask: word);
begin
WriteLn(Format('Interrupt Mask: %d', [interruptMask]));// hier will ich den Button ändern (off/on)
WriteLn(Format('Value Mask: %d', [valueMask])); // die 3 Zeilen zu ändern krieg ich hin
WriteLn('');
end;
//das gehört auch noch irgendwo hin
{ Register interrupt callback to procedure InterruptCB }
idi4.OnInterrupt := {$ifdef FPC}@{$endif}InterruptCB;
melde dich erst wenn du einen Wechsel der Zustände am Eingang erkennst.
Dann ruft es den Callback "InterruptCB" auf mit dem ich dann was anfangen kann.
Tinkerforge beschreibt das über den Callback zum machen als den besseren Weg.
Was ich noch nachvollziehen kann.
Aber die paar Zeilen in ein Gui zu bekommen halt nicht mehr.
Gruß
NoCee
-
- Beiträge: 6918
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Consolenanwendung in Gui wandeln
Auf diese Art sollte es gehen, habe den Code blind getippt.
Code: Alles auswählen
TForm1 = class(TForm)
procedure FormCreate(Sender: TObject);
procedure FormDestroy(Sender: TObject);
private
ipcon: TIPConnection;
idi4: TBrickletIndustrialDigitalIn4;
procedure InterruptCB(Sender: TBrickletIndustrialDigitalIn4; const interruptMask: word; const valueMask: word);
public
end;
...
const
HOST = 'localhost';
PORT = 4223;
UID = 'XYZ'; { Change XYZ to the UID of your Industrial Digital In 4 Bricklet }
procedure TForm1.FormCreate(Sender: TObject);
begin
{ Create IP connection }
ipcon := TIPConnection.Create;
{ Create device object }
idi4 := TBrickletIndustrialDigitalIn4.Create(UID, ipcon);
{ Connect to brickd }
ipcon.Connect(HOST, PORT);
{ Don't use device before ipcon is connected }
{ Register interrupt callback to procedure InterruptCB }
idi4.OnInterrupt := @InterruptCB;
{ Enable interrupt on pin 0 }
idi4.SetInterrupt(1 shl 0);
end;
procedure TForm1.FormDestroy(Sender: TObject);
begin
idi4.Free;
ipcon.Free;
end;
procedure TForm1.InterruptCB(Sender: TBrickletIndustrialDigitalIn4;
const interruptMask: word; const valueMask: word);
begin
ShowMessage('Ausgelöst');
end;
Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Re: Consolenanwendung in Gui wandeln
Danke für die schnelle Antwort.
Das sieht optisch schon mal richtig gut aus.
So in der Art hab ich mir das vorgestellt, bin aber in der Ecke noch ziemlicher Laie
als das ich das selber so hinbekommen würde.
Bin gespannt obs auch tut. Zumindest hilfts mal ein ganzes Stück weiter.
Komm aber erst nächste Woche zum Testen.
Ich hab mir noch alle Beispiele für Delphi/Lazarus auf der Seite von Tinkerforge angeschaut.
Alle nur für Konsole. Zwar schön aufwändig gemacht, aber hilft mir halt nicht.
Aber jetzt könnte es ja endlich klappen.
Danke nochmals für die Hilfe
und ein schönes Wochenende
NoCee
Das sieht optisch schon mal richtig gut aus.
So in der Art hab ich mir das vorgestellt, bin aber in der Ecke noch ziemlicher Laie
als das ich das selber so hinbekommen würde.
Bin gespannt obs auch tut. Zumindest hilfts mal ein ganzes Stück weiter.
Komm aber erst nächste Woche zum Testen.
Ich hab mir noch alle Beispiele für Delphi/Lazarus auf der Seite von Tinkerforge angeschaut.
Alle nur für Konsole. Zwar schön aufwändig gemacht, aber hilft mir halt nicht.
Aber jetzt könnte es ja endlich klappen.
Danke nochmals für die Hilfe
und ein schönes Wochenende
NoCee
- kupferstecher
- Beiträge: 433
- Registriert: Do 17. Nov 2016, 11:52
Re: Consolenanwendung in Gui wandeln
Wenn ich das richtig sehe, ist dir eigentlich nur unklar, wo die Initialisierungen hingehoeren, oder?
*Einmal - wie Mathias vorgeschlagen hat - in das OnCreate-Ereignis der Form. Die kannst du im Objektinspektor anlegen.
*Eine andere geeignete Stelle ist in der Programmdatei '.lpr', direkt vor Application.Run. Dort ruft man zweckmaessigerweise eine Funktion auf, in der man alle Initialisierungen buendelt.
*Dann gibt es noch die INITIALIZATION (und FINALIZATION) -Abschnitte in den Units. Das ist ein Sprachfeature und wird damit noch vor der Erzeugung der Form(s) aufgerufen. Ist dadurch fuer visuelle Komponenten aber ungeeignet (Owner und Parent koennen nicht gesetzt werden).
*Einmal - wie Mathias vorgeschlagen hat - in das OnCreate-Ereignis der Form. Die kannst du im Objektinspektor anlegen.
*Eine andere geeignete Stelle ist in der Programmdatei '.lpr', direkt vor Application.Run. Dort ruft man zweckmaessigerweise eine Funktion auf, in der man alle Initialisierungen buendelt.
*Dann gibt es noch die INITIALIZATION (und FINALIZATION) -Abschnitte in den Units. Das ist ein Sprachfeature und wird damit noch vor der Erzeugung der Form(s) aufgerufen. Ist dadurch fuer visuelle Komponenten aber ungeeignet (Owner und Parent koennen nicht gesetzt werden).
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Re: Consolenanwendung in Gui wandeln
Guten Abend zusammen,
ich hab das in der Art in mein Prog eingebaut und es funzt einwandfrei.
Nur hab ich jetzt ein Problem mit einem Timer.
Den hab ich auf mein Formular gepackt und entsprechend gestartet.
Aber da passiert nix.
Ich hab versuchsweise noch im MyTimer.OnStart und OnStop noch was reingeschrieben.
Diese Events kommen einwandfrei.
Aber die Sekunde läuft nicht ab, bzw OnTimer kommt nicht.
Was ich dann herrausgefunden habe ist das wenn ich mir eine Variable im InteruptCB auf true setze mit der ich
wo anders den Timer starte, zB hab ich einen Sekundentakt, wenn ich hier reinschreibe
if MyVariable=true then MyTimer.Enable:=true;
und meine Variable dann auf false setze, läuft der Timer ganz wie gewohnt.
Warum kommen OnStart und OnStop vom Timer aber der OnTimer nicht?
Wie krieg ich das richtig zum Laufen ohne den Umweg mit einer Variablen?
Vielen Dank schon mal im Vorraus
Gruß
NoCee
ich hab das in der Art in mein Prog eingebaut und es funzt einwandfrei.
Nur hab ich jetzt ein Problem mit einem Timer.
Den hab ich auf mein Formular gepackt und entsprechend gestartet.
Aber da passiert nix.
Code: Alles auswählen
procedure TForm1.InterruptCB(Sender: TBrickletIndustrialDigitalIn4; const interruptMask: word; const valueMask: word);
begin
ShowMessage('Ausgelöst');
MyTimer.enabled:=true;
end;
Diese Events kommen einwandfrei.
Aber die Sekunde läuft nicht ab, bzw OnTimer kommt nicht.
Was ich dann herrausgefunden habe ist das wenn ich mir eine Variable im InteruptCB auf true setze mit der ich
wo anders den Timer starte, zB hab ich einen Sekundentakt, wenn ich hier reinschreibe
if MyVariable=true then MyTimer.Enable:=true;
und meine Variable dann auf false setze, läuft der Timer ganz wie gewohnt.
Warum kommen OnStart und OnStop vom Timer aber der OnTimer nicht?
Wie krieg ich das richtig zum Laufen ohne den Umweg mit einer Variablen?
Vielen Dank schon mal im Vorraus
Gruß
NoCee
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Re: Consolenanwendung in Gui wandeln
Jou, nachdem mir keiner helfen will
Ich vermute daß das Problem an dem Callback im Zusammenhang mit einem TTimer liegt.
Beim Pupillen wundlesen hab ich gefunden daß ein TTimer nicht threadsave sei.
Da kam das Gefühl auf, daß der Callback nicht zum Mainthread gehört es also hier Probleme geben kann.
Da hab ich dann einen Versuch mit einem TFPTimer gestartet und siehe da, es funktioniert.
Es wäre schön, wenn mir das jetzt noch jemand schlüssig erklären könnte.
Wo ist der Unterschied zwischen TTimer und TFPTimer?
Ansonsten ist das Thema damit erledigt.
Gruß und schönes Wochenende
NoCee

Ich vermute daß das Problem an dem Callback im Zusammenhang mit einem TTimer liegt.
Beim Pupillen wundlesen hab ich gefunden daß ein TTimer nicht threadsave sei.
Da kam das Gefühl auf, daß der Callback nicht zum Mainthread gehört es also hier Probleme geben kann.
Da hab ich dann einen Versuch mit einem TFPTimer gestartet und siehe da, es funktioniert.
Es wäre schön, wenn mir das jetzt noch jemand schlüssig erklären könnte.
Wo ist der Unterschied zwischen TTimer und TFPTimer?
Ansonsten ist das Thema damit erledigt.
Gruß und schönes Wochenende
NoCee
-
- Lazarusforum e. V.
- Beiträge: 3178
- Registriert: Di 22. Jul 2008, 19:27
- OS, Lazarus, FPC: Lazarus: SVN; FPC: svn; Win 10/Linux/Raspbian/openSUSE
- CPU-Target: 32bit x86 armhf
- Wohnort: Köln
- Kontaktdaten:
Re: Consolenanwendung in Gui wandeln
TTimer wird vom Widgetset bereitgestellt und ist daher wie alle Widgetset-Dinge nicht threadsafe. Alles was das Widgetset betrifft (=GUI) gehört immer in den Mainthread. TTimer wird also von extern im Mainthread benachrichtigt und bearbeitet.NoCee hat geschrieben:Wo ist der Unterschied zwischen TTimer und TFPTimer?
TFPTimer ist hingegen unabhängig von einem Widgetset implementiert. Die Komponente stellt hier lediglich eine Schnittstelle zum eigentlichen Timer der Klasse TFPTimerDriver dar. Deine Anwendung kann hier für verschiedene Zwecke verschieden Timer-Driver nutzen; das Widgetset als Quelle zu nutzen wäre also auch möglich. Die Standardimplementierung TFPThreadedTimerDriver nutzt einen eigenen Thread pro Timer für das Timing (Warten zwischen den Intervallen). Die eigentliche Ausführung des Event-Codes wird dann aber per Synchronize() an den Mainthread übergeben. D.h. selbst wenn du den Timer aus einem Thread heraus startest, wird der Event-Code immer noch im Mainthread und nicht im Timer-startenden Thread ausgeführt.
MfG Socke
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
Ein Gedicht braucht keinen Reim//Ich pack’ hier trotzdem einen rein
-
- Beiträge: 174
- Registriert: Do 3. Mär 2011, 21:34
- OS, Lazarus, FPC: WinXp/7/10 Opensuse13.2/Leap15.3 (L 2.2.0 FPC 3.2.2 )
- CPU-Target: Intel 32/64Bit, ARM9
- Wohnort: Ulm
Re: [gelöst] Consolenanwendung in Gui wandeln
Vielen Dank für die Antwort.
Der Timer ist genau das was ich gerade brauche.
Nur noch aus Neugier:
Wenn ich jetzt in einer Gui Anwendung einen Timer innerhalb eines separaten Threads bräuchte,
wie könnte man das lösen?
Gruß
NoCee
Der Timer ist genau das was ich gerade brauche.
Nur noch aus Neugier:
Wenn ich jetzt in einer Gui Anwendung einen Timer innerhalb eines separaten Threads bräuchte,
wie könnte man das lösen?
Gruß
NoCee