Delphi-PRAXiS
Seite 1 von 5  1 23     Letzte » 

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Nach Timer.Enable killt sich das Programm (https://www.delphipraxis.net/208680-nach-timer-enable-killt-sich-das-programm.html)

Rupert 5. Sep 2021 19:11

Nach Timer.Enable killt sich das Programm
 
Liebe Freunde.

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.
Danke und
lg Rupert

Delphi-Quellcode:
procedure THauptformular.Hauptschleife(Owner: TObject);

Begin

  inc (Hauptschleifencounter,1);

  if Hauptschleifencounter > 10 then Begin
    CounterStop(nil);
    inc(Regel_intervall_ist,1);
    if Regel_intervall_ist >= Regel_intervall then
    Begin
// 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;
      Begin
        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
end;


procedure THauptformular.Counterstop(Owner: TObject);
Begin
  TimerEx1.Enabled:=False;
end;

procedure THauptformular.CounterStart(Owner: TObject);
Begin
    TimerEx1. CleanupInstance;
    TimerEx1.Enabled:=True;
end;

zeras 5. Sep 2021 20:09

AW: Nach Timer.Enable killt sich das Programm
 
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?

mmw 5. Sep 2021 20:19

AW: Nach Timer.Enable killt sich das Programm
 
Halo,

laut Online Hilfe soll man

CleanupInstance

nicht direkt aufrufen.

https://docwiki.embarcadero.com/Libr...leanupInstance

Gruß

Uwe Raabe 5. Sep 2021 22:59

AW: Nach Timer.Enable killt sich das Programm
 
Zitat:

Zitat von zeras (Beitrag 1494177)
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
Delphi-Quellcode:
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.

Blup 6. Sep 2021 08:07

AW: Nach Timer.Enable killt sich das Programm
 
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.
Delphi-Quellcode:
    procedure Hauptschleife(Owner: TObject);
  private
    SteuerungAktiv: Boolean;
    NextStart: TDateTime;
    procedure DoSteuerung;
  end;

implementation

const
  StartIntervall   = 1{s} /24/60/60;
  Startverzoegerung = 10{s} /24/60/60;

function NowUTC: TDateTime;
var
  SystemTime: TSystemTime;
begin
  GetSystemTime(SystemTime);
  Result := SystemTimeToDateTime(SystemTime);
end;

procedure THauptformular.Hauptschleife(Owner: TObject);
begin
  if not SteuerungAktiv then
  begin
    SteuerungAktiv := True;
    if NowUTC >= NextStart then
    begin
      NextStart := NextStart + StartIntervall; // alternativ NowUTC + StartIntervall
      DoSteuerung;
    end;
    SteuerungAktiv := False;
  end;
end;

procedure THauptformular.Counterstop(Owner: TObject);
Begin
  TimerEx1.Enabled:=False;
end;

procedure THauptformular.CounterStart(Owner: TObject);
Begin
  NextStart := NowUTC + Startverzoegerung;
  TimerEx1.Enabled:=True;
end;

Rupert 6. Sep 2021 08:24

AW: Nach Timer.Enable killt sich das Programm
 
Zitat:

Zitat von mmw (Beitrag 1494178)
Halo,

laut Online Hilfe soll man

CleanupInstance

nicht direkt aufrufen.

https://docwiki.embarcadero.com/Libr...leanupInstance

Gruß

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!

Rupert 6. Sep 2021 08:46

AW: Nach Timer.Enable killt sich das Programm
 
Zitat:

Zitat von Uwe Raabe (Beitrag 1494179)
Zitat:

Zitat von zeras (Beitrag 1494177)
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
Delphi-Quellcode:
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.

JA, das ist so gedacht.
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.

Danke für die Tipps!


Delphi-Quellcode:
        Ausgeben_auf_Steuerungskarte(nil);
        Hauptschleifencounter:=0;
        Istwerte_aktualisieren(nil);

hoika 6. Sep 2021 09:36

AW: Nach Timer.Enable killt sich das Programm
 
Hallo,
was sagt denn FastMM4 zu Deinem Programm?

Ansonsten, wie schon gesagt wurde, mal den Taskmanager mitlaufen lassen
zwecks Kontrolle des Speichers und der Handles.

Rupert 6. Sep 2021 15:14

AW: Nach Timer.Enable killt sich das Programm
 
Zitat:

Zitat von hoika (Beitrag 1494186)
Hallo,
was sagt denn FastMM4 zu Deinem Programm?

Ansonsten, wie schon gesagt wurde, mal den Taskmanager mitlaufen lassen
zwecks Kontrolle des Speichers und der Handles.

FastMM4 kannte ich nicht. Halte es vorerst im Focus - Danke.
Taskmanager läuft bereits mit.

Rupert 6. Sep 2021 15:38

AW: Nach Timer.Enable killt sich das Programm
 
Liste der Anhänge anzeigen (Anzahl: 1)
Zitat:

Zitat von zeras (Beitrag 1494177)
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?

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!

https://www.delphipraxis.net/attachm...1&d=1630935434


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:58 Uhr.
Seite 1 von 5  1 23     Letzte » 

Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf