text: Nach Timer.Enable killt sich das Programm - Delphi-PRAXiS
  5. Sep 2021, 19:11
  Ich habe ein Programm geschrieben, das meine Heizung steuert. Seit 1997 läuft das Programm klaglaos, bis ich vor 6 Monaten die Pumpen- und Mischersteuerung ausgegliedert habe, und mit einer Siemens-LOGO durchführen lasse.
  Im Grunde genommen hat sich nicht viel geändert:
  - die Steuerbefehle für 4 Pumpen und 4 Mischer werden nicht mehr von der Steuerkarte in meinem PC ausgeführt.
  - Daten vom Heizkessel und von der PV werden von einem Server eingelesen
  - Die Abarbeitung Hauptschleife dauert nun anstatt 0,8sec. 1,3 sec.
  Zu Beginn der Regelung stoppe ich den Timer und am Ende starte ich ihn wieder, damit er die Hauptschleife nicht erneut auslöst.
  Der Timer löst jede Sekunde die Hauptschleife aus.
  Ich habe schon andere Timerkomponenten ausprobiert, was leider keinen Erfolg gebracht hat
  Mittlerweile habe ich zur Fehlersuche eine kleine Datenbank angelegt, die die Routinen vor dem Aufruf einträgt (siehe Bild)
  irgendwann -mal nach 40000 Einträgen, dann nach 6000 Einträgen beendet sich das Programm an einem Punkt, wo der Punkt Timer.enable:=true ausgeführt wird.
  Ich bin leider mit meiner Weisheit am Ende und hoffe, dass ich auf diesem Wege Ideen erhalte, die dieses Problem lösen.
  Vielleicht stehe ich auch nur auf dem Schlauch.
  procedure THauptformular.Hauptschleife(Owner: TObject);
  inc (Hauptschleifencounter,1);
  if Hauptschleifencounter > 10 then Begin
  CounterStop(nil);
  inc(Regel_intervall_ist,1);
  if Regel_intervall_ist >= Regel_intervall then
  // Abscannen der Raum- und Wassertemperaturen
  Digital_Messwerte_holen(nil);
  Analog_Messwerte_holen(nil);
  Pruefung_der_Vorprogrammierung(nil); // check auf einen Programmwechsel
  // Daten der Photovoltaik und des Heizkessels abfragen
  NANO_Daten_vom_Server(nil);
  Fronius_Daten_vom_Server(nil);
  Steuern[Kessel_Port]:=aus;
  Regelvorgang_Raeume(nil);
  // Kesselbetrieb abfragen
  if ((not Heizung_ausflag)) then
  Abfrage_Kessel_Einschalten(nil);
  If ((not Winterbetrieb_Aktiv)) then
  Abfrage_Kessel_Ausschalten(nil); // nicht Abschalten, wenn Winterbetrieb
  Ausgeben_auf_Steuerungskarte(nil);
  Istwerte_aktualisieren(nil);
  // Speichern der aktuellen Werte zur Statistik
  inc(Speicherintervall_ist,1);
  if Speicherintervall_ist >= Speicherintervall then Begin
  Speicherintervall_ist:=0;
  Memo1.Clear; //memofeld entleeren um Speicherüberläufe zu verhindern
  Speicherung_Der_Messdaten(nil);
  end; //Speicherintervall
  end; // if Heizung_ausflag
  end; //Regel_intervall
  Display_aktualisieren(nil);
  CounterStart(nil);
  end; //if Hauptschleifencounter > 10
  procedure THauptformular.Counterstop(Owner: TObject);
  TimerEx1.Enabled:=False;
  procedure THauptformular.CounterStart(Owner: TObject);
  TimerEx1. CleanupInstance;
  TimerEx1.Enabled:=True;
  5. Sep 2021, 20:09
  Nach den Infos klingt das für mich komisch. Deine Hauptschleife wird jede Sekunde aufgerufen, dauert aber manchmal mehr als eine Sekunde.
  Ich habe jetzt nicht dein Programm angeschaut, aber warum läßt du den Timer dann nicht alle 2 oder mehr Sekunden laufen, damit das Ende immer innerhalb der Zeit fertig ist?
  5. Sep 2021, 20:19
  laut Online Hilfe soll man
  nicht direkt aufrufen.
  https://docwiki.embarcadero.com/Libr...leanupInstance
  5. Sep 2021, 22:59
  Deine Hauptschleife wird jede Sekunde aufgerufen, dauert aber manchmal mehr als eine Sekunde.
  Der Timer wird ja innerhalb der Schleife aus- und wieder eingeschaltet. Das Timer-Intervall startet also erst am Ende der Schleife.
  Was allerdings auffällt ist, dass der Hauptschleifencounter nicht zurückgesetzt wird. Es wird also ab dem 10-ten Aufruf jedes mal der gesamte Zyklus durchlaufen. Ich weiß nicht, ob das so gedacht ist.
  6. Sep 2021, 08:07
  Ich vermute auch das "CleanupInstance" da nicht hingehört, kommentiere das mal aus.
  Statt den Timer immer wieder aus und ein zu schalten, ist es vieleicht besser die vergangene Zeit seit dem letzen Aufruf zu testen.
  procedure Hauptschleife(Owner: TObject);
  SteuerungAktiv: Boolean;
  NextStart: TDateTime;
  procedure DoSteuerung;
  StartIntervall = 1{s} /24/60/60;
  Startverzoegerung = 10{s} /24/60/60;
  function NowUTC: TDateTime;
  if not SteuerungAktiv then
  SteuerungAktiv := True;
  if NowUTC >= NextStart then
  NextStart := NextStart + StartIntervall; // alternativ NowUTC + StartIntervall
  DoSteuerung;
  SteuerungAktiv := False;
  NextStart := NowUTC + Startverzoegerung;
  Geändert von Blup ( 6. Sep 2021 um 08:40 Uhr)
  6. Sep 2021, 08:24
  CleanupInstance ist erst zuletzt hinzugefügt worden, um ev. Puffer zu bereinigen - aus Verzweiflung, weil bisher nichts zur Lösung beigetragen hat.
  Wird remarkt - Danke!
  6. Sep 2021, 08:46
  Die Regelintervalle sind 20 sec. damit die Mischermotoren nicht dauernd auf/zu fahren. Deren Gesamtlaufzeit ist 140 sec.
  Die Sericherintervalle sind 30 x Regelintervall also 600 sec.
  der Hauptschleifencounter wird auf 0 gesetzt - habe ich beim Löschen der Kommentierung (wegen der Lesbarkeit des Codes) versehentlich mitgelöscht - sorry - aber danke, würde ohne Nullsetzung nicht funktionieren.
  Hat sich von gestern auf heute nach 33142 Ereignissen wieder gekillt - an der selben Stelle.
  Habe CleanupInstance entfernt und nach inc (Hauptschleifencounter,1); einen Eintrag in die Datenbank gesetzt, um zu sehen, ob der Timer die Hauptschleife auslöst oder er selbst den Kill auslöst.
  SW neu gestartet.
  Hauptschleifencounter:=0;
  6. Sep 2021, 09:36
  was sagt denn FastMM4 zu Deinem Programm?
  Ansonsten, wie schon gesagt wurde, mal den Taskmanager mitlaufen lassen
  zwecks Kontrolle des Speichers und der Handles.
  6. Sep 2021, 15:14
  FastMM4 kannte ich nicht. Halte es vorerst im Focus - Danke.
  Taskmanager läuft bereits mit.
  6. Sep 2021, 15:38
  Es läuft ein Countdown mit, der signalisiert, wann der nächste Regelvorgang startet.
  In der Statuszeile werden die jeweiligen "Stationen" - was soeben durchgeführt wird - visualisiert.
  Werde ich beim nächsten Crash auf 2 sec. erhöhen und testen. Führt m.e. jedoch nicht zum Verursacher des Problems, wäre aber vlt. eine Lösung - Danke!