Ankündigung

Einklappen
Keine Ankündigung bisher.

Frage zu systemstart()

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [Firmware] Frage zu systemstart()

    Guten Morgen,

    ich glaube ich hab das Verhalten von systemstart() nach all den Jahren doch noch nicht verstanden. Ich hatte ursprünglich folgenden Code:

    Code:
    LOS = AUS
    if after(systemstart(),  5000u64) then LOS = EIN endif
    if after(systemstart(),  5500u64) then LOS = AUS endif
    
    ....
    interneVariable=0b01
    if (change(interneVariable) or LOS) and interneVariable then
    if (change(interneVariable) or LOS) and !interneVariable then
    ​​
    Erwartet hätte ich, dass bei jeder Änderung von "interne Variable" je nach Wert die eine oder die andere Zeile ausgeführt wird. Macht es auch.
    Zusätzlich hätte ich aber auch erwartete, dass eine der beiden Zeilen 5 Sekunden nach Systemstart ausgeführt wird. Das macht es NICHT.

    Dieser Code führt zum erwarteten Ergebnis:
    Code:
    LOS = AUS
    if after(systemstart(),  5000u64) then LOS = EIN endif
    //if after(systemstart(),  5500u64) then LOS = AUS endif
    
    ....
    interneVariable=0b01
    if (change(interneVariable) or LOS) and interneVariable then
    if (change(interneVariable) or LOS) and !interneVariable then
    ​​
    Meine Vermutung war jetzt, dass bei "after(5500)" LOS schon wieder auf AUS ist, bevor die anderen Zeilen ausgeführt werden.
    Eine Änderung auf "after( 10.000)" hat nicht funktioniert.
    Eine Änderung auf "after(100.000)" hat funktioniert.

    Was sagt uns das? Der Erste Verarbeitugszyklus dauert mehr als 10 Sekunden und daher geht LOS im ersten Zyklus von EIN direkt wieder auf AUS zurück und die Zeilen mit "or LOS" sehen LOS immer als AUS?

    Dann müsste die Zeile "after(systemstart(), 5500u64)" aber im ersten Zyklus ausgeführt werden, wohingegen "after(systemstart(), 10000u64)" nicht mehr im ersten Zyklus ausgeführt wird. Das wäre aber wenig deterministisch.

    Hab dann zum besseren Verständnis noch folgenden Testcode ausgeführt und über die ETS den Gruppenmonitor mitlaufen lassen:
    Code:
    if systemstart() then write("Test-15/0/0", 0u16) endif
    if after(systemstart(),  1000u64) then write("Test-15/0/0", 1u16) endif
    if after(systemstart(),  5000u64) then write("Test-15/0/0", 5u16) endif
    if after(systemstart(),  5500u64) then write("Test-15/0/0", 6u16) endif
    if after(systemstart(), 10000u64) then write("Test-15/0/0", 10u16) endif
    if after(systemstart(), 20000u64) then write("Test-15/0/0", 20u16) endif
    if after(systemstart(), 30000u64) then write("Test-15/0/0", 30u16) endif
    if after(systemstart(), 40000u64) then write("Test-15/0/0", 40u16) endif
    if after(systemstart(), 50000u64) then write("Test-15/0/0", 50u16) endif​
    Im Gruppenmonitor sehe ich:
    Code:
    Timestamp                  Service       Source    Destination    Hop  Type                Value   Info
    2026-10-27 05:49:58.219    vom Bus        1.0.8    alle INIT GA   6    GroupValue_Read        
    2026-10-27 05:50:48.133    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    0000    00 00 | 0
    2026-10-27 05:50:48.212    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    0001    00 01 | 1
    2026-10-27 05:50:48.329    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    0005    00 05 | 5
    2026-10-27 05:50:48.376    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    0006    00 06 | 6
    2026-10-27 05:50:48.457    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    000A    00 0A | 10
    2026-10-27 05:50:48.537    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    0014    00 14 | 20
    2026-10-27 05:50:54.839    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    001E    00 1E | 30
    2026-10-27 05:50:54.915    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    0028    00 28 | 40
    2026-10-27 05:50:54.991    vom Bus        1.0.8    15/0/0         6    GroupValue_Write    0032    00 32 | 50
    ​
    Die Abstände, in denen die Writes kommen, verstehe ich nicht.
    ​
    Zuletzt geändert von Uwe!; 27.10.2026, 08:03.
    ....und versuchen Sie nicht erst anhand der Farbe der Stichflamme zu erkennen, was Sie falsch gemacht haben!

    #2
    weitere Erkentnisse/Fragen:

    1. Der Ablauf beim Start
    05:49:37,1 – 05:49:58,2 Init-Reads, rund 200 GAs in 21 s, alle ohne Lücke
    05:49:58,2 – 05:50:47,9 49,7 s Stille, wohl der normale EibPC Start
    05:50:47,9 Datum und Uhrzeit, danach die 0/1/5/6/10/20 Sekunden nach Systemstart Writes auf 15/0/0, dann der übrige Startverkehr
    05:50:54,8 30/40/50 Sekunden nach Systemstart Writes auf 15/0/0
    05:50:55,2 erneute Uhrzeit
    2. Die Uhr des EibPC springt
    • Um 05:50:47,9 sendet er die Uhrzeit 06:50:04.
    • Nur 7,2 s später, um 05:50:55,2, sendet er 06:50:53.
    Die Uhr ist um gut 40 s nach vorn gesprungen. Vor dem Sprung lief sie rund 44 s nach (Monitor 06:50:48 lokal gegenüber gesendet 06:50:04), danach stimmt sie bis auf etwa 2 s. Das sieht stark nach der NTP-Synchronisierung aus, oder?
    ​"Programm erst nach NTP-Synchronisation starten" ist aber aktiv. Woher kommt dann der Sprung, wenn nicht von der Synchronisation?

    Und evtl. ist das Verhalten mit den after(systemstart)) Zeilen auch durch diesen Sprung zu erklären!?

    ....und versuchen Sie nicht erst anhand der Farbe der Stichflamme zu erkennen, was Sie falsch gemacht haben!

    Kommentar


      #3
      ich hab noch weiter getestet und einige (aus meiner Sicht) gesicherte Erkenntnisse gewonnen.
      Transparenzhinweis: ich hab Claude genutzt, um die Mitschnitte aus dem ETS-Gruppenmonitor auszuwerten, das war sehr hilfreich. Der nachfolgende Text stammt großteils auch aus der "Claude-Feder" teilweise aber manuell überarbeitet:

      Umgebung
      EibPC², Firmware 5.511, EibStudio 5.507. Rund 190 GAs mit Init-Flag. „Programm erst nach NTP-Synchronisation starten“ ist aktiv; ein Test ohne diese Option ergab keinen Unterschied. Aufgezeichnet habe ich mit dem ETS-Gruppenmonitor, gefiltert auf den EibPC und alle Response-Telegramme. Die GPS-Zeit kommt von einer Jung-Wetterstation (2225WSU).

      Ausgangsproblem
      Ich wollte nach dem Start einmalig einen kurzen Impuls erzeugen:
      LOS = AUS
      if after(systemstart(), 5000u64) then LOS = EIN endif
      if after(systemstart(), 5500u64) then LOS = AUS endif
      ...
      if (change(Variable) or LOS) and Variable then ... endif

      Zeilen mit "or LOS" haben nie ausgelöst. Mit 5 s / 10 s ging es auch nicht, mit 5 s / 100 s schon, und ebenso, wenn LOS dauerhaft EIN blieb.

      Meine Ergebnisse
      • after(systemstart(), X) ist für X bis etwa 100 s nicht vorhersagbar, ich vermute abhängig vom individuellen Programm mal länger, mal kürzer, aber bei mir rund 100s. Ein Impuls, der komplett in diese Phase fällt, wird nie ausgewertet. Das erklärt das Ausgangsproblem.
      • ready() ist der richtige Bezugspunkt. So funktioniert es bei mir:
      LOS = AUS
      if after(ready(), 1000u64) then LOS = EIN endif
      if after(LOS, 500u64) then LOS = AUS endif
      • Wer nach dem Start auf frische Telegrammwerte angewiesen ist (nicht nur auf Init-Werte), sollte etwa 20 s nach ready() warten. (Test 4)
      • after() und cycle() laufen etwa 1,7 bis 1,9 % langsamer als die Uhr des EibPC. (war glaube ich neulich in einem anderen Thread schon mal Thema)

      enertegus
      foobar0815 ​

      Was nur Enertex sagen kann:
      1. Warum feuern die after(systemstart())-Timer in zwei Schüben? (Test 1)
      2. Warum verhalten sich die after(systemstart())-Timer so, als lägen zwischen systemstart() und ready() etwa 107 s, obwohl es laut Uhr nur 48 bis 50 s sind? (Test 2)
      3. Ist es so vorgesehen, dass eingehende Telegramme erst ab ready() verarbeitet und dann nachgeholt werden? (Test 4)
        Wodurch ist das Nachholen so langsam (1 bis 5 s pro Telegramm)?


      ================================================== ======================================
      Ab hier sind die Tests beschrieben. Ziemlich viel Text, kann man lesen, muss man nicht:

      Test 1: after(systemstart()) und after(ready())
      if systemstart() then write("Test-15/0/0", 0u16) endif
      if after(systemstart(), 1000u64) then write("Test-15/0/0", 1u16) endif
      gleiche Zeilen mit 2, 4, 6, 8, 10, 20, 30 ... 210 s

      if ready() then write("Test-15/0/0", 9u16) endif
      if after(ready(), 1000u64) then write("Test-15/0/0", 91u16) endif
      auch hier gleiche Zeilen mit 2, 4, 6, 8, 10, 20, 30 ... 210 s
      (beim geschriebenen Wert hab ich einfach eine "9" vorangestellt, um die Telegramme von systemstart() und ready() sauber trennen zu können.)

      Ergebnis:
      • Die Init-Reads dauern etwa 21 s. Danach sendet der EibPC rund 49 s lang nichts.
      • Dann kommen die Writes aus dem systemstart-Block und mit ihnen die after(systemstart())-Werte 1 bis 30 s. Alle kommen auf einmal, im Abstand von 80 ms.
      • Etwa 6 s später kommen die Werte 40 bis 100 s auf einmal, unmittelbar gefolgt vom ready().
      • der "110 s Wert" kommt etwa 5 s nach ready(). Ab dann laufen die systemstart-Timer im 10-s-Abstand.
      • Die Grenze zwischen dem ersten und zweiten Schub verschiebt sich von Lauf zu Lauf etwas.
      • after(ready(), X) kommt ab etwa 6 s mit korrekten Abständen. 1 bis 4 s kommen 1 bis 2 s zu spät, vermutlich weil sie hinter dem Startverkehr in der Warteschlange stehen.
      • Vergleicht man after(systemstart(), X) mit after(ready(), X) bei gleichem X (120/120, 130/130 … 210/210), liegen sie konstant rund 107s auseinander. Nach den Timern liegt ready() also etwa 107 s nach systemstart(). Passt für mich zu dem Ergebnis, dass erst ab "after(systemstart(110000))" der 10 Sek. Abstand eingehalten wird.
      als "Zeitstrahl":
      Init-Reads (~21 s) → ~6 s → erster Zyklus (systemstart) → ~43 s ohne Senden/Empfangen
      → Telegramme aus dem 1. Zyklus gehen raus → ~6 s → ready() → ~15 s Nachholen eingehender Telegramme

      ​
      Test 2: Uhr gegen Timer – wie lange dauert es von systemstart() bis ready()?

      Vorgehen: Im selben Programm wie Test 1 speichere ich zusätzlich die EibPC-Uhrzeit im systemstart-Zyklus und im ready-Zyklus. Zur Kontrolle lese ich auch die GPS-Uhrzeit der Wetterstation mit. Beides geht per Mail raus.
      if systemstart() then UhrStartEPC = convert(settime(), $$) ; UhrStartGPS = convert("GPS.Uhrzeit-8/6/44", $$) endif
      if ready() then UhrReadyEPC = convert(settime(), $$) ; UhrReadyGPS = convert("GPS.Uhrzeit-8/6/44", $$) endif

      Messung laut Uhr:
      • systemstart(): 07:35:02
      • ready(): 07:35:50
      • Abstand: 48 s. Zwei weitere Läufe ergaben 49 und 50 s.

      Die Uhr stimmt dabei: Sie passt zur GPS-Zeit.

      Messung laut Timern (gleicher Lauf, Test-Writes aus Test 1):
      • Die Writes von after(systemstart(), 30000u64) bis 100000u64 kommen alle gleichzeitig mit ready().
      • after(systemstart(), 110000u64) kommt etwa 5 s nach ready().
      • Aus Sicht der Timer kommt ready() also ungefähr 105 s nach systemstart().
      • Dasselbe zeigt der direkte Vergleich: after(systemstart(), X) kommt immer rund 107 s vor after(ready(), X) (gemessen für X = 120 … 210 s).

      Der Widerspruch: Laut Uhr liegen 48 s zwischen systemstart() und ready(), laut Timern etwa 105 bis 107 s. Die after(systemstart())-Timer sind beim Start also rund eine Minute „voraus“. Deshalb kommen bis etwa 100 s alle auf einmal, und ein kurzer Impuls wie mein LOS (5 s EIN, 5,5 s AUS) wird nie ausgewertet.
      ​

      Test 3: Telegramme aus dem ersten Zyklus werden "zurückgehalten"
      • Das Uhrzeit-Telegramm aus dem systemstart-Block (write("Uhrzeit-8/3/2", settime())) enthält in jedem Lauf eine Zeit, die etwa 43 s vor dem Sendezeitpunkt liegt. Das passt genau zu settime() im ersten Zyklus (z. B. 07:54:49 berechnet, Telegramm 07:54:50, gesendet 43 s später).
      • Das read() aus dem systemstart-Block geht ebenfalls erst 43 s nach dem ersten Zyklus auf den Bus.
      • Die Telegramme aus dem ersten Zyklus warten vermutlich so lange in der Warteschlange.

      Test 4: Eingehende Telegramme werden erst ab ready() verarbeitet
      GPSLog = $$c2000
      if event("GPS.Uhrzeit-8/6/44") then GPSLog = GPSLog + $GPS $ + convert("GPS.Uhrzeit-8/6/44", $$) + $ / EibPC $ + convert(settime(), $$) + $<br>$ endif
      if after(ready(), 120000u64) then sendhtmlmail(MailAdmin, $Test GPS-Log$, GPSLog) endif

      Die Log-Einträge passen 1:1 zu den Telegrammen im Mitschnitt:
      Telegramm auf 8/6/44 GA-Wert beim event() EibPC-Uhrzeit beim event()
      Init-Response (vor systemstart) 08:25:17 08:26:25 (= ready)
      Write der Station 08:25:38 08:25:38 08:26:27
      eigenes Read (systemstart) 08:25:38 (alt) 08:26:32
      Response 08:26:18 08:26:18 08:26:33
      eigenes Read (ready) 08:26:18 (alt) 08:26:36
      Response 08:26:25 08:26:25 08:26:37
      eigenes Read (ready + 5 s) 08:26:25 (alt) 08:26:39
      Response 08:26:28 08:26:28 08:26:39
      Write der Station 08:26:38 08:26:38 08:26:40
      Write der Station 08:27:38 08:27:38 08:27:39
      • Zwischen systemstart() und ready() wird kein eingehendes Telegramm verarbeitet. Das Programm sieht in dieser Zeit nur die Init-Werte.
      • Ab ready() wird alles der Reihe nach nachgeholt. Die Verzögerung schrumpft von 49 s über 15 s und 11–12 s auf 1–2 s. Erst etwa 15 s nach ready() arbeitet der EibPC wieder in Echtzeit.

      Nebenbefund: Timer laufen etwas langsamer als die Uhr
      after() und cycle() laufen etwa 1,7 bis 1,9 % langsamer als die Uhr des EibPC. Beispiele: after(ready(), 200000u64) kommt nach rund 203,8 s, und cycle(1,0) sendet laut EibPC-eigener Uhrzeit alle 61 s. Bei kurzen Zeiten spielt das keine Rolle, bei einer Stunde sind es etwa eine Minute.
      ....und versuchen Sie nicht erst anhand der Farbe der Stichflamme zu erkennen, was Sie falsch gemacht haben!

      Kommentar


        #4
        schade das es hierzu keine Rückmeldung gibt. Nachdem Enertex "after(systemstart(1000f16))" ja selbst empfiehlt, würd ich das eigentlich als Bug einstufen.

        Ich habs für mich gelöst und kann damit leben.
        ....und versuchen Sie nicht erst anhand der Farbe der Stichflamme zu erkennen, was Sie falsch gemacht haben!

        Kommentar

        Lädt...
        X