Claude aufgeräumt und motor ausgelagert. Temperatur Variablentyp noch anpassen ist uitn und int nicht durchgängig!
This commit is contained in:
parent
2343a99d68
commit
96dd8da2d9
1 changed files with 97 additions and 79 deletions
176
kugelmuehle.ino
176
kugelmuehle.ino
|
|
@ -211,7 +211,7 @@ int getTempInC(uint8_t senTemp){
|
||||||
return ((milliVolt - 500)/10);
|
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
|
constexpr uint8_t FILTER_SAMPLES = 100; // Puffergröße (100 Messwerte) Mittelwert über 10s
|
||||||
static int readings[FILTER_SAMPLES];
|
static int readings[FILTER_SAMPLES];
|
||||||
static uint8_t readIndex = 0;
|
static uint8_t readIndex = 0;
|
||||||
|
|
@ -417,17 +417,19 @@ if (settings.editAcc) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Prüft ob der Motor zu heiß wird.
|
// Prüft ob der Motor zu heiß wird (mit Hysterese: AN ab maxTemp, AUS erst bei coldTemp)
|
||||||
// return: true wenn zu heiß
|
// return: true wenn zu heiß
|
||||||
// false wenn unter der Grenze
|
// false wenn unter der Grenze
|
||||||
bool checkOverHeat(int sensorPin){
|
bool checkOverHeat(int sensorPin){
|
||||||
|
static bool overheated = false;
|
||||||
curTemp = getFilteredTemp(sensorPin);
|
curTemp = getFilteredTemp(sensorPin);
|
||||||
|
|
||||||
if (curTemp >= settings.maxTemp) {
|
if (curTemp >= settings.maxTemp) {
|
||||||
return true;
|
overheated = true;
|
||||||
} else if (curTemp <= settings.coldTemp) {
|
} else if (curTemp <= settings.coldTemp) {
|
||||||
return false;
|
overheated = false;
|
||||||
}
|
}
|
||||||
|
return overheated;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ################## TODO #########################
|
// ################## 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 ###################################
|
//#################### MAIN ###################################
|
||||||
//#############################################################
|
//#############################################################
|
||||||
void loop() {
|
void loop() {
|
||||||
int32_t speed = 0;
|
int32_t speed = 0;
|
||||||
|
MotorCmd motorCmd = MOTOR_KEEP;
|
||||||
|
|
||||||
if (!stepper) {
|
if (!stepper) {
|
||||||
Serial.println("[HALT] Kein Stepper-Objekt aktiv.");
|
Serial.println("[HALT] Kein Stepper-Objekt aktiv.");
|
||||||
|
|
@ -468,7 +516,7 @@ void loop() {
|
||||||
// 1. Eingaben & Sensoren lesen
|
// 1. Eingaben & Sensoren lesen
|
||||||
getInputs(clickPlus, clickMinus, clickStop, holdPlus, holdMinus, holdStop);
|
getInputs(clickPlus, clickMinus, clickStop, holdPlus, holdMinus, holdStop);
|
||||||
|
|
||||||
// 3. Zeitschaltuhr & NTP prüfen
|
// 2. Zeitschaltuhr & NTP prüfen
|
||||||
int curH, curM, curS;
|
int curH, curM, curS;
|
||||||
bool timeIsValid = getCurrentTime(curH, curM, curS);
|
bool timeIsValid = getCurrentTime(curH, curM, curS);
|
||||||
|
|
||||||
|
|
@ -478,32 +526,17 @@ void loop() {
|
||||||
shouldRun = false;
|
shouldRun = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 4. Schutz-Verriegelung (Überhitzung)
|
// 3. Schutz-Verriegelung (Überhitzung)
|
||||||
static bool tempOverheat;
|
bool tempOverheat = checkOverHeat(senTemp);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ################# Menü / Hotkey auswerten ###################
|
// 4. Menü / Hotkeys auswerten
|
||||||
if (holdStop && clickPlus) {
|
if (holdStop && clickPlus) {
|
||||||
bSettings = true;
|
bSettings = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// HotKey Timer Toggeln
|
// HotKey Timer Toggeln
|
||||||
if (holdStop && clickMinus) {
|
if (holdStop && clickMinus) {
|
||||||
if(settings.timerEnabled){
|
settings.timerEnabled = !settings.timerEnabled;
|
||||||
settings.timerEnabled = false;
|
|
||||||
}else{
|
|
||||||
settings.timerEnabled = true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sperr-Flag, falls der Nutzer im aktiven Timer-Fenster bewusst Stopp gedrückt hat
|
// 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
|
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) {
|
if (bSettings) {
|
||||||
setting();
|
setting();
|
||||||
}
|
motorCmd = MOTOR_KEEP;
|
||||||
|
}
|
||||||
// NOT-AUS BEI ÜBERHITZUNG
|
// NOT-AUS BEI ÜBERHITZUNG
|
||||||
else if (tempOverheat) {
|
else if (tempOverheat) {
|
||||||
if (stepper->isRunning()) {
|
motorCmd = MOTOR_STOP;
|
||||||
stepper->setAcceleration(10000);
|
|
||||||
stepper->applySpeedAcceleration();
|
|
||||||
stepper->stopMove();
|
|
||||||
lastSpeed = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// AUTOMATIK-BETRIEB (Zeitschaltuhr)
|
// AUTOMATIK-BETRIEB (Zeitschaltuhr)
|
||||||
else if (settings.timerEnabled) {
|
else if (settings.timerEnabled) {
|
||||||
|
|
||||||
// Druch drücken von plus den Timer betrieb vortsetzen
|
// Durch Drücken von Plus den Timerbetrieb fortsetzen
|
||||||
if (manualTimerStopped && clickPlus) {
|
if (manualTimerStopped && clickPlus) {
|
||||||
manualTimerStopped = false;
|
manualTimerStopped = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldRun && !manualTimerStopped) {
|
if (shouldRun && !manualTimerStopped) {
|
||||||
if (!stepper->isRunning()) {
|
motorCmd = MOTOR_AUTO;
|
||||||
uint32_t autoHz = ((uint32_t)settings.autoSpeed * MIKROSTEPS) / 60;
|
|
||||||
stepper->setSpeedInHz(autoHz);
|
|
||||||
stepper->setAcceleration(settings.accelRate);
|
|
||||||
stepper->runForward();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Manuelles Anhalten im laufenden Timer erlauben
|
// Manuelles Anhalten im laufenden Timer erlauben
|
||||||
if (clickStop) {
|
if (clickStop) {
|
||||||
manualTimerStopped = true;
|
manualTimerStopped = true;
|
||||||
stepper->setAcceleration(10000);
|
motorCmd = MOTOR_STOP;
|
||||||
stepper->applySpeedAcceleration();
|
|
||||||
stepper->stopMove();
|
|
||||||
lastSpeed = 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Außerhalb des Fensters oder manuell gestoppt
|
// Außerhalb des Fensters oder manuell gestoppt
|
||||||
if (stepper->isRunning()) {
|
motorCmd = MOTOR_STOP;
|
||||||
stepper->setAcceleration(10000);
|
|
||||||
stepper->applySpeedAcceleration();
|
|
||||||
stepper->stopMove();
|
|
||||||
lastSpeed = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// MANUELLER BETRIEB (Zeitschaltuhr aus)
|
// MANUELLER BETRIEB (Zeitschaltuhr aus)
|
||||||
else {
|
else {
|
||||||
static bool manualStopped = false;
|
static bool manualStopped = false;
|
||||||
|
motorCmd = MOTOR_MANUAL;
|
||||||
|
|
||||||
if (clickStop) {
|
if (clickStop) {
|
||||||
if (stepper->isRunning()) {
|
manualStopped = true;
|
||||||
stepper->setAcceleration(10000);
|
speed = 0;
|
||||||
stepper->applySpeedAcceleration(); // <-- macht die neue Rampe sofort wirksam
|
motorCmd = MOTOR_STOP;
|
||||||
stepper->stopMove();
|
} 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) {
|
// 6. Motor ansteuern (einzige Stelle)
|
||||||
stepper->setSpeedInHz(MAX_SPEED_HZ);
|
applyMotor(motorCmd, speed);
|
||||||
stepper->setAcceleration(settings.accelRate);
|
|
||||||
stepper->moveByAcceleration(speed, true);
|
|
||||||
lastSpeed = speed;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 7. Geschwindigkeitsberechnung & UI
|
// 7. Geschwindigkeitsberechnung & UI
|
||||||
int32_t currentSpeed_HZ = (stepper->getCurrentSpeedInUs() == 0) ? 0 : (1000000 / stepper->getCurrentSpeedInUs());
|
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);
|
updateDisplay(bSettings, settings.settingIdx, timeEditStep, settings, currentSpeed, curH, curM, timeIsValid, curTemp);
|
||||||
printStatus(stepper, speed, clickPlus, clickMinus);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue