From 96dd8da2d9521ba710a1dee69dc093b353e576ad Mon Sep 17 00:00:00 2001 From: Jannis Date: Wed, 7 Oct 2026 12:01:38 +0200 Subject: [PATCH] =?UTF-8?q?Claude=20aufger=C3=A4umt=20und=20motor=20ausgel?= =?UTF-8?q?agert.=20Temperatur=20Variablentyp=20noch=20anpassen=20ist=20ui?= =?UTF-8?q?tn=20und=20int=20nicht=20durchg=C3=A4ngig!?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- kugelmuehle.ino | 176 ++++++++++++++++++++++++++---------------------- 1 file changed, 97 insertions(+), 79 deletions(-) diff --git a/kugelmuehle.ino b/kugelmuehle.ino index 398afb7..f720000 100644 --- a/kugelmuehle.ino +++ b/kugelmuehle.ino @@ -211,7 +211,7 @@ int getTempInC(uint8_t senTemp){ return ((milliVolt - 500)/10); } -int getFilteredTemp(int rawSensorPin) { +uint32_t getFilteredTemp(int rawSensorPin) { constexpr uint8_t FILTER_SAMPLES = 100; // Puffergröße (100 Messwerte) Mittelwert über 10s static int readings[FILTER_SAMPLES]; static uint8_t readIndex = 0; @@ -417,17 +417,19 @@ if (settings.editAcc) { } } -// Prüft ob der Motor zu heiß wird. -// return: true wenn zu heiß +// Prüft ob der Motor zu heiß wird (mit Hysterese: AN ab maxTemp, AUS erst bei coldTemp) +// return: true wenn zu heiß // false wenn unter der Grenze bool checkOverHeat(int sensorPin){ + static bool overheated = false; curTemp = getFilteredTemp(sensorPin); if (curTemp >= settings.maxTemp) { - return true; + overheated = true; } else if (curTemp <= settings.coldTemp) { - return false; + overheated = false; } + return overheated; } // ################## TODO ######################### @@ -453,11 +455,57 @@ void printStatus(FastAccelStepper *stepper, int speed, int clickPlus, int clickM } } +// ############################################################ +// ################ EINZIGE STELLE FÜR MOTORSTEUERUNG ######### +// ############################################################ +enum MotorCmd { + MOTOR_KEEP, // nichts am Motor ändern + MOTOR_STOP, // schnell anhalten + MOTOR_AUTO, // Automatikbetrieb (Zeitschaltuhr) laufen lassen + MOTOR_MANUAL // Handbetrieb mit 'speed' +}; + +void applyMotor(MotorCmd cmd, int32_t speed) { + switch (cmd) { + case MOTOR_STOP: + if (stepper->isRunning()) { + stepper->setAcceleration(10000); + stepper->applySpeedAcceleration(); + stepper->stopMove(); + } + lastSpeed = 0; + break; + + case MOTOR_AUTO: + if (!stepper->isRunning()) { + uint32_t autoHz = ((uint32_t)settings.autoSpeed * MIKROSTEPS) / 60; + stepper->setSpeedInHz(autoHz); + stepper->setAcceleration(settings.accelRate); + stepper->runForward(); + } + break; + + case MOTOR_MANUAL: + if (speed != lastSpeed) { + stepper->setSpeedInHz(MAX_SPEED_HZ); + stepper->setAcceleration(settings.accelRate); + stepper->moveByAcceleration(speed, true); + lastSpeed = speed; + } + break; + + case MOTOR_KEEP: + default: + break; + } +} + //############################################################# //#################### MAIN ################################### //############################################################# void loop() { int32_t speed = 0; + MotorCmd motorCmd = MOTOR_KEEP; if (!stepper) { Serial.println("[HALT] Kein Stepper-Objekt aktiv."); @@ -468,7 +516,7 @@ void loop() { // 1. Eingaben & Sensoren lesen getInputs(clickPlus, clickMinus, clickStop, holdPlus, holdMinus, holdStop); - // 3. Zeitschaltuhr & NTP prüfen + // 2. Zeitschaltuhr & NTP prüfen int curH, curM, curS; bool timeIsValid = getCurrentTime(curH, curM, curS); @@ -478,32 +526,17 @@ void loop() { shouldRun = false; } - // 4. Schutz-Verriegelung (Überhitzung) - static bool tempOverheat; - tempOverheat = checkOverHeat(senTemp); - ///######################################### TODO - // Discord Überhitzungs-Alarm - static bool send = false; - if (tempOverheat && !send) { - String message = "⚠️ **Kugelmuehle ueberhitzt!** Aktuelle Temp: " + String(curTemp) + " °C"; - sendDiscordNotification(message); - send = true; - } else if (tempOverheat) { - send = false; - } + // 3. Schutz-Verriegelung (Überhitzung) + bool tempOverheat = checkOverHeat(senTemp); - // ################# Menü / Hotkey auswerten ################### + // 4. Menü / Hotkeys auswerten if (holdStop && clickPlus) { - bSettings = true; + bSettings = true; } // HotKey Timer Toggeln if (holdStop && clickMinus) { - if(settings.timerEnabled){ - settings.timerEnabled = false; - }else{ - settings.timerEnabled = true; - } + settings.timerEnabled = !settings.timerEnabled; } // Sperr-Flag, falls der Nutzer im aktiven Timer-Fenster bewusst Stopp gedrückt hat @@ -512,86 +545,61 @@ void loop() { manualTimerStopped = false; // Reset für den nächsten regulären Zeitzyklus } - // 6. Betriebsmodi steuern + // 5. Betriebsmodi: hier wird nur ENTSCHIEDEN, nicht am Motor gesteuert if (bSettings) { setting(); - } + motorCmd = MOTOR_KEEP; + } // NOT-AUS BEI ÜBERHITZUNG else if (tempOverheat) { - if (stepper->isRunning()) { - stepper->setAcceleration(10000); - stepper->applySpeedAcceleration(); - stepper->stopMove(); - lastSpeed = 0; - } + motorCmd = MOTOR_STOP; } // AUTOMATIK-BETRIEB (Zeitschaltuhr) else if (settings.timerEnabled) { - // Druch drücken von plus den Timer betrieb vortsetzen + // Durch Drücken von Plus den Timerbetrieb fortsetzen if (manualTimerStopped && clickPlus) { manualTimerStopped = false; } if (shouldRun && !manualTimerStopped) { - if (!stepper->isRunning()) { - uint32_t autoHz = ((uint32_t)settings.autoSpeed * MIKROSTEPS) / 60; - stepper->setSpeedInHz(autoHz); - stepper->setAcceleration(settings.accelRate); - stepper->runForward(); - } + motorCmd = MOTOR_AUTO; // Manuelles Anhalten im laufenden Timer erlauben if (clickStop) { manualTimerStopped = true; - stepper->setAcceleration(10000); - stepper->applySpeedAcceleration(); - stepper->stopMove(); - lastSpeed = 0; + motorCmd = MOTOR_STOP; } } else { // Außerhalb des Fensters oder manuell gestoppt - if (stepper->isRunning()) { - stepper->setAcceleration(10000); - stepper->applySpeedAcceleration(); - stepper->stopMove(); - lastSpeed = 0; - } + motorCmd = MOTOR_STOP; } - } + } // MANUELLER BETRIEB (Zeitschaltuhr aus) else { - static bool manualStopped = false; + static bool manualStopped = false; + motorCmd = MOTOR_MANUAL; - if (clickStop) { - if (stepper->isRunning()) { - stepper->setAcceleration(10000); - stepper->applySpeedAcceleration(); // <-- macht die neue Rampe sofort wirksam - stepper->stopMove(); + if (clickStop) { + manualStopped = true; + speed = 0; + motorCmd = MOTOR_STOP; + } else if (manualStopped) { + if (!holdPlus && !holdMinus) { + manualStopped = false; // erst freigeben wenn Tasten los sind + } + speed = 0; // während Sperre: nichts tun + } else if (holdPlus) { + speed = settings.accelRate; + } else if (holdMinus) { + speed = -settings.accelRate; + } else { + speed = 0; } - speed = 0; - lastSpeed = 0; - manualStopped = true; - } else if (manualStopped) { - if (!holdPlus && !holdMinus) { - manualStopped = false; // erst freigeben wenn Tasten los sind - } - speed = 0; // während Sperre: nichts tun - } else if (holdPlus) { - speed = settings.accelRate; - } else if (holdMinus) { - speed = -settings.accelRate; - } else { - speed = 0; } - if (speed != lastSpeed) { - stepper->setSpeedInHz(MAX_SPEED_HZ); - stepper->setAcceleration(settings.accelRate); - stepper->moveByAcceleration(speed, true); - lastSpeed = speed; - } -} + // 6. Motor ansteuern (einzige Stelle) + applyMotor(motorCmd, speed); // 7. Geschwindigkeitsberechnung & UI int32_t currentSpeed_HZ = (stepper->getCurrentSpeedInUs() == 0) ? 0 : (1000000 / stepper->getCurrentSpeedInUs()); @@ -599,4 +607,14 @@ void loop() { updateDisplay(bSettings, settings.settingIdx, timeEditStep, settings, currentSpeed, curH, curM, timeIsValid, curTemp); printStatus(stepper, speed, clickPlus, clickMinus); + + // 8. Discord-Alarm (bewusst NACH der Motorsteuerung, da der HTTP-Call blockiert) + // Genau eine Nachricht pro Überhitzungs-Ereignis, Reset erst wenn wieder abgekühlt + if (tempOverheat && !send) { + String message = "⚠️ **Kugelmuehle ueberhitzt!** Aktuelle Temp: " + String(curTemp) + " °C"; + sendDiscordNotification(message); + send = true; + } else if (!tempOverheat) { + send = false; + } } \ No newline at end of file