Timer zählt zu langsam
Timer zählt zu langsam
Hallo zusammen,
habe mir letztens ein kleines Programm mit mehreren Timern gebastelt. Das Programm funktioniert soweit, aber jetzt ist mir aufgefallen das der Timer (zählt von 24h abwärts) zu langsam zählt. Bei 3 Minuten macht das ca. 1-2 Sekunden Differenz aus. Weshalb? Ist das Programm mit den vielen Timern überfordert?
Hab es mal Angehängt.
Danke im voraus!
habe mir letztens ein kleines Programm mit mehreren Timern gebastelt. Das Programm funktioniert soweit, aber jetzt ist mir aufgefallen das der Timer (zählt von 24h abwärts) zu langsam zählt. Bei 3 Minuten macht das ca. 1-2 Sekunden Differenz aus. Weshalb? Ist das Programm mit den vielen Timern überfordert?
Hab es mal Angehängt.
Danke im voraus!
Zuletzt geändert von l0lhaxx am Do 4. Feb 2016, 13:25, insgesamt 1-mal geändert.
-
- Beiträge: 152
- Registriert: Mo 3. Feb 2014, 14:07
- OS, Lazarus, FPC: Winux (L 0.9.xy FPC 2.2.z)
- CPU-Target: xxBit
Re: Timer zählt zu langsam
Ein Timer zählt nur wenn er Rechnerzeit bekommt. Du kannst also einen Timer nicht für eine korrekte Uhrzeit benutzen. Die aktuelle Uhrzeit bekommst du mit der Funktion now.
.
-
- Beiträge: 6919
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Timer zählt zu langsam
@l0lhaxx
So wie ich sehe, macht du 16x das gleiche,
Wieso packst du das ganze nicht eine eine Procedure ?
Ist doch einfacher als 16 mal Copy/Paste, vor allem wen du etwas ändern willst, zB. dein fehlerhafter Timer, dann muss du die 16x tun.
So wie ich es sehe brauchst du auch nur einen Timer, anstelle von 16 Stück.
Die Label-Ausgabe geht auch viel einfacher:
So kannst am einfachten die Zeit ausgeben, zeit ist der Start des Ablaufes (zeit := now).
So wie ich sehe, macht du 16x das gleiche,
Wieso packst du das ganze nicht eine eine Procedure ?
Ist doch einfacher als 16 mal Copy/Paste, vor allem wen du etwas ändern willst, zB. dein fehlerhafter Timer, dann muss du die 16x tun.

So wie ich es sehe brauchst du auch nur einen Timer, anstelle von 16 Stück.
Die Label-Ausgabe geht auch viel einfacher:
Code: Alles auswählen
HH := HH + ':';
MM := MM + ':';
Label63.Caption := SS;
Label62.Caption := MM;
Label61.Caption := HH;
// einfacher so_
Labelxx.Caption:= HH + ':' + MM + ':' + SS
// oder direkt:
Labelxx.Caption:=Format('%.2d:%.2d:%.2d',[intHH, intMM, intSS]);
Code: Alles auswählen
var
zeit: TDateTime;
begin
Label1.Caption := TimeToStr(now - zeit);
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: 6079
- Registriert: Do 21. Sep 2006, 07:51
- OS, Lazarus, FPC: iWinux (L 1.x.xy FPC 2.y.z)
- CPU-Target: AVR,ARM,x86(-64)
- Wohnort: Dessau
- Kontaktdaten:
Re: Timer zählt zu langsam
TTimer ist nichts genaues. Er garantiert dir eigentlich nur das er mindestens Interval ms später aufgerufen wird. Wenn dein Programm oder das ganze System gerade ausgelastet ist wird er später aufgerufen. Das ganze passiert über die Message Que des Programms.
W.m.k.A.h.e.m.F.h. -> http://www.gidf.de/
-
- 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: Timer zählt zu langsam
Das müsste aber nicht so sein. Der Durchschnitt der Intervallzeit des MSEgui ttimer ist Mikrosekunden genau. Auf einem Linux System mit moderater Auslastung liegt auch der Jitter im Mikrosekundenbereich. Auf Windows ist der Jitter meist kleiner +-1ms wenn "options to_highres" gesetzt wird.Christian hat geschrieben:TTimer ist nichts genaues. Er garantiert dir eigentlich nur das er mindestens Interval ms später aufgerufen wird.
Realisiert wird dies indem sich das MSEgui Timersystem an der Realtimeclock orientiert und die einzelnen Zeitscheiben entsprechend anpasst.
Re: Timer zählt zu langsam
Und wie soll das funktionieren? Teilweise laufen alle 16 Countdownzeiten gleichzeitig.Mathias hat geschrieben: So wie ich es sehe brauchst du auch nur einen Timer, anstelle von 16 Stück.
Tut mir leid aber ich versteh nicht ganz wie das funktionieren soll?!Mathias hat geschrieben: So kannst am einfachten die Zeit ausgeben, zeit ist der Start des Ablaufes (zeit := now).Code: Alles auswählen
var zeit: TDateTime; begin Label1.Caption := TimeToStr(now - zeit); end;
Und wie kann ich jetzt darauf zurückgreifen?mse hat geschrieben: Der Durchschnitt der Intervallzeit des MSEgui ttimer ist Mikrosekunden genau. AufAuf Windows ist der Jitter meist kleiner +-1ms wenn "options to_highres" gesetzt wird.
-
- 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: Timer zählt zu langsam
Das Verfahren in Lazarus zu integrieren ist vermutlich ziemlich anspruchsvoll. Der Code ist hier:l0lhaxx hat geschrieben:Und wie kann ich jetzt darauf zurückgreifen?
https://gitlab.com/mseide-msegui/mseide ... etimer.pas
Oder du verwendest MSEide+MSEgui.
Re: Timer zählt zu langsam
Es gibt doch auch unter Windows noch einige Möglichkeiten:
Statt der SetTimer Function einen Multimedia Timer nehmen.
Zu XP Zeiten (mmSYSTEM) gab es doch:
timeGetDevCaps, timeBeginPeriod, EndPeriod
timeSetEvent, timeKillEvent
Höhere Windows Versionen haben da doch sicher auch was anzubieten!?
Ansonsten vielleicht ein eigener Thread + Sleep oder SleepEX
oder WaitableTimerAPI
oder QueueTimers (CreateTimerQueueTimer)
oder QueryPerformance Counter, QueryPerformanceFrequency
oder ab Windows 8: GetSystemTimePreciseAsFileTime
Vielleicht kann man damit ja was brauchbares bauen...
Statt der SetTimer Function einen Multimedia Timer nehmen.
Zu XP Zeiten (mmSYSTEM) gab es doch:
timeGetDevCaps, timeBeginPeriod, EndPeriod
timeSetEvent, timeKillEvent
Höhere Windows Versionen haben da doch sicher auch was anzubieten!?
Ansonsten vielleicht ein eigener Thread + Sleep oder SleepEX
oder WaitableTimerAPI
oder QueueTimers (CreateTimerQueueTimer)
oder QueryPerformance Counter, QueryPerformanceFrequency
oder ab Windows 8: GetSystemTimePreciseAsFileTime
Vielleicht kann man damit ja was brauchbares bauen...
Re: Timer zählt zu langsam
Welche ist die schnellere Variante und gibt es irgendwo eine Anleitung dazu?
-
- Beiträge: 6919
- Registriert: Do 2. Jan 2014, 17:21
- OS, Lazarus, FPC: Linux (die neusten Trunk)
- CPU-Target: 64Bit
- Wohnort: Schweiz
Re: Timer zählt zu langsam
Dies sollte als Gedankenstütze reichen:Und wie soll das funktionieren? Teilweise laufen alle 16 Countdownzeiten gleichzeitig.
Code: Alles auswählen
type
TMyTimer = record
start: TDateTime;
aktiv: boolean;
end;
var
MyTimer: array[0..1] of TMyTimer;
{ TForm1 }
procedure TForm1.FormCreate(Sender: TObject);
var
i: integer;
begin
Button1.Caption := 'Start M1'; // Kann im Obj-Inspector gemacht werden
Button2.Caption := 'Start M2';
Button3.Caption := 'Reset M1';
Button4.Caption := 'Reset M2';
for i := 0 to Length(MyTimer) - 1 do begin
MyTimer[i].aktiv := False;
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
MyTimer[0].aktiv := True;
MyTimer[0].start := Now;
end;
procedure TForm1.Button3Click(Sender: TObject);
begin
MyTimer[1].aktiv := True;
MyTimer[1].start := Now;
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
MyTimer[0].aktiv := False;
end;
procedure TForm1.Button4Click(Sender: TObject);
begin
MyTimer[1].aktiv := False;
end;
procedure TForm1.Timer1Timer(Sender: TObject);
begin
if MyTimer[0].aktiv then begin
Label1.Caption := TimeToStr(Now - MyTimer[0].start);
end else begin
Label1.Caption := '-';
end;
if MyTimer[1].aktiv then begin
Label2.Caption := TimeToStr(Now - MyTimer[1].start);
end else begin
Label2.Caption := '-';
end;
end;
Das Klick-Ereignis brauchst du auch nur einmal, welcher Button das gedrückt wurde, kannst mit TButton(Sender).Tag abfragen.
Tönt schlimmer als es ist, dafür muss du nicht alles 16x kopieren.
Der Vorteil, wen zB. das Label eine andere Farbe oder Schrift braucht, dann muss es nur 1x geänder werden.
Ich hoffe ich kann dir helfen damit.

Mit Lazarus sehe ich grün
Mit Java und C/C++ sehe ich rot
Mit Java und C/C++ sehe ich rot