Ursache gefunden - Problem gelöst.
Das Programm hat nicht nur den Timer, der die Hauptschleife triggert, sondern es gibt noch zwei weitere.
Ein Timer (Timer-A) dient dazu, dass der Heizkessel seinen Impuls bekommt, sich einzuschalten und der andere Timer (Timer-B) erfüllt den Zweck, dass ein oder mehrere Räume schnell aufgeheizt werden (Ferienwohnung wurde kurzfristig gebucht und muss auf Normaltemperatur gebracht werden).
Timer-A läuft 25 min (Kessel)
Timer-B läuft 4 Stunden (Raumheizung)
Timer-B wird durch den Button extra heizen ausgelöst oder auch gestoppt:
Delphi-Quellcode:
if extraheizenchecked then begin
if Timer_Extra_heizen.Enabled then begin
Timer_Extra_heizen.visible:=true;
Timer_Extra_heizen.StartCountdown;
end;
end else
Timer_Extra_heizen.EndCountdown;
Ereignis OnCountdownEnd sieht so aus:
Delphi-Quellcode:
procedure THauptformular.Timer_Extra_heizenCountdownEnd(Sender: TObject);
var i:SmallInt;
begin
extraheizenchecked:=false;
for i:=1 to 23 do // alle Räume
if Extra_heizen[i] then begin
Extra_heizen[i]:=false; // Status löschen
Heizstatus[i]:= normal_erreicht; //egal bei welcher tats. Temperatur
end;
Timer_Extra_heizen.Enabled:=false;
Timer_Extra_heizen.visible:=false;
end;
Dieser Timer verursachte das Problem nicht. Aber Timer-A, der so ähnlich aussieht.
Timer-A:
Der Pellets Heizkessel muss mindestens 25 min laufen, damit der Kamin nicht versottet.
Ereignis OnCountdownEnd sah so aus:
Delphi-Quellcode:
procedure THauptformular.Kessel_Ende_Countdown(Owner:TObject);
Begin
Kessel_manuell_ein:=false;
Kesseluhr.Endcountdown();
Kesseluhr.Visible:=false;
// kessel wird erst abgeschaltet, wenn die Vorlauf-Temperaturbedingungen erfüllt sind
Abfrage_Kessel_Ausschalten(nil);
end;
Jeder Timer bedient sich des Windows
API Timers und deshalb sah es so aus, als würde der Hauptschleifentimer den Crash verursachen. Tatsächlich verursachte jedoch Timer-A den Stack-Overflow. Nachdem ich mich nicht auf diesen Timer konzentriert habe, fand ic auch die Ursache für den Stack-Overlow nicht sofort.
Erst, als ich einen Demomode eingebaut hatte, um das Programm außerhalb des Heizcomputers zu betreiben erhielt ich die Position, wo sich das Programm gekillt hat - bei der Procedure
Kessel_Ende_Countdown
Delphi-Quellcode:
Begin
Kessel_manuell_ein:=false;
Kesseluhr.Endcountdown(); // hier wurde Kessel_Ende_Countdown rekursiv aufgerufen
Kesseluhr.Visible:=false;
// kessel wird erst abgeschaltet, wenn die Vorlauf-Temperaturbedingungen erfüllt sind
Abfrage_Kessel_Ausschalten(nil);
end;
Warum der Stack-Overflow nicht bei jedem Kessel_Ende_Countdown ausgelöst wurde weiß ich nicht, ist mir aber nun egal. Die Zeile muss irgendwann versehentlich durch copy/paste hineingerutscht sein, da ich in der Doku keinen Hinweis auf Änderung der Procedure fand.
Vielen, vielen Dank an euch alle.
Ihr habt mich großartig unterstützt, denn durch eure Hinweise kam ich dem Verursacher immer näher und fand schließlich die kurze, aber todbringende Zeile, was bei 8032 Programmzeilen gar nicht mehr so einfach ist!