Timer in Module (Kernel.TimerPoolEx.SetInterval)

Hallo zusammen.

Ich habe mich am Wochenende ein wenig weiter mit der Modulentwicklung beschäftigt.
Ich wollte mein Modul erweitern und brauchte dafür einen Timer, nach längeren versuchen einen API Timer in einer Hilfsklasse umzusetzen
[ mit SetTimer, einer WndProc und AllocateHWnd ]

  • was aus mir nicht begreiflichen Gründen gescheitert ist!

Deshalb habe ich nochmal die 3 Beispiel Pojekte die ich damals von Paresy bekommen habe durchsucht und herausgefunden, das IPS bereits Timer zur verfügungstellt.
Ich habe mich also daran gemacht aus dem UOneWire-Modul die Timerbefehle zu portieren.
Aber leider klappt das auch nicht. :confused:

Ich habe mal alle relvanten Stellen herausgeschrieben:

 TIPSMyModule = class(TIPSModuleObject,
                     IIPSOneWire,
                     IIPSTMEXClient,
                     IIPSModule)
  private
	 fTimer          : TTimerID;
  .
	.
	.
  //--- Private Procedures/Functions
  procedure UpdateEvent; stdcall;
  procedure StartTimer;
  constructor Create(IKernel: IIPSKernel; InstanceID: TInstanceID); override;
  destructor  Destroy; override;
  .
	.
  .
implementation

.
.
.

//------------------------------------------------------------------------------
constructor TIPSMyModule.Create(IKernel: IIPSKernel; InstanceID: TInstanceID);
begin
 inherited;

 fTimer := fKernel.TimerPoolEx.RegisterTimer('UpdateEvent', fInstanceID, UpdateEvent);
 .
 .
 .
 //Load/Apply Settings
 ConstructorPostProcess;
 
end;

//------------------------------------------------------------------------------
destructor  TIPSMyModule.Destroy;
begin

 //Save Settings
 DestructorPreProcess;

 //Cleanup custom Object
 if fTimer <> 0 then
  fKernel.TimerPoolEx.UnregisterTimer(fTimer);
 
 .
 .
 .
 
 inherited;

end;

//------------------------------------------------------------------------------
procedure TIPSMyModule.StartTimer;
begin
 fKernel.TimerPoolEx.SetInterval(fTimer, 1000);
end;


//------------------------------------------------------------------------------
procedure TIPSMyModule.UpdateEvent;
begin
 fKernel.LogMessage(KL_MESSAGE, 0, 'MyModule', '*****Timer******');
end;

.
.
.

end.

Es wird nie eine Message geloggt => Timer läuft nicht.

Hab ich was vergessen/falsch gemacht?
Sehe ich richtig das der Timer mit SetInerval automatisch gestartet wird oder muss ich den noch mal von Hand starten?
Wie Stoppe ich den Timer wieder? (muss ich Ihn das Interval auf „0“ setzen oder den Timer „unregistern“).

Generell finde ich es recht schwierig Module zu entwickeln ohne einen größeren Blick auf den „Rahmen“ zu haben. Gibt es mitlerweile eine kleine Funktions/Klassen Übersicht die einem zeigt was alles möglich ist? Oder mehr Beispielprogramme das man sich das selbst erschließen kann?

Vielen Dank für Eure Hilfe,

MfG Huelke

1000 <- Das sind 1000 Sekunden

Wenn du die Konsole startest, kannst du über Ansicht hinzufügen -> Timer Informationen alle Timer sehen und dort sollte dein Timer samt status und nächster Ausführung drin sein.

Mehr Doku gibt es zum SDK leider nicht. Du kannst gerne Fragen und ich werde versuchen so gut wie Möglich darauf zu antworten.

paresy

PS: AllocateHWnd klappt nicht, weil du innerhalb der DLL kein gültiges sichtbares Fenster erzeugen kannst.
PPS: TTimer solltest du nicht verwenden, da es nicht Threadsafe ist und definitiv IPS crashen würde.
PPPS: Falls du Intervall <1 Sek brauchst musst die SetIntervalEx Funktion nutzen, dessen Parameter auch „Millisekunden“ annimmt.

kleine Funktions/Klassen Übersicht

Wenn du dir UIPSTypes.pas durchliest, dann hast du die komplette Funktionsreferenz.
Und im Prinzip findest du davon 90% in der Doku als PHP Befehle wieder.

paresy

Hi Paresy,
Vielen vielen Dank - echt Klasse ein Tipp von Dir und alles Läuft. :smiley:

Das mit der UIPSTypes.pas ist mir gestern auch aufgefallen, wenn ich die in mein Projekt einbinde bekomme ich sogar eine Autovervollständigung - dann steht da sogar bei der SetIntveral: timer_id, seconds :wink:

Ja muss man alles wissen :stuck_out_tongue: dank Dir noch mal ich denke jetzt nerv ich nur noch halb so oft. Das Problem mit der Vervielfältigung der Variablen hab ich dank deiner Hilfe auch gefunden. Hatte in der Tat ein inherited vergessen/gelöscht (in der SaveSettings).

THX
Huelke

Und da is er schon wieder :wink:

Also es hat alles super geklappt, das Modul läuft unter 2.04 besser als ich gedacht hatte, war ja nur ne „Idee“ die sich aber sehr gut umsetzen ließ.

Und dennoch.
Da ich nun endlich meine Supskription verlängert hab und Werner mir mitgeteilt hat das es unter 2.1 nicht so doll läuft - hab ich nun auch auf 2.1 Upgedated.

Und er hat recht. Der Timer steuert z.B. einen Farbverlauf eines RGB Controllers - und was unter 2.04 noch super flüssig und chick war, harkt jetzt im halb Sekunden Takt.

Nun erstmal der „Schocker“: Ich führe den Timer mit einem 40 ms Interval aus.
Diesen Wert hab ich unter 2.04 als den Maximalwert ermittelt, bei dem das Ding nicht ruckelt (25 mal pro Sekunde).
Und wie gesagt: In 2.04 war alles dufte, hätte sogar noch schneller sein können. Nichts wurde gestörrt und IPS lief flüssig wie immer.

Das (unerfreuliche) Ergebnis meiner Recherche: Der Timer ist unter 2.1 unregelmäßig… Genauer gesagt: regelmäßig unregelmäßig :wink:
Er schlägt immer erst 6 mal im Abstand von 47ms! zu dann „wartet“ er 265ms !!! macht wieder 2 Takte im Abstand von 47 ms… und
nach 453ms!!! wiederholt sich das Ganze.

2 Riesen Lücken in denen nichts passiert
…und schon Harkt alles und sieht nimmer schön (=unbrauchbar) aus.

10.09.2009 01:55:51.231 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:51.278 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:51.325 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:51.372 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:51.419 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:51.466 |     0 | MESSAGE | ChromoflexRC *timer* | hit

10.09.2009 01:55:51.731 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:51.778 |     0 | MESSAGE | ChromoflexRC *timer* | hit

10.09.2009 01:55:52.231 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:52.278 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:52.325 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:52.372 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:52.419 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:52.466 |     0 | MESSAGE | ChromoflexRC *timer* | hit

10.09.2009 01:55:52.731 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:52.778 |     0 | MESSAGE | ChromoflexRC *timer* | hit

10.09.2009 01:55:53.231 |     0 | MESSAGE | ChromoflexRC *timer* | hit
10.09.2009 01:55:53.278 |     0 | MESSAGE | ChromoflexRC *timer* | hit

usw...

Für meinen Letzten Test habe ich die OnTimer Funktion bis auf die Log Zeile reduziert - und hatte sogar noch weniger „Hits“:
4-6 Timer Events pro Sekunde (statt 25) :frowning:

Nun sagt mir Bitte das die 2.1 Version die Timer nicht irgendwie beschränkt und das sich das Lösen lässt.
Die neuen Möglichkeiten des Chromoflex Moduls sind nämlich zu edel als das sie mit der Version 2.05 von IPS begraben werden sollten. :rolleyes:

Danke Vielmals
THX
Huelke

P.S.
Hab ein MiniModul „TimerTest“ geschrieben. Einzige aufgabe: einen Timer mit beliebigem Interval(ms) Starten und die Hits loggen (mit Berechnung der Zeit seit dem letzten Event)

TimerTest_Start(29326  /*[TimerTest]*/,1000); // Starte Timer mit 1000ms Interval
TimerTest_Stop(29326  /*[TimerTest]*/);// Timer anhalten

Ergebnis: selbst bei größeren Intervallen von einer Sekunde schwankt der Timer zwischen 1000 und 1600 ms! Das is echt ne Menge.
Wenns euch hilft: Das Modul ist angefügt - zum Testen.

TimerTest.rar (238 KB)