From 6c6a9d15de538812cc2af1895bd6c66c59ed8cda Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Mon, 24 Apr 2023 02:34:02 +0200 Subject: [PATCH] put soldering profile mode into its own file, put common functions in utils --- source/Core/BSP/BSP.h | 4 +- source/Core/BSP/MHP30/BSP.cpp | 11 +- source/Core/BSP/Miniware/BSP.cpp | 2 +- source/Core/BSP/Pinecil/BSP.cpp | 2 +- source/Core/BSP/Pinecilv2/BSP.cpp | 2 +- .../Threads/OperatingModes/HomeScreen.cpp | 8 +- .../Threads/OperatingModes/OperatingModes.h | 1 + .../Core/Threads/OperatingModes/Soldering.cpp | 340 ++---------------- .../OperatingModes/SolderingProfile.cpp | 236 ++++++++++++ .../OperatingModes/utils/SolderingCommon.cpp | 123 +++++++ .../OperatingModes/utils/SolderingCommon.h | 8 + 11 files changed, 402 insertions(+), 335 deletions(-) create mode 100644 source/Core/Threads/OperatingModes/SolderingProfile.cpp create mode 100644 source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp create mode 100644 source/Core/Threads/OperatingModes/utils/SolderingCommon.h diff --git a/source/Core/BSP/BSP.h b/source/Core/BSP/BSP.h index 3d07a51962..732a3adcf2 100644 --- a/source/Core/BSP/BSP.h +++ b/source/Core/BSP/BSP.h @@ -92,7 +92,9 @@ enum StatusLED { LED_COOLING_STILL_HOT, // The unit is off and cooling but still hot LED_UNKNOWN, // }; -void setStatusLED(const enum StatusLED state, bool buzzer); +void setStatusLED(const enum StatusLED state); + +void setBuzzer(bool on); // preStartChecks are run until they return 0 // By the PID, after each ADC sample comes in diff --git a/source/Core/BSP/MHP30/BSP.cpp b/source/Core/BSP/MHP30/BSP.cpp index a269bcc423..2c4b338126 100644 --- a/source/Core/BSP/MHP30/BSP.cpp +++ b/source/Core/BSP/MHP30/BSP.cpp @@ -436,7 +436,7 @@ void setBuzzer(bool on) { htim3.Instance->PSC = 1; // revert back out of hearing range } } -void setStatusLED(const enum StatusLED state, bool buzzer) { +void setStatusLED(const enum StatusLED state) { static enum StatusLED lastState = LED_UNKNOWN; static TickType_t buzzerEnd = 0; @@ -460,18 +460,9 @@ void setStatusLED(const enum StatusLED state, bool buzzer) { ws2812.led_set_color(0, 0xFF, 0x8C, 0x00); // Orange break; } - if (buzzer) { - // Buzzer requested - buzzerEnd = xTaskGetTickCount() + TICKS_SECOND / 3; - } ws2812.led_update(); lastState = state; } - if (xTaskGetTickCount() < buzzerEnd) { - setBuzzer(true); - } else { - setBuzzer(false); - } } uint64_t getDeviceID() { // diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index 55c06c8207..2cc36e6e42 100644 --- a/source/Core/BSP/Miniware/BSP.cpp +++ b/source/Core/BSP/Miniware/BSP.cpp @@ -245,7 +245,7 @@ bool isTipDisconnected() { return tipTemp > tipDisconnectedThres; } -void setStatusLED(const enum StatusLED state, bool buzzer) {} +void setStatusLED(const enum StatusLED state) {} uint8_t preStartChecks() { return 1; } uint64_t getDeviceID() { // diff --git a/source/Core/BSP/Pinecil/BSP.cpp b/source/Core/BSP/Pinecil/BSP.cpp index 96b880d108..5bac313d43 100644 --- a/source/Core/BSP/Pinecil/BSP.cpp +++ b/source/Core/BSP/Pinecil/BSP.cpp @@ -86,7 +86,7 @@ bool isTipDisconnected() { return tipTemp > tipDisconnectedThres; } -void setStatusLED(const enum StatusLED state, bool buzzer) {} +void setStatusLED(const enum StatusLED state) {} uint8_t preStartChecks() { return 1; } uint64_t getDeviceID() { return dbg_id_get(); } diff --git a/source/Core/BSP/Pinecilv2/BSP.cpp b/source/Core/BSP/Pinecilv2/BSP.cpp index 14b58f0dad..eb996bd8db 100644 --- a/source/Core/BSP/Pinecilv2/BSP.cpp +++ b/source/Core/BSP/Pinecilv2/BSP.cpp @@ -145,7 +145,7 @@ bool isTipDisconnected() { return tipTemp > tipDisconnectedThres; } -void setStatusLED(const enum StatusLED state, bool buzzer) { +void setStatusLED(const enum StatusLED state) { // Dont have one } diff --git a/source/Core/Threads/OperatingModes/HomeScreen.cpp b/source/Core/Threads/OperatingModes/HomeScreen.cpp index 7874bf8541..fa2388e24c 100644 --- a/source/Core/Threads/OperatingModes/HomeScreen.cpp +++ b/source/Core/Threads/OperatingModes/HomeScreen.cpp @@ -57,7 +57,7 @@ void drawHomeScreen(bool buttonLockout) { case BUTTON_F_LONG: #ifdef PROFILE_SUPPORT if (!isTipDisconnected()) { - gui_solderingMode(0); // enter soldering mode + gui_solderingProfileMode(); // enter soldering profile mode buttonLockout = true; } #else @@ -97,13 +97,13 @@ void drawHomeScreen(bool buttonLockout) { if ((tipTemp < 50) && getSettingValue(SettingsOptions::Sensitivity) && (((xTaskGetTickCount() - lastMovementTime) > MOVEMENT_INACTIVITY_TIME) && ((xTaskGetTickCount() - lastButtonTime) > BUTTON_INACTIVITY_TIME))) { OLED::setDisplayState(OLED::DisplayState::OFF); - setStatusLED(LED_OFF, false); + setStatusLED(LED_OFF); } else { OLED::setDisplayState(OLED::DisplayState::ON); if (tipTemp > 55) { - setStatusLED(LED_COOLING_STILL_HOT, false); + setStatusLED(LED_COOLING_STILL_HOT); } else { - setStatusLED(LED_STANDBY, false); + setStatusLED(LED_STANDBY); } } // Clear the lcd buffer diff --git a/source/Core/Threads/OperatingModes/OperatingModes.h b/source/Core/Threads/OperatingModes/OperatingModes.h index 06f7070ec0..9e9e73cd34 100644 --- a/source/Core/Threads/OperatingModes/OperatingModes.h +++ b/source/Core/Threads/OperatingModes/OperatingModes.h @@ -37,6 +37,7 @@ void performCJCC(void); // Used to ca void gui_solderingTempAdjust(void); // For adjusting the setpoint temperature of the iron int gui_SolderingSleepingMode(bool stayOff, bool autoStarted); // Sleep mode void gui_solderingMode(uint8_t jumpToSleep); // Main mode for hot pointy tool +void gui_solderingProfileMode(); // Profile mode for hot likely-not-so-pointy tool void showDebugMenu(void); // Debugging values void showPDDebug(void); // Debugging menu that hows PD adaptor info void showWarnings(void); // Shows user warnings if required diff --git a/source/Core/Threads/OperatingModes/Soldering.cpp b/source/Core/Threads/OperatingModes/Soldering.cpp index 96b9b877bd..5cdd2c1f72 100644 --- a/source/Core/Threads/OperatingModes/Soldering.cpp +++ b/source/Core/Threads/OperatingModes/Soldering.cpp @@ -1,7 +1,7 @@ #include "OperatingModes.h" +#include "SolderingCommon.h" -extern bool heaterThermalRunaway; extern OperatingMode currentMode; void gui_solderingMode(uint8_t jumpToSleep) { @@ -21,36 +21,10 @@ void gui_solderingMode(uint8_t jumpToSleep) { */ bool boostModeOn = false; bool buttonsLocked = false; + bool converged = false; currentMode = OperatingMode::soldering; -#ifdef PROFILE_SUPPORT - bool waitForRelease = false; - TickType_t profileStartTime = 0; - TickType_t phaseStartTime = 0; - - uint16_t tipTemp = 0; - uint8_t profilePhase = 0; - - uint16_t phaseElapsedSeconds = 0; - uint16_t phaseTotalSeconds = 0; - uint16_t phaseStartTemp = 0; - uint16_t phaseEndTemp = 0; - uint16_t phaseTicksPerDegree = 0; - uint16_t profileCurrentTargetTemp = 0; - - ButtonState buttons = getButtonState(); - - if (buttons != BUTTON_NONE) { - // Soldering entered by long-pressing F button, profile mode - waitForRelease = true; - profileStartTime = xTaskGetTickCount(); - phaseStartTime = xTaskGetTickCount(); - phaseEndTemp = getSettingValue(SettingsOptions::ProfilePreheatTemp); - phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfilePreheatSpeed); - } -#else - ButtonState buttons; -#endif + TickType_t buzzerEnd = 0; if (jumpToSleep) { if (gui_SolderingSleepingMode(jumpToSleep == 2, true) == 1) { @@ -59,14 +33,7 @@ void gui_solderingMode(uint8_t jumpToSleep) { } } for (;;) { - buttons = getButtonState(); -#ifdef PROFILE_SUPPORT - if (buttons) { - if (waitForRelease) buttons = BUTTON_NONE; - } else { - waitForRelease = false; - } -#endif + ButtonState buttons = getButtonState(); if (buttonsLocked && (getSettingValue(SettingsOptions::LockingMode) != 0)) { // If buttons locked switch (buttons) { case BUTTON_NONE: @@ -79,9 +46,6 @@ void gui_solderingMode(uint8_t jumpToSleep) { break; case BUTTON_F_LONG: // if boost mode is enabled turn it on -#ifdef PROFILE_SUPPORT - if (profileStartTime != 0) break; // no boost in profile mode -#endif if (getSettingValue(SettingsOptions::BoostTemp) && (getSettingValue(SettingsOptions::LockingMode) == 1)) { boostModeOn = true; currentMode = OperatingMode::boost; @@ -109,9 +73,6 @@ void gui_solderingMode(uint8_t jumpToSleep) { case BUTTON_B_LONG: return; // exit on back long hold case BUTTON_F_LONG: -#ifdef PROFILE_SUPPORT - if (profileStartTime != 0) break; // no manual temp change in profile mode -#endif // if boost mode is enabled turn it on if (getSettingValue(SettingsOptions::BoostTemp)) { boostModeOn = true; @@ -120,9 +81,6 @@ void gui_solderingMode(uint8_t jumpToSleep) { break; case BUTTON_F_SHORT: case BUTTON_B_SHORT: { -#ifdef PROFILE_SUPPORT - if (profileStartTime != 0) break; // no manual temp change in profile mode -#endif uint16_t oldTemp = getSettingValue(SettingsOptions::SolderingTemp); gui_solderingTempAdjust(); // goto adjust temp mode if (oldTemp != getSettingValue(SettingsOptions::SolderingTemp)) { @@ -142,91 +100,6 @@ void gui_solderingMode(uint8_t jumpToSleep) { } // else we update the screen information -#ifdef PROFILE_SUPPORT - if (profileStartTime != 0) { - if (getSettingValue(SettingsOptions::TemperatureInF)) { - tipTemp = TipThermoModel::getTipInF(); - } else { - tipTemp = TipThermoModel::getTipInC(); - } - - // if start temp is unknown (preheat), we're setting it now - if (phaseStartTemp == 0) { - phaseStartTemp = tipTemp; - // if this is hotter than the preheat temperature, we should fail - if (phaseStartTemp >= 55) { - warnUser(translatedString(Tr->TooHotToStartProfileWarning), 10 * TICKS_SECOND); - return; - } - } - - phaseElapsedSeconds = (xTaskGetTickCount() - phaseStartTime) / TICKS_SECOND; - - // have we finished this phase? - if (phaseElapsedSeconds >= phaseTotalSeconds && tipTemp == phaseEndTemp) { - profilePhase++; - phaseStartTemp = phaseEndTemp; - phaseStartTime = xTaskGetTickCount(); - phaseElapsedSeconds = 0; - if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { - // done with all phases, lets go to cooldown - phaseTotalSeconds = 0; - phaseEndTemp = 0; - phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfileCooldownSpeed); - } else { - // set up next phase - switch(profilePhase) { - case 1: - phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase1Duration); - phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase1Temp); - break; - case 2: - phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase2Duration); - phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase2Temp); - break; - case 3: - phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase3Duration); - phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase3Temp); - break; - case 4: - phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase4Duration); - phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase4Temp); - break; - case 5: - phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase5Duration); - phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase5Temp); - break; - } - if (phaseStartTemp < phaseEndTemp) { - phaseTicksPerDegree = (phaseTotalSeconds * TICKS_SECOND) / (phaseEndTemp - phaseStartTemp); - } else { - phaseTicksPerDegree = (phaseTotalSeconds * TICKS_SECOND) / (phaseStartTemp - phaseEndTemp); - } - } - } - - // cooldown phase done? - if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { - if (TipThermoModel::getTipInC() < 55) { - // we're done, let the buzzer beep too - setStatusLED(LED_STANDBY, true); - return; - } - } - - // determine current target temp - if (phaseStartTemp < phaseEndTemp) { - if (profileCurrentTargetTemp < phaseEndTemp) { - profileCurrentTargetTemp = phaseStartTemp + ((xTaskGetTickCount() - phaseStartTime) / phaseTicksPerDegree); - } - } else { - if (profileCurrentTargetTemp > phaseEndTemp) { - profileCurrentTargetTemp = phaseStartTemp - ((xTaskGetTickCount() - phaseStartTime) / phaseTicksPerDegree); - } - } - } -#endif - OLED::clearScreen(); // Draw in the screen details if (getSettingValue(SettingsOptions::DetailedSoldering)) { @@ -236,66 +109,7 @@ void gui_solderingMode(uint8_t jumpToSleep) { OLED::setCursor(-1, 0); } -#ifdef PROFILE_SUPPORT - if (profileStartTime != 0) { - // print temperature - if (OLED::getRotation()) { - OLED::setCursor(48, 0); - } else { - OLED::setCursor(0, 0); - } - - OLED::printNumber(tipTemp, 3, FontStyle::SMALL); - OLED::print(SmallSymbolSlash, FontStyle::SMALL); - OLED::printNumber(profileCurrentTargetTemp, 3, FontStyle::SMALL); - - if (getSettingValue(SettingsOptions::TemperatureInF)) - OLED::print(SmallSymbolDegF, FontStyle::SMALL); - else - OLED::print(SmallSymbolDegC, FontStyle::SMALL); - - // print phase - if (profilePhase > 0 && profilePhase <= getSettingValue(SettingsOptions::ProfilePhases)) { - if (OLED::getRotation()) { - OLED::setCursor(36, 0); - } else { - OLED::setCursor(55, 0); - } - OLED::printNumber(profilePhase, 1, FontStyle::SMALL); - } - - // print time progress / preheat / cooldown - if (OLED::getRotation()) { - OLED::setCursor(42, 8); - } else { - OLED::setCursor(0, 8); - } - - if (profilePhase == 0) { - OLED::print(translatedString(Tr->ProfilePreheatString), FontStyle::SMALL); - } else if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { - OLED::print(translatedString(Tr->ProfileCooldownString), FontStyle::SMALL); - } else { - OLED::printNumber(phaseElapsedSeconds / 60, 1, FontStyle::SMALL); - OLED::print(SmallSymbolColon, FontStyle::SMALL); - OLED::printNumber(phaseElapsedSeconds % 60, 2, FontStyle::SMALL, false); - - OLED::print(SmallSymbolSlash, FontStyle::SMALL); - - // blink if we can't keep up with the time goal - if (phaseElapsedSeconds < phaseTotalSeconds+2 || (xTaskGetTickCount() / TICKS_SECOND) % 2 == 0) { - OLED::printNumber(phaseTotalSeconds / 60, 1, FontStyle::SMALL); - OLED::print(SmallSymbolColon, FontStyle::SMALL); - OLED::printNumber(phaseTotalSeconds % 60, 2, FontStyle::SMALL, false); - } - } - - } else { -#endif gui_drawTipTemp(true, FontStyle::LARGE); -#ifdef PROFILE_SUPPORT - } -#endif #ifndef NO_SLEEP_MODE if (getSettingValue(SettingsOptions::Sensitivity) && getSettingValue(SettingsOptions::SleepTime)) { @@ -317,78 +131,14 @@ void gui_solderingMode(uint8_t jumpToSleep) { OLED::print(SmallSymbolPlus, FontStyle::SMALL); } - if (OLED::getRotation()) { - OLED::setCursor(0, 0); - } else { - OLED::setCursor(67, 0); - } - // Print wattage - { - uint32_t x10Watt = x10WattHistory.average(); - if (x10Watt > 999) { // If we exceed 99.9W we drop the decimal place to keep it all fitting - OLED::print(SmallSymbolSpace, FontStyle::SMALL); - OLED::printNumber(x10WattHistory.average() / 10, 3, FontStyle::SMALL); - } else { - OLED::printNumber(x10WattHistory.average() / 10, 2, FontStyle::SMALL); - OLED::print(SmallSymbolDot, FontStyle::SMALL); - OLED::printNumber(x10WattHistory.average() % 10, 1, FontStyle::SMALL); - } - OLED::print(SmallSymbolWatts, FontStyle::SMALL); - } + detailedPowerStatus(); - if (OLED::getRotation()) { - OLED::setCursor(0, 8); - } else { - OLED::setCursor(67, 8); - } - printVoltage(); - OLED::print(SmallSymbolVolts, FontStyle::SMALL); } else { - OLED::setCursor(0, 0); - // We switch the layout direction depending on the orientation of the oled - if (OLED::getRotation()) { - // battery - gui_drawBatteryIcon(); - OLED::print(LargeSymbolSpace, FontStyle::LARGE); // Space out gap between battery <-> temp - gui_drawTipTemp(true, FontStyle::LARGE); // Draw current tip temp - - // We draw boost arrow if boosting, or else gap temp <-> heat - // indicator - if (boostModeOn) - OLED::drawSymbol(2); - else - OLED::print(LargeSymbolSpace, FontStyle::LARGE); - - // Draw heating/cooling symbols - OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); - } else { - // Draw heating/cooling symbols - OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); - // We draw boost arrow if boosting, or else gap temp <-> heat - // indicator - if (boostModeOn) - OLED::drawSymbol(2); - else - OLED::print(LargeSymbolSpace, FontStyle::LARGE); - gui_drawTipTemp(true, FontStyle::LARGE); // Draw current tip temp - - OLED::print(LargeSymbolSpace, FontStyle::LARGE); // Space out gap between battery <-> temp - - gui_drawBatteryIcon(); - } + basicSolderingStatus(boostModeOn); } OLED::refresh(); // Update the setpoints for the temperature -#ifdef PROFILE_SUPPORT - if (profileStartTime != 0) { - if (getSettingValue(SettingsOptions::TemperatureInF)) { - currentTempTargetDegC = TipThermoModel::convertFtoC(profileCurrentTargetTemp); - } else { - currentTempTargetDegC = profileCurrentTargetTemp; - } - } else -#endif if (boostModeOn) { if (getSettingValue(SettingsOptions::TemperatureInF)) currentTempTargetDegC = TipThermoModel::convertFtoC(getSettingValue(SettingsOptions::BoostTemp)); @@ -403,75 +153,31 @@ void gui_solderingMode(uint8_t jumpToSleep) { } } -#ifdef POW_DC - // Undervoltage test - if (checkForUnderVoltage()) { - lastButtonTime = xTaskGetTickCount(); + if (checkExitSoldering()) { + setBuzzer(false); return; } -#endif - -#ifdef ACCEL_EXITS_ON_MOVEMENT - // If the accel works in reverse where movement will cause exiting the soldering mode - if (getSettingValue(SettingsOptions::Sensitivity)) { - if (lastMovementTime) { - if (lastMovementTime > TICKS_SECOND * 10) { - // If we have moved recently; in the last second - // Then exit soldering mode - if (((TickType_t)(xTaskGetTickCount() - lastMovementTime)) < (TickType_t)(TICKS_SECOND)) { - currentTempTargetDegC = 0; - return; - } - } + // Update status + int error = currentTempTargetDegC - TipThermoModel::getTipInC(); + if (error >= -10 && error <= 10) { + // converged + if (!converged) { + setBuzzer(true); + buzzerEnd = xTaskGetTickCount() + TICKS_SECOND / 3; + converged = true; } - } -#endif -#ifdef NO_SLEEP_MODE - // No sleep mode, but still want shutdown timeout - - if (shouldShutdown()) { - // shutdown - currentTempTargetDegC = 0; - return; // we want to exit soldering mode - } -#endif - if (shouldBeSleeping(false)) { - if (gui_SolderingSleepingMode(false, false)) { - return; // If the function returns non-0 then exit - } - } -#ifdef PROFILE_SUPPORT - if (profileStartTime == 0) { -#endif - // Update LED status (manual mode) - int error = currentTempTargetDegC - TipThermoModel::getTipInC(); - if (error >= -10 && error <= 10) { - // converged - setStatusLED(LED_HOT, true); - } else { - setStatusLED(LED_HEATING, false); - } -#ifdef PROFILE_SUPPORT + setStatusLED(LED_HOT); } else { - // Update LED status (profile mode) - if (profilePhase == 0) { - setStatusLED(LED_HEATING, false); - } else if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { - setStatusLED(LED_COOLING_STILL_HOT, false); - } else { - setStatusLED(LED_HOT, false); - } + setStatusLED(LED_HEATING); + converged = false; } -#endif - // If we have tripped thermal runaway, turn off heater and show warning - if (heaterThermalRunaway) { - currentTempTargetDegC = 0; // heater control off - warnUser(translatedString(Tr->WarningThermalRunaway), 10 * TICKS_SECOND); - heaterThermalRunaway = false; - return; + if (buzzerEnd != 0 && xTaskGetTickCount() >= buzzerEnd) { + setBuzzer(false); } + // slow down ui update rate GUIDelay(); } } + diff --git a/source/Core/Threads/OperatingModes/SolderingProfile.cpp b/source/Core/Threads/OperatingModes/SolderingProfile.cpp new file mode 100644 index 0000000000..6b3eb28a8c --- /dev/null +++ b/source/Core/Threads/OperatingModes/SolderingProfile.cpp @@ -0,0 +1,236 @@ + +#include "OperatingModes.h" +#include "SolderingCommon.h" + +extern OperatingMode currentMode; + +void gui_solderingProfileMode() { + /* + * * Soldering (gui_solderingMode) + * -> Main loop where we draw temp, and animations + * --> User presses buttons and they goto the temperature adjust screen + * ---> Display the current setpoint temperature + * ---> Use buttons to change forward and back on temperature + * ---> Both buttons or timeout for exiting + * --> Long hold front button to enter boost mode + * ---> Just temporarily sets the system into the alternate temperature for + * PID control + * --> Long hold back button to exit + * --> Double button to exit + * --> Long hold double button to toggle key lock + */ + currentMode = OperatingMode::soldering; + + TickType_t buzzerEnd = 0; + + bool waitForRelease = true; + TickType_t profileStartTime = xTaskGetTickCount(); + TickType_t phaseStartTime = xTaskGetTickCount(); + + uint16_t tipTemp = 0; + uint8_t profilePhase = 0; + + uint16_t phaseElapsedSeconds = 0; + uint16_t phaseTotalSeconds = 0; + uint16_t phaseStartTemp = 0; + uint16_t phaseEndTemp = getSettingValue(SettingsOptions::ProfilePreheatTemp); + uint16_t phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfilePreheatSpeed); + uint16_t profileCurrentTargetTemp = 0; + + for (;;) { + ButtonState buttons = getButtonState(); + if (buttons) { + if (waitForRelease) buttons = BUTTON_NONE; + } else { + waitForRelease = false; + } + + switch (buttons) { + case BUTTON_NONE: + break; + case BUTTON_BOTH: + case BUTTON_B_LONG: + return; // exit on back long hold + case BUTTON_F_LONG: + case BUTTON_F_SHORT: + case BUTTON_B_SHORT: + // Not used yet + break; + default: + break; + } + + if (getSettingValue(SettingsOptions::TemperatureInF)) { + tipTemp = TipThermoModel::getTipInF(); + } else { + tipTemp = TipThermoModel::getTipInC(); + } + + // if start temp is unknown (preheat), we're setting it now + if (phaseStartTemp == 0) { + phaseStartTemp = tipTemp; + // if this is hotter than the preheat temperature, we should fail + if (phaseStartTemp >= 55) { + warnUser(translatedString(Tr->TooHotToStartProfileWarning), 10 * TICKS_SECOND); + return; + } + } + + phaseElapsedSeconds = (xTaskGetTickCount() - phaseStartTime) / TICKS_SECOND; + + // have we finished this phase? + if (phaseElapsedSeconds >= phaseTotalSeconds && tipTemp == phaseEndTemp) { + profilePhase++; + phaseStartTemp = phaseEndTemp; + phaseStartTime = xTaskGetTickCount(); + phaseElapsedSeconds = 0; + if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { + // done with all phases, lets go to cooldown + phaseTotalSeconds = 0; + phaseEndTemp = 0; + phaseTicksPerDegree = TICKS_SECOND / getSettingValue(SettingsOptions::ProfileCooldownSpeed); + } else { + // set up next phase + switch(profilePhase) { + case 1: + phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase1Duration); + phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase1Temp); + break; + case 2: + phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase2Duration); + phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase2Temp); + break; + case 3: + phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase3Duration); + phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase3Temp); + break; + case 4: + phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase4Duration); + phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase4Temp); + break; + case 5: + phaseTotalSeconds = getSettingValue(SettingsOptions::ProfilePhase5Duration); + phaseEndTemp = getSettingValue(SettingsOptions::ProfilePhase5Temp); + break; + default: + break; + } + if (phaseStartTemp < phaseEndTemp) { + phaseTicksPerDegree = (phaseTotalSeconds * TICKS_SECOND) / (phaseEndTemp - phaseStartTemp); + } else { + phaseTicksPerDegree = (phaseTotalSeconds * TICKS_SECOND) / (phaseStartTemp - phaseEndTemp); + } + } + } + + // cooldown phase done? + if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { + if (TipThermoModel::getTipInC() < 55) { + // we're done, let the buzzer beep too + setStatusLED(LED_STANDBY); + if (buzzerEnd == 0) { + setBuzzer(true); + buzzerEnd = xTaskGetTickCount() + TICKS_SECOND / 3; + } + } + } + + // determine current target temp + if (phaseStartTemp < phaseEndTemp) { + if (profileCurrentTargetTemp < phaseEndTemp) { + profileCurrentTargetTemp = phaseStartTemp + ((xTaskGetTickCount() - phaseStartTime) / phaseTicksPerDegree); + } + } else { + if (profileCurrentTargetTemp > phaseEndTemp) { + profileCurrentTargetTemp = phaseStartTemp - ((xTaskGetTickCount() - phaseStartTime) / phaseTicksPerDegree); + } + } + + OLED::clearScreen(); + // Draw in the screen details + if (getSettingValue(SettingsOptions::DetailedSoldering)) { + // print temperature + if (OLED::getRotation()) { + OLED::setCursor(48, 0); + } else { + OLED::setCursor(0, 0); + } + + OLED::printNumber(tipTemp, 3, FontStyle::SMALL); + OLED::print(SmallSymbolSlash, FontStyle::SMALL); + OLED::printNumber(profileCurrentTargetTemp, 3, FontStyle::SMALL); + + if (getSettingValue(SettingsOptions::TemperatureInF)) + OLED::print(SmallSymbolDegF, FontStyle::SMALL); + else + OLED::print(SmallSymbolDegC, FontStyle::SMALL); + + // print phase + if (profilePhase > 0 && profilePhase <= getSettingValue(SettingsOptions::ProfilePhases)) { + if (OLED::getRotation()) { + OLED::setCursor(36, 0); + } else { + OLED::setCursor(55, 0); + } + OLED::printNumber(profilePhase, 1, FontStyle::SMALL); + } + + // print time progress / preheat / cooldown + if (OLED::getRotation()) { + OLED::setCursor(42, 8); + } else { + OLED::setCursor(0, 8); + } + + if (profilePhase == 0) { + OLED::print(translatedString(Tr->ProfilePreheatString), FontStyle::SMALL); + } else if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { + OLED::print(translatedString(Tr->ProfileCooldownString), FontStyle::SMALL); + } else { + OLED::printNumber(phaseElapsedSeconds / 60, 1, FontStyle::SMALL); + OLED::print(SmallSymbolColon, FontStyle::SMALL); + OLED::printNumber(phaseElapsedSeconds % 60, 2, FontStyle::SMALL, false); + + OLED::print(SmallSymbolSlash, FontStyle::SMALL); + + // blink if we can't keep up with the time goal + if (phaseElapsedSeconds < phaseTotalSeconds+2 || (xTaskGetTickCount() / TICKS_SECOND) % 2 == 0) { + OLED::printNumber(phaseTotalSeconds / 60, 1, FontStyle::SMALL); + OLED::print(SmallSymbolColon, FontStyle::SMALL); + OLED::printNumber(phaseTotalSeconds % 60, 2, FontStyle::SMALL, false); + } + } + + detailedPowerStatus(); + + } else { + basicSolderingStatus(false); + } + + OLED::refresh(); + // Update the setpoints for the temperature + if (getSettingValue(SettingsOptions::TemperatureInF)) { + currentTempTargetDegC = TipThermoModel::convertFtoC(profileCurrentTargetTemp); + } else { + currentTempTargetDegC = profileCurrentTargetTemp; + } + + if (checkExitSoldering() || (buzzerEnd != 0 && xTaskGetTickCount() >= buzzerEnd)) { + setBuzzer(false); + return; + } + + // Update LED status + if (profilePhase == 0) { + setStatusLED(LED_HEATING); + } else if (profilePhase > getSettingValue(SettingsOptions::ProfilePhases)) { + setStatusLED(LED_COOLING_STILL_HOT); + } else { + setStatusLED(LED_HOT); + } + + // slow down ui update rate + GUIDelay(); + } +} + diff --git a/source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp b/source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp new file mode 100644 index 0000000000..0feb65d3eb --- /dev/null +++ b/source/Core/Threads/OperatingModes/utils/SolderingCommon.cpp @@ -0,0 +1,123 @@ +// +// Created by laura on 24.04.23. +// + +#include "OperatingModes.h" +#include "SolderingCommon.h" + +extern bool heaterThermalRunaway; + +void detailedPowerStatus() { + if (OLED::getRotation()) { + OLED::setCursor(0, 0); + } else { + OLED::setCursor(67, 0); + } + // Print wattage + { + uint32_t x10Watt = x10WattHistory.average(); + if (x10Watt > 999) { // If we exceed 99.9W we drop the decimal place to keep it all fitting + OLED::print(SmallSymbolSpace, FontStyle::SMALL); + OLED::printNumber(x10WattHistory.average() / 10, 3, FontStyle::SMALL); + } else { + OLED::printNumber(x10WattHistory.average() / 10, 2, FontStyle::SMALL); + OLED::print(SmallSymbolDot, FontStyle::SMALL); + OLED::printNumber(x10WattHistory.average() % 10, 1, FontStyle::SMALL); + } + OLED::print(SmallSymbolWatts, FontStyle::SMALL); + } + + if (OLED::getRotation()) { + OLED::setCursor(0, 8); + } else { + OLED::setCursor(67, 8); + } + printVoltage(); + OLED::print(SmallSymbolVolts, FontStyle::SMALL); +} + +void basicSolderingStatus(bool boostModeOn) { + OLED::setCursor(0, 0); + // We switch the layout direction depending on the orientation of the oled + if (OLED::getRotation()) { + // battery + gui_drawBatteryIcon(); + OLED::print(LargeSymbolSpace, FontStyle::LARGE); // Space out gap between battery <-> temp + gui_drawTipTemp(true, FontStyle::LARGE); // Draw current tip temp + + // We draw boost arrow if boosting, or else gap temp <-> heat + // indicator + if (boostModeOn) + OLED::drawSymbol(2); + else + OLED::print(LargeSymbolSpace, FontStyle::LARGE); + + // Draw heating/cooling symbols + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); + } else { + // Draw heating/cooling symbols + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); + // We draw boost arrow if boosting, or else gap temp <-> heat + // indicator + if (boostModeOn) + OLED::drawSymbol(2); + else + OLED::print(LargeSymbolSpace, FontStyle::LARGE); + gui_drawTipTemp(true, FontStyle::LARGE); // Draw current tip temp + + OLED::print(LargeSymbolSpace, FontStyle::LARGE); // Space out gap between battery <-> temp + + gui_drawBatteryIcon(); + } +} + +bool checkExitSoldering(void) { +#ifdef POW_DC + // Undervoltage test + if (checkForUnderVoltage()) { + lastButtonTime = xTaskGetTickCount(); + return true; + } +#endif + +#ifdef ACCEL_EXITS_ON_MOVEMENT + // If the accel works in reverse where movement will cause exiting the soldering mode + if (getSettingValue(Sensitivity)) { + if (lastMovementTime) { + if (lastMovementTime > TICKS_SECOND * 10) { + // If we have moved recently; in the last second + // Then exit soldering mode + + if (((TickType_t)(xTaskGetTickCount() - lastMovementTime)) < (TickType_t)(TICKS_SECOND)) { + currentTempTargetDegC = 0; + return true; + } + } + } + } +#endif +#ifdef NO_SLEEP_MODE + // No sleep mode, but still want shutdown timeout + + if (shouldShutdown()) { + // shutdown + currentTempTargetDegC = 0; + return true; // we want to exit soldering mode + } +#endif + if (shouldBeSleeping(false)) { + if (gui_SolderingSleepingMode(false, false)) { + return true; // If the function returns non-0 then exit + } + } + + // If we have tripped thermal runaway, turn off heater and show warning + if (heaterThermalRunaway) { + currentTempTargetDegC = 0; // heater control off + warnUser(translatedString(Tr->WarningThermalRunaway), 10 * TICKS_SECOND); + heaterThermalRunaway = false; + return true; + } + + return false; +} \ No newline at end of file diff --git a/source/Core/Threads/OperatingModes/utils/SolderingCommon.h b/source/Core/Threads/OperatingModes/utils/SolderingCommon.h new file mode 100644 index 0000000000..4b45a5836d --- /dev/null +++ b/source/Core/Threads/OperatingModes/utils/SolderingCommon.h @@ -0,0 +1,8 @@ +#ifndef SOLDERINGMODEUTILITIES_H +#define SOLDERINGMODEUTILITIES_H + +void detailedPowerStatus(); +void basicSolderingStatus(bool boostModeOn); +bool checkExitSoldering(); + +#endif //SOLDERINGMODEUTILITIES_H