Timing zu hoch...

Für alles, was in den übrigen Lazarusthemen keinen Platz, aber mit Lazarus zutun hat.
Antworten
Benutzeravatar
Maik81SE
Beiträge: 323
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.4 FPC 3.2.2)
CPU-Target: x86-64; avr
Wohnort: Lübeck
Kontaktdaten:

Timing zu hoch...

Beitrag von Maik81SE »

Moin @ll,

vorweg euch allen einen entspannten 2ten Advent.

in einem meiner aktuellen Projekten habe ich auf mir aktuell unbekannten Gründen ein Problem mit dem TTimer.

Aufgabe:
ich will eine Art Lauflicht erstellen, welches aktuell aus 10 x 40 Pixel besteht.
Nominell keine große Sache, würde ich meinen, aber aus einem mir unerklärlichen Grund braucht mein Timer 2 Sekunden, für einen Durchlauf, obgleich der Intervall auf 250ms eingestellt ist. :shock:

wenn ich mir die Funktion anschaue, welche in der Summe nur eine aktive Schleife fährt wundert es mich doch schon arg, das ein Programm für diesen Durchlauf so arg lange braucht.

Code: Alles auswählen

procedure TForm1.Timer1Timer(Sender: TObject);
var
  a, b                            : byte;
begin
  if bMatrix.first then begin
    for a := 1 to 10 do begin
      if bMatrix._on[bMatrix.b, a] then
        Matrix[40, a].State       := lsOn
      else Matrix[40, a].State    := lsDisabled;
      bMatrix.first               := false;
      end;
    end else begin
      inc(bMatrix.b);
      for a := 2 to 8 do begin
        for b := 1 to 39 do
          // eine reihe vorrücken
          Matrix[b, a].State      := Matrix[b + 1, a].State
        if bMatrix._on[bMatrix.b, a] then
          Matrix[40, a].State     := lsOn
        else
          Matrix[40, a].State     := lsDisabled;
        end;
      end;
  dec(bMatrix.c);
  if bMatrix.b = 40 then
    Timer1.Enabled                := false;
end;
verwendete Komponenten in dem Aufruf sind

Code: Alles auswählen

    // Sichtbare Matrix
    Matrix                   : array[1..40, 1..10] of TAdvLed;
    // Backup Matrix, nur für Lauflicht funktion
    bMatrix                  : record
      _on                    : array[1..40, 1..10] of boolean;
      b, c                   : byte;
      first                  : boolean;
      end;
also abgesehen von den beiden For-Schleifen sehe ich nichts, was so viel zeit Fressen sollte und selbst da wird nur der State von der zB Matrix[37, a] auf Matrix[36, a], Matrix[38, a] auf Matrix[37, a], Matrix[39, a] auf Matrix[38, a] kopiert und der State von Matrix[40, a] entsprechend bMatrix._on[b, a] gesetzt.

Sieht jemand von euch gegebfalls etwas, was ich dabei übersehe?

Danke für eure Aufmerksamkeit und einen schönen Sonntag euch allen.

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.4 FPC 3.2.2);

Warf
Beiträge: 2079
Registriert: Di 23. Sep 2014, 17:46
OS, Lazarus, FPC: Win10 | Linux
CPU-Target: x86_64

Re: Timing zu hoch...

Beitrag von Warf »

Was ist TAdvLed und was passiert beim Setter von State? Wenn das einen redraw triggert hast du da dein Problem

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6512
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Timing zu hoch...

Beitrag von af0815 »

Ich würde den Timer1 gleich in der ersten Zeile disablen und in der letzen Zeile entscheiden ob ich den Timer wie aktiviere.

Wenn du sowas wie ein Lauflicht machen willst, dann sollte die Berechnung für einen Zyklus im Timer gemacht werden, so wie es aussieht fährst du die ganzen Schleifen auf einmal ab - wie soll das dann an die Leds (oder was auch immer) kommen ? Damit hast du so alle 250ms einen Zyklus und der dauert dann nur kurz. Wie ein Schrittschaltwerk in der SPS Programmierung.
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

Benutzeravatar
Maik81SE
Beiträge: 323
Registriert: Fr 30. Sep 2011, 14:07
OS, Lazarus, FPC: Debian 12 (L 3.4 FPC 3.2.2)
CPU-Target: x86-64; avr
Wohnort: Lübeck
Kontaktdaten:

Re: Timing zu hoch...

Beitrag von Maik81SE »

Warf hat geschrieben: So 8. Dez 2024, 12:44 Was ist TAdvLed und was passiert beim Setter von State? Wenn das einen redraw triggert hast du da dein Problem
kommt aus dem Komponente https://sourceforge.net/projects/lazaru ... rialstuff/

State definiert den Zustand der LED, welche wie folgt definiert ist,

Code: Alles auswählen

TLedState = (lsDisabled, lsOff, lsOn);
Aber wenn ich mir anschaue, was alles dahinter stecke, könnte dies der Grund sein.
Setzen der LED von Disabled auf ON, darauf wird das Bild anscheinend neu geladen. :shock: :shock:
Schaut wohl so aus, das ich mir entweder eine Low-Level, LED suche, um dies in meinem Formular anzuzeigen, oder ich schreibe mir diese selber und nur auf die benödigten Routinen.
af0815 hat geschrieben: So 8. Dez 2024, 12:45 Ich würde den Timer1 gleich in der ersten Zeile disablen und in der letzen Zeile entscheiden ob ich den Timer wie aktiviere.

Wenn du sowas wie ein Lauflicht machen willst, dann sollte die Berechnung für einen Zyklus im Timer gemacht werden, so wie es aussieht fährst du die ganzen Schleifen auf einmal ab - wie soll das dann an die Leds (oder was auch immer) kommen ? Damit hast du so alle 250ms einen Zyklus und der dauert dann nur kurz. Wie ein Schrittschaltwerk in der SPS Programmierung.
Leider ändert dies nichts an den 2 Sekunden vom Timer eintritt bis zum ende. :(

Edit
Habe gerade mal die Komponente TAdvLED durch und eine TCheckBox ersetzt und nun stimmt das Timing auch so, wie ich es mir wünsche. :D

Merke!
Keine Komponenten im Timer änder, welche auf größere Datenmengen zurückgreifen (zB Glyph, Bitmap)

Code: Alles auswählen

label.caption:= 'gnublin.no-ip.info'
Debian 12 (L 3.4 FPC 3.2.2);

CCRDudeLaz
Beiträge: 52
Registriert: Do 25. Jan 2024, 08:33
OS, Lazarus, FPC: Win/macOS (L trunk FPC trunk)
CPU-Target: 32+64

Re: Timing zu hoch...

Beitrag von CCRDudeLaz »

Wenn man einen Timer benutzt für etwas, das flüssig wirken soll, ist es oft praktischer, den Zustand abhängig von der gemessenen vergangenen Zeit zu berechnen und weiterzuverarbeiten (hier auszugeben), anstatt sich darauf verlassen, dass der eigene Code immer dieselbe Laufzeit hat, zudem er ja gglfs. je nach Hardware unterschiedlich schnell ausgeführt wird.

Benutzeravatar
af0815
Lazarusforum e. V.
Beiträge: 6512
Registriert: So 7. Jan 2007, 10:20
OS, Lazarus, FPC: FPC fixes Lazarus fixes per fpcupdeluxe (win,linux,raspi)
CPU-Target: 32Bit (64Bit)
Wohnort: Burgenland
Kontaktdaten:

Re: Timing zu hoch...

Beitrag von af0815 »

Der Timer ist sowieso so zu sehen, das nur mindestens die Zeit die man einstellt als untere Grenze eingehalten wird. In den PCs hat man ohne Vorkehrungen ja keine Echtzeit. Ja es gibt eigen RT-Kernel (RT-RealTime), da ist das Verhalten dann deterministisch.

Beispiel:
https://github.com/remusmp/rpi-rt-kernel
https://ubuntu.com/engage/an-introducti ... time-linux
Blöd kann man ruhig sein, nur zu Helfen muss man sich wissen (oder nachsehen in LazInfos/LazSnippets).

schoschy
Beiträge: 47
Registriert: Di 18. Okt 2022, 15:46

Re: Timing zu hoch...

Beitrag von schoschy »

Das mit der Überprüfung anhand der vergangenen Zeit macht man in Unity auf jeden fall so.
Da überprüft man zwar beim neu laden des Frames, aber jeder PC ist unterschiedlich schnell, selbst mit baugleicher Hardware, weshalb alles andere nicht funktioniert.

Viel hab ich in Unity zwar nicht gemacht, aber das hab ich noch im Hinterkopf :)

Antworten