fix(S3): Cold Extraction brach waehrend der Vorbenetzung ab (5.3.3) #15

Merged
thomas merged 1 commits from fix/cold-extraction-vorbenetzung into main 2026-08-11 01:55:31 +02:00
2 changed files with 33 additions and 7 deletions
+16
View File
@@ -1,3 +1,19 @@
Version 5.3.3:
- Bug-Fix (Cold Extraction, hätte die Funktion mit Waage komplett unbrauchbar gemacht): Die
Stillstands-Erkennung lief bereits während der Vorbenetzung mit. In dieser Phase sättigt der Puck
aber erst, es kommt naturgemäß nichts in der Tasse an - bei einer Vorbenetzung länger als die
15 s Stillstands-Zeit wurde deshalb JEDER kalte Bezug mit „kein Zulauf" abgebrochen. Mit dem
bisherigen Standard von 30 s Vorbenetzung wäre das immer passiert. Die Erkennung startet jetzt
erst mit dem Hauptbezug.
- Standard der Vorbenetzung von 30 s auf 10 s gesenkt. In dieser Phase läuft die Pumpe bewusst
ungepulst auf voller Leistung; bei heißem Bezug kommt der erste Tropfen nach etwa 7 s, kalt
(rund dreifache Viskosität) entsprechend später. 30 s wären also längst voller Bezug bei vollem
Druck gewesen, und die Hälfte des Pumpen-Laufzeitbudgets wäre vor dem eigentlichen Bezug
verbraucht. Bestehende Installationen behalten ihren gespeicherten Wert - dort ggf. auf
/Brew-Control nachziehen.
- Die Beschriftung auf /Brew-Control sagt jetzt ausdrücklich, dass die Pumpe während der
Vorbenetzung durchläuft und erst im Hauptbezug gepulst wird.
Version 5.3.2: Version 5.3.2:
- Cold Extraction sendet den Sperrgrund jetzt als Code („cxBlock") statt als Klartext („cxMessage"), - Cold Extraction sendet den Sperrgrund jetzt als Code („cxBlock") statt als Klartext („cxMessage"),
dazu eine transiente Meldung als Code („cxNotice") und die Vorbenetzungsdauer („cxPreInf"). dazu eine transiente Meldung als Code („cxNotice") und die Vorbenetzungsdauer („cxPreInf").
+17 -7
View File
@@ -369,7 +369,7 @@ Adafruit_SH1106G display = Adafruit_SH1106G(128, 64, &Wire);
* Firmware-Informationen * Firmware-Informationen
************************************************************************************/ ************************************************************************************/
String version = "5.3.2"; String version = "5.3.3";
String versionHersteller = "Thomas Müller"; String versionHersteller = "Thomas Müller";
String versionHerstellerMail = String versionHerstellerMail =
"<a href='mailto:thomas@mueller.black' class='info-link'>thomas@mueller.black</a>"; "<a href='mailto:thomas@mueller.black' class='info-link'>thomas@mueller.black</a>";
@@ -782,7 +782,7 @@ bool flowGuardPumpPulseActive = false;
************************************************************************************/ ************************************************************************************/
bool coldExtractionEnabled = false; // Funktion in der Web-UI freigeschaltet bool coldExtractionEnabled = false; // Funktion in der Web-UI freigeschaltet
float coldExtractionMaxTempC = 30.0f; // Freigabeschwelle Wasserkessel float coldExtractionMaxTempC = 30.0f; // Freigabeschwelle Wasserkessel
float coldExtractionPreInfusionSeconds = 30.0f; // Vorbenetzung (Pumpe laeuft ungepulst) float coldExtractionPreInfusionSeconds = 10.0f; // Vorbenetzung (Pumpe laeuft ungepulst)
uint16_t coldExtractionPulsePeriodMs = 2000; // Pulsperiode der Pumpe im Hauptbezug uint16_t coldExtractionPulsePeriodMs = 2000; // Pulsperiode der Pumpe im Hauptbezug
float coldExtractionDutyPercent = 30.0f; // Pumpen-Duty im Hauptbezug float coldExtractionDutyPercent = 30.0f; // Pumpen-Duty im Hauptbezug
float coldExtractionTargetGrams = 60.0f; // Zielgewicht (ca. 1:3 auf 18 g) float coldExtractionTargetGrams = 60.0f; // Zielgewicht (ca. 1:3 auf 18 g)
@@ -792,7 +792,11 @@ float coldExtractionPumpRestSec = 20.0f; // Dauer der Zwangspause
const bool defaultColdExtractionEnabled = false; const bool defaultColdExtractionEnabled = false;
const float defaultColdExtractionMaxTempC = 30.0f; const float defaultColdExtractionMaxTempC = 30.0f;
const float defaultColdExtractionPreInfusionSeconds = 30.0f; // 10 s statt der urspruenglichen 30 s: Die Pumpe laeuft in dieser Phase ungepulst auf
// voller Leistung. Heiss kommt der erste Tropfen nach ~7 s, kalt (rund dreifache
// Viskositaet) entsprechend spaeter - 30 s waeren laengst voller Bezug bei vollem Druck
// gewesen, und die Haelfte des Pumpen-Laufzeitbudgets waere vor dem Hauptbezug verbraucht.
const float defaultColdExtractionPreInfusionSeconds = 10.0f;
const uint16_t defaultColdExtractionPulsePeriodMs = 2000; const uint16_t defaultColdExtractionPulsePeriodMs = 2000;
const float defaultColdExtractionDutyPercent = 30.0f; const float defaultColdExtractionDutyPercent = 30.0f;
const float defaultColdExtractionTargetGrams = 60.0f; const float defaultColdExtractionTargetGrams = 60.0f;
@@ -4202,8 +4206,12 @@ bool coldExtractionStallDetected(float netWeight) {
coldExtractionStallSinceMs = 0; coldExtractionStallSinceMs = 0;
return false; return false;
} }
if (coldExtractionPumpResting) { // Waehrend der Vorbenetzung saettigt der Puck erst - da kommt naturgemaess nichts in
coldExtractionStallSinceMs = 0; // Pause ist kein Stillstand // der Tasse an. Ohne diese Ausnahme wuerde die Erkennung jeden kalten Bezug abbrechen,
// sobald die Vorbenetzung laenger als COLDEX_STALL_TIMEOUT_MS dauert. Der Zaehler
// startet damit erst mit dem Hauptbezug.
if (coldExtractionPumpResting || currentPreInfusionState == PI_PRE_BREW) {
coldExtractionStallSinceMs = 0; // Pause/Vorbenetzung ist kein Stillstand
coldExtractionStallLastWeight = netWeight; coldExtractionStallLastWeight = netWeight;
return false; return false;
} }
@@ -7144,7 +7152,7 @@ static const char brewControlCX_ToggleContainerEnd[] PROGMEM = R"rawliteral(><sp
static const char brewControlCX_Fields[] PROGMEM = R"rawliteral( static const char brewControlCX_Fields[] PROGMEM = R"rawliteral(
<label for='cxMaxTemp'>Freigabe bis Wassertemperatur (&deg;C):</label> <label for='cxMaxTemp'>Freigabe bis Wassertemperatur (&deg;C):</label>
<input type='number' min='10.0' max='40.0' step='0.5' id='cxMaxTemp' name='cxMaxTemp' value='{CX_MAX_TEMP}' required> <input type='number' min='10.0' max='40.0' step='0.5' id='cxMaxTemp' name='cxMaxTemp' value='{CX_MAX_TEMP}' required>
<label for='cxPreInf'>Vorbenetzung (Sekunden):</label> <label for='cxPreInf'>Vorbenetzung (Sekunden, Pumpe l&auml;uft dabei durchgehend):</label>
<input type='number' min='0.0' max='120.0' step='1.0' id='cxPreInf' name='cxPreInf' value='{CX_PREINF}' required> <input type='number' min='0.0' max='120.0' step='1.0' id='cxPreInf' name='cxPreInf' value='{CX_PREINF}' required>
<label for='cxPulseMs'>Pulsperiode (ms):</label> <label for='cxPulseMs'>Pulsperiode (ms):</label>
<input type='number' min='200' max='5000' step='50' id='cxPulseMs' name='cxPulseMs' value='{CX_PULSE_MS}' required> <input type='number' min='200' max='5000' step='50' id='cxPulseMs' name='cxPulseMs' value='{CX_PULSE_MS}' required>
@@ -7161,7 +7169,9 @@ static const char brewControlCX_Fields[] PROGMEM = R"rawliteral(
<small class="toggle-description-input">(Die Maschine hat keinen Bypass um den Wasserkessel: Kaltes Wasser kommt nur bei kaltem <small class="toggle-description-input">(Die Maschine hat keinen Bypass um den Wasserkessel: Kaltes Wasser kommt nur bei kaltem
Kessel am Puck an. Deshalb ist die kalte Extraktion nur unterhalb der Freigabetemperatur m&ouml;glich, praktisch also Kessel am Puck an. Deshalb ist die kalte Extraktion nur unterhalb der Freigabetemperatur m&ouml;glich, praktisch also
aus dem kalten Zustand heraus. Solange der Modus aktiv ist, heizt der Wasserkreis nicht - der Dampfkreis bleibt aus dem kalten Zustand heraus. Solange der Modus aktiv ist, heizt der Wasserkreis nicht - der Dampfkreis bleibt
unber&uuml;hrt und darf weiter heizen. Die Pumpenlaufzeit wird kumuliert gez&auml;hlt; nach der eingestellten unber&uuml;hrt und darf weiter heizen. W&auml;hrend der Vorbenetzung l&auml;uft die Pumpe durchgehend auf voller
Leistung (kein Pulsen) - sinnvoll ist eine Dauer knapp unterhalb des ersten Tropfens; gepulst wird erst im
Hauptbezug. Die Pumpenlaufzeit wird kumuliert gez&auml;hlt; nach der eingestellten
Laufzeit legt die Steuerung eine Zwangspause ein. Der Modus selbst wird auf dem Dashboard bzw. am Touch-Display Laufzeit legt die Steuerung eine Zwangspause ein. Der Modus selbst wird auf dem Dashboard bzw. am Touch-Display
ein- und ausgeschaltet und bleibt &uuml;ber Standby und Neustart hinweg aktiv, bis er dort wieder ausgeschaltet ein- und ausgeschaltet und bleibt &uuml;ber Standby und Neustart hinweg aktiv, bis er dort wieder ausgeschaltet
wird - solange heizt der Wasserkreis nicht.)</small> wird - solange heizt der Wasserkreis nicht.)</small>