From cb2e8af7006dafd9db076a88c84efc4837b40c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laura=20Kl=C3=BCnder?= Date: Sun, 23 Apr 2023 23:48:24 +0200 Subject: [PATCH] full profile support --- Translations/make_translation.py | 2 + Translations/translation_EN.json | 9 + Translations/translations_definitions.json | 69 ++++-- source/Core/BSP/BSP.h | 2 +- source/Core/BSP/MHP30/BSP.cpp | 10 +- source/Core/BSP/MHP30/configuration.h | 2 +- source/Core/BSP/Miniware/BSP.cpp | 2 +- source/Core/BSP/Pinecil/BSP.cpp | 2 +- source/Core/BSP/Pinecilv2/BSP.cpp | 2 +- source/Core/Inc/Translation.h | 6 + source/Core/Src/Settings.cpp | 12 +- source/Core/Src/settingsGUI.cpp | 50 ++-- .../Threads/OperatingModes/HomeScreen.cpp | 19 +- .../Core/Threads/OperatingModes/Soldering.cpp | 230 +++++++++++++++++- .../OperatingModes/TemperatureAdjust.cpp | 4 +- 15 files changed, 334 insertions(+), 87 deletions(-) diff --git a/Translations/make_translation.py b/Translations/make_translation.py index 9a6341c6..dbe4c9a4 100755 --- a/Translations/make_translation.py +++ b/Translations/make_translation.py @@ -101,6 +101,8 @@ def get_constants() -> List[Tuple[str, str]]: ("SmallSymbolSpace", " "), ("LargeSymbolDot", "."), ("SmallSymbolDot", "."), + ("SmallSymbolSlash", "/"), + ("SmallSymbolColon", ":"), ("LargeSymbolDegC", "C"), ("SmallSymbolDegC", "C"), ("LargeSymbolDegF", "F"), diff --git a/Translations/translation_EN.json b/Translations/translation_EN.json index 1c4fb67b..29eefd10 100644 --- a/Translations/translation_EN.json +++ b/Translations/translation_EN.json @@ -60,8 +60,17 @@ "OffString": { "message": "Off" }, + "ProfilePreheatString": { + "message": "Preheat\n" + }, + "ProfileCooldownString": { + "message": "Cooldown\n" + }, "DeviceFailedValidationWarning": { "message": "Your device is most likely a counterfeit!" + }, + "TooHotToStartProfileWarning": { + "message": "Too hot to\nstart profile" } }, "characters": { diff --git a/Translations/translations_definitions.json b/Translations/translations_definitions.json index 3ab7177a..875dd2cb 100644 --- a/Translations/translations_definitions.json +++ b/Translations/translations_definitions.json @@ -62,6 +62,16 @@ "note": "Preferably end with a space", "description": "Prefix text for 'Input Voltage' shown before showing the input voltage reading." }, + { + "id": "ProfilePreheatString", + "maxLen": 9, + "description": "Shown when the soldering profile is preheating" + }, + { + "id": "ProfileCooldownString", + "maxLen": 9, + "description": "Shown when the soldering profile is done and cooling down" + }, { "id": "SleepingSimpleString", "maxLen": 4, @@ -86,6 +96,11 @@ "id": "DeviceFailedValidationWarning", "default": "Device may be\ncounterfeit", "description": "Warning shown if the device may be a clone or counterfeit unit." + }, + { + "id": "TooHotToStartProfileWarning", + "default": "Too hot to\nstart profile", + "description": "Shown when profile mode is started while the device is too hot." } ], "characters": [{ @@ -257,84 +272,84 @@ "id": "ProfilePhases", "maxLen": 6, "maxLen2": 13, - "description": "Enable / set the number of phases for the soldering profile." + "description": "set the number of phases for the soldering profile." }, { "id": "ProfilePreheatTemp", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "For the soldering profile, preheat to this temperature before proceeding with phase 1." }, { "id": "ProfilePreheatSpeed", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 5, + "maxLen2": 11, "description": "How fast the temperature is allowed to rise during the heatup phase of the soldering profile." }, { "id": "ProfilePhase1Temp", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Target temperature for the end of phase 1 of the soldering profile." }, { "id": "ProfilePhase1Duration", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Duration of phase 1 of the soldering profile. The phase might actually take longer if it takes longer to reach the target temperature." }, { "id": "ProfilePhase2Temp", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Target temperature for the end of phase 2 of the soldering profile." }, { "id": "ProfilePhase2Duration", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Duration of phase 2 of the soldering profile. The phase might actually take longer if it takes longer to reach the target temperature." }, { "id": "ProfilePhase3Temp", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Target temperature for the end of phase 3 of the soldering profile." }, { "id": "ProfilePhase3Duration", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Duration of phase 3 of the soldering profile. The phase might actually take longer if it takes longer to reach the target temperature." }, { "id": "ProfilePhase4Temp", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Target temperature for the end of phase 5 of the soldering profile." }, { "id": "ProfilePhase4Duration", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Duration of phase 5 of the soldering profile. The phase might actually take longer if it takes longer to reach the target temperature." }, { "id": "ProfilePhase5Temp", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Target temperature for the end of phase 5 of the soldering profile." }, { "id": "ProfilePhase5Duration", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 4, + "maxLen2": 9, "description": "Duration of phase 5 of the soldering profile. The phase might actually take longer if it takes longer to reach the target temperature." }, { "id": "ProfileCooldownSpeed", - "maxLen": 6, - "maxLen2": 13, + "maxLen": 5, + "maxLen2": 11, "description": "How fast the temperature is allowed to drop after the last phase of the soldering profile." }, { diff --git a/source/Core/BSP/BSP.h b/source/Core/BSP/BSP.h index 574d98d2..ae949113 100644 --- a/source/Core/BSP/BSP.h +++ b/source/Core/BSP/BSP.h @@ -92,7 +92,7 @@ enum StatusLED { LED_COOLING_STILL_HOT, // The unit is off and cooling but still hot LED_UNKNOWN, // }; -void setStatusLED(const enum StatusLED state); +void setStatusLED(enum StatusLED state, bool buzzer); // 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 a9e686d9..a269bcc4 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) { +void setStatusLED(const enum StatusLED state, bool buzzer) { static enum StatusLED lastState = LED_UNKNOWN; static TickType_t buzzerEnd = 0; @@ -455,17 +455,19 @@ void setStatusLED(const enum StatusLED state) { } break; case LED_HOT: ws2812.led_set_color(0, 0xFF, 0, 0); // red - // We have hit the right temp, run buzzer for a short period - buzzerEnd = xTaskGetTickCount() + TICKS_SECOND / 3; break; case LED_COOLING_STILL_HOT: 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 (state == LED_HOT && xTaskGetTickCount() < buzzerEnd) { + if (xTaskGetTickCount() < buzzerEnd) { setBuzzer(true); } else { setBuzzer(false); diff --git a/source/Core/BSP/MHP30/configuration.h b/source/Core/BSP/MHP30/configuration.h index af5bae52..7cb7e1bd 100644 --- a/source/Core/BSP/MHP30/configuration.h +++ b/source/Core/BSP/MHP30/configuration.h @@ -155,7 +155,7 @@ #define ACCEL_SC7 #define ACCEL_MSA -#define PROFILE_MODE +#define PROFILE_SUPPORT #define POW_PD 1 #define TEMP_NTC diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index 2cc36e6e..55c06c82 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) {} +void setStatusLED(const enum StatusLED state, bool buzzer) {} 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 5bac313d..96b880d1 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) {} +void setStatusLED(const enum StatusLED state, bool buzzer) {} 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 eb996bd8..14b58f0d 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) { +void setStatusLED(const enum StatusLED state, bool buzzer) { // Dont have one } diff --git a/source/Core/Inc/Translation.h b/source/Core/Inc/Translation.h index 9aa017f2..4ff9ae88 100644 --- a/source/Core/Inc/Translation.h +++ b/source/Core/Inc/Translation.h @@ -23,6 +23,8 @@ extern const char *SmallSymbolAmps; extern const char *LargeSymbolAmps; extern const char *SmallSymbolDot; extern const char *LargeSymbolDot; +extern const char *SmallSymbolSlash; +extern const char *SmallSymbolColon; extern const char *SmallSymbolDegC; extern const char *LargeSymbolDegC; extern const char *SmallSymbolDegF; @@ -121,12 +123,15 @@ struct TranslationIndexTable { uint16_t UVLOWarningString; uint16_t UndervoltageString; uint16_t InputVoltageString; + uint16_t ProfilePreheatString; + uint16_t ProfileCooldownString; uint16_t SleepingSimpleString; uint16_t SleepingAdvancedString; uint16_t SleepingTipAdvancedString; uint16_t OffString; uint16_t DeviceFailedValidationWarning; + uint16_t TooHotToStartProfileWarning; uint16_t SettingRightChar; uint16_t SettingLeftChar; @@ -142,6 +147,7 @@ struct TranslationIndexTable { uint16_t SettingLockDisableChar; uint16_t SettingLockBoostChar; uint16_t SettingLockFullChar; + uint16_t SolderingPhaseChar; uint16_t SettingsDescriptions[static_cast(SettingsItemIndex::NUM_ITEMS)]; uint16_t SettingsShortNames[static_cast(SettingsItemIndex::NUM_ITEMS)]; diff --git a/source/Core/Src/Settings.cpp b/source/Core/Src/Settings.cpp index 812c7a49..9a06592b 100644 --- a/source/Core/Src/Settings.cpp +++ b/source/Core/Src/Settings.cpp @@ -88,19 +88,19 @@ static const SettingConstants settingsConstants[(int)SettingsOptions::SettingsOp {0, 1, 1, 0}, // CalibrateCJC {0, 1, 1, 1}, // BluetoothLE {0, 1, 1, 1}, // PDVpdo - {0, 5, 1, 4}, // ProfilePhases + {1, 5, 1, 4}, // ProfilePhases {MIN_TEMP_C, MAX_TEMP_F, 5, 90}, // ProfilePreheatTemp {1, 10, 1, 1}, // ProfilePreheatSpeed {MIN_TEMP_C, MAX_TEMP_F, 5, 130}, // ProfilePhase1Temp - {10, 120, 5, 90}, // ProfilePhase1Duration + {10, 180, 5, 90}, // ProfilePhase1Duration {MIN_TEMP_C, MAX_TEMP_F, 5, 140}, // ProfilePhase2Temp - {10, 120, 5, 30}, // ProfilePhase2Duration + {10, 180, 5, 30}, // ProfilePhase2Duration {MIN_TEMP_C, MAX_TEMP_F, 5, 165}, // ProfilePhase3Temp - {10, 120, 5, 30}, // ProfilePhase3Duration + {10, 180, 5, 30}, // ProfilePhase3Duration {MIN_TEMP_C, MAX_TEMP_F, 5, 140}, // ProfilePhase4Temp - {10, 120, 5, 30}, // ProfilePhase4Duration + {10, 180, 5, 30}, // ProfilePhase4Duration {MIN_TEMP_C, MAX_TEMP_F, 5, 90}, // ProfilePhase5Temp - {10, 120, 5, 30}, // ProfilePhase5Duration + {10, 180, 5, 30}, // ProfilePhase5Duration {1, 10, 1, 2}, // ProfileCooldownSpeed }; static_assert((sizeof(settingsConstants) / sizeof(SettingConstants)) == ((int)SettingsOptions::SettingsOptionsLength)); diff --git a/source/Core/Src/settingsGUI.cpp b/source/Core/Src/settingsGUI.cpp index 33d64ab0..5af8d2d3 100644 --- a/source/Core/Src/settingsGUI.cpp +++ b/source/Core/Src/settingsGUI.cpp @@ -53,7 +53,7 @@ static void displayDisplayRotation(void); static bool setBoostTemp(void); static void displayBoostTemp(void); -#ifdef PROFILE_MODE +#ifdef PROFILE_SUPPORT static bool setProfilePreheatTemp(); static bool setProfilePhase1Temp(); static bool setProfilePhase2Temp(); @@ -248,21 +248,21 @@ const menuitem solderingMenu[] = { {SETTINGS_DESC(SettingsItemIndex::TempChangeLongStep), nullptr, displayTempChangeLongStep, nullptr, SettingsOptions::TempChangeLongStep, SettingsItemIndex::TempChangeLongStep, 6}, /*Temp change long step*/ {SETTINGS_DESC(SettingsItemIndex::LockingMode), nullptr, displayLockingMode, nullptr, SettingsOptions::LockingMode, SettingsItemIndex::LockingMode, 7}, /*Locking Mode*/ -#ifdef PROFILE_MODE - {SETTINGS_DESC(SettingsItemIndex::ProfilePhases), nullptr, displayProfilePhases, nullptr, SettingsOptions::ProfilePhases, SettingsItemIndex::ProfilePhases, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePreheatTemp), setProfilePreheatTemp, displayProfilePreheatTemp, showProfileOptions, SettingsOptions::ProfilePreheatTemp, SettingsItemIndex::ProfilePreheatTemp, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePreheatSpeed), nullptr, displayProfilePreheatSpeed, showProfileOptions, SettingsOptions::ProfilePreheatSpeed, SettingsItemIndex::ProfilePreheatSpeed, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase1Temp, displayProfilePhase1Temp, showProfileOptions, SettingsOptions::ProfilePhase1Temp, SettingsItemIndex::ProfilePhase1Temp, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase1Duration, showProfileOptions, SettingsOptions::ProfilePhase1Duration, SettingsItemIndex::ProfilePhase1Duration, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase2Temp, displayProfilePhase2Temp, showProfilePhase2Options, SettingsOptions::ProfilePhase2Temp, SettingsItemIndex::ProfilePhase2Temp, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase2Duration, showProfilePhase2Options, SettingsOptions::ProfilePhase2Duration, SettingsItemIndex::ProfilePhase2Duration, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase3Temp, displayProfilePhase3Temp, showProfilePhase3Options, SettingsOptions::ProfilePhase3Temp, SettingsItemIndex::ProfilePhase3Temp, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase3Duration, showProfilePhase3Options, SettingsOptions::ProfilePhase3Duration, SettingsItemIndex::ProfilePhase3Duration, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase4Temp, displayProfilePhase4Temp, showProfilePhase4Options, SettingsOptions::ProfilePhase4Temp, SettingsItemIndex::ProfilePhase4Temp, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase4Duration, showProfilePhase4Options, SettingsOptions::ProfilePhase4Duration, SettingsItemIndex::ProfilePhase4Duration, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase5Temp, displayProfilePhase5Temp, showProfilePhase5Options, SettingsOptions::ProfilePhase5Temp, SettingsItemIndex::ProfilePhase5Temp, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase5Duration, showProfilePhase5Options, SettingsOptions::ProfilePhase5Duration, SettingsItemIndex::ProfilePhase5Duration, 5}, /*Boost Temp*/ - {SETTINGS_DESC(SettingsItemIndex::ProfileCooldownSpeed), nullptr, displayProfileCooldownSpeed, showProfileOptions, SettingsOptions::ProfileCooldownSpeed, SettingsItemIndex::ProfileCooldownSpeed, 5}, /*Boost Temp*/ +#ifdef PROFILE_SUPPORT + {SETTINGS_DESC(SettingsItemIndex::ProfilePhases), nullptr, displayProfilePhases, nullptr, SettingsOptions::ProfilePhases, SettingsItemIndex::ProfilePhases, 7}, /*Profile Phases*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePreheatTemp), setProfilePreheatTemp, displayProfilePreheatTemp, showProfileOptions, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePreheatTemp, 5}, /*Profile Preheat Temp*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePreheatSpeed), nullptr, displayProfilePreheatSpeed, showProfileOptions, SettingsOptions::ProfilePreheatSpeed, SettingsItemIndex::ProfilePreheatSpeed, 5}, /*Profile Preheat Speed*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase1Temp, displayProfilePhase1Temp, showProfileOptions, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase1Temp, 5}, /*Phase 1 Temp*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase1Duration, showProfileOptions, SettingsOptions::ProfilePhase1Duration, SettingsItemIndex::ProfilePhase1Duration, 5}, /*Phase 1 Duration*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase2Temp, displayProfilePhase2Temp, showProfilePhase2Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase2Temp, 5}, /*Phase 2 Temp*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase2Duration, showProfilePhase2Options, SettingsOptions::ProfilePhase2Duration, SettingsItemIndex::ProfilePhase2Duration, 5}, /*Phase 2 Duration*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase3Temp, displayProfilePhase3Temp, showProfilePhase3Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase3Temp, 5}, /*Phase 3 Temp*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase3Duration, showProfilePhase3Options, SettingsOptions::ProfilePhase3Duration, SettingsItemIndex::ProfilePhase3Duration, 5}, /*Phase 3 Duration*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase4Temp, displayProfilePhase4Temp, showProfilePhase4Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase4Temp, 5}, /*Phase 4 Temp*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase4Duration, showProfilePhase4Options, SettingsOptions::ProfilePhase4Duration, SettingsItemIndex::ProfilePhase4Duration, 5}, /*Phase 4 Duration*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Temp), setProfilePhase5Temp, displayProfilePhase5Temp, showProfilePhase5Options, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::ProfilePhase5Temp, 5}, /*Phase 5 Temp*/ + {SETTINGS_DESC(SettingsItemIndex::ProfilePhase1Duration), nullptr, displayProfilePhase5Duration, showProfilePhase5Options, SettingsOptions::ProfilePhase5Duration, SettingsItemIndex::ProfilePhase5Duration, 5}, /*Phase 5 Duration*/ + {SETTINGS_DESC(SettingsItemIndex::ProfileCooldownSpeed), nullptr, displayProfileCooldownSpeed, showProfileOptions, SettingsOptions::ProfileCooldownSpeed, SettingsItemIndex::ProfileCooldownSpeed, 5}, /*Profile Cooldown Speed*/ {0, nullptr, nullptr, nullptr, SettingsOptions::SettingsOptionsLength, SettingsItemIndex::NUM_ITEMS, 0} // end of menu marker. DO NOT REMOVE #endif }; @@ -524,14 +524,10 @@ static void displayLockingMode(void) { } } -#ifdef PROFILE_MODE +#ifdef PROFILE_SUPPORT static void displayProfilePhases(void) { - if (getSettingValue(SettingsOptions::ProfilePhases)) { - OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhases), 1, FontStyle::LARGE); - } else { - OLED::print(translatedString(Tr->OffString), FontStyle::LARGE); - } + OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhases), 1, FontStyle::LARGE); } static bool setProfileTemp(const enum SettingsOptions option) { @@ -568,10 +564,10 @@ static void displayProfilePhase5Temp(void) { OLED::printNumber(getSettingValue(S static void displayProfilePreheatSpeed(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePreheatSpeed), 2, FontStyle::LARGE); } static void displayProfileCooldownSpeed(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfileCooldownSpeed), 2, FontStyle::LARGE); } static void displayProfilePhase1Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase1Duration), 3, FontStyle::LARGE); } -static void displayProfilePhase2Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase1Duration), 3, FontStyle::LARGE); } -static void displayProfilePhase3Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase1Duration), 3, FontStyle::LARGE); } -static void displayProfilePhase4Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase1Duration), 3, FontStyle::LARGE); } -static void displayProfilePhase5Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase1Duration), 3, FontStyle::LARGE); } +static void displayProfilePhase2Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase2Duration), 3, FontStyle::LARGE); } +static void displayProfilePhase3Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase3Duration), 3, FontStyle::LARGE); } +static void displayProfilePhase4Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase4Duration), 3, FontStyle::LARGE); } +static void displayProfilePhase5Duration(void) { OLED::printNumber(getSettingValue(SettingsOptions::ProfilePhase5Duration), 3, FontStyle::LARGE); } static bool showProfileOptions(void) { return getSettingValue(SettingsOptions::ProfilePhases); } static bool showProfilePhase2Options(void) { return getSettingValue(SettingsOptions::ProfilePhases) >= 2; } @@ -659,7 +655,7 @@ static bool setTempF(void) { #ifndef NO_SLEEP_MODE setTempF(SettingsOptions::SleepTemp); #endif -#ifdef PROFILE_MODE +#ifdef PROFILE_SUPPORT setTempF(SettingsOptions::ProfilePreheatTemp); setTempF(SettingsOptions::ProfilePhase1Temp); setTempF(SettingsOptions::ProfilePhase2Temp); diff --git a/source/Core/Threads/OperatingModes/HomeScreen.cpp b/source/Core/Threads/OperatingModes/HomeScreen.cpp index d9dbc7bf..7874bf85 100644 --- a/source/Core/Threads/OperatingModes/HomeScreen.cpp +++ b/source/Core/Threads/OperatingModes/HomeScreen.cpp @@ -55,8 +55,11 @@ void drawHomeScreen(bool buttonLockout) { showDebugMenu(); break; case BUTTON_F_LONG: -#ifdef PROFILE_MODE - // todo: add profile mode +#ifdef PROFILE_SUPPORT + if (!isTipDisconnected()) { + gui_solderingMode(0); // enter soldering mode + buttonLockout = true; + } #else gui_solderingTempAdjust(); saveSettings(); @@ -84,11 +87,6 @@ void drawHomeScreen(bool buttonLockout) { currentTempTargetDegC = 0; // ensure tip is off getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0); uint32_t tipTemp = TipThermoModel::getTipInC(); - if (tipTemp > 55) { - setStatusLED(LED_COOLING_STILL_HOT); - } else { - setStatusLED(LED_STANDBY); - } // Preemptively turn the display on. Turn it off if and only if // the tip temperature is below 50 degrees C *and* motion sleep // detection is enabled *and* there has been no activity (movement or @@ -99,9 +97,14 @@ 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); + setStatusLED(LED_OFF, false); } else { OLED::setDisplayState(OLED::DisplayState::ON); + if (tipTemp > 55) { + setStatusLED(LED_COOLING_STILL_HOT, false); + } else { + setStatusLED(LED_STANDBY, false); + } } // Clear the lcd buffer OLED::clearScreen(); diff --git a/source/Core/Threads/OperatingModes/Soldering.cpp b/source/Core/Threads/OperatingModes/Soldering.cpp index aa0416d2..96b9b877 100644 --- a/source/Core/Threads/OperatingModes/Soldering.cpp +++ b/source/Core/Threads/OperatingModes/Soldering.cpp @@ -23,6 +23,35 @@ void gui_solderingMode(uint8_t jumpToSleep) { bool buttonsLocked = 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 + if (jumpToSleep) { if (gui_SolderingSleepingMode(jumpToSleep == 2, true) == 1) { lastButtonTime = xTaskGetTickCount(); @@ -30,7 +59,14 @@ void gui_solderingMode(uint8_t jumpToSleep) { } } for (;;) { - ButtonState buttons = getButtonState(); + buttons = getButtonState(); +#ifdef PROFILE_SUPPORT + if (buttons) { + if (waitForRelease) buttons = BUTTON_NONE; + } else { + waitForRelease = false; + } +#endif if (buttonsLocked && (getSettingValue(SettingsOptions::LockingMode) != 0)) { // If buttons locked switch (buttons) { case BUTTON_NONE: @@ -43,6 +79,9 @@ 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; @@ -70,6 +109,9 @@ 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; @@ -78,6 +120,9 @@ 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)) { @@ -97,8 +142,92 @@ void gui_solderingMode(uint8_t jumpToSleep) { } // else we update the screen information - OLED::clearScreen(); +#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)) { if (OLED::getRotation()) { @@ -106,7 +235,67 @@ void gui_solderingMode(uint8_t jumpToSleep) { } else { 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)) { @@ -188,8 +377,18 @@ void gui_solderingMode(uint8_t jumpToSleep) { gui_drawBatteryIcon(); } } + 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)); @@ -242,14 +441,29 @@ void gui_solderingMode(uint8_t jumpToSleep) { return; // If the function returns non-0 then exit } } - // Update LED status - int error = currentTempTargetDegC - TipThermoModel::getTipInC(); - if (error >= -10 && error <= 10) { - // converged - setStatusLED(LED_HOT); +#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 } else { - setStatusLED(LED_HEATING); + // 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); + } } +#endif // If we have tripped thermal runaway, turn off heater and show warning if (heaterThermalRunaway) { currentTempTargetDegC = 0; // heater control off diff --git a/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp b/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp index 3593b82d..5c05a520 100644 --- a/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp +++ b/source/Core/Threads/OperatingModes/TemperatureAdjust.cpp @@ -4,7 +4,7 @@ void gui_solderingTempAdjust(void) { currentTempTargetDegC = 0; // Turn off heater while adjusting temp TickType_t autoRepeatTimer = 0; uint8_t autoRepeatAcceleration = 0; -#ifndef PROFILE_MODE +#ifndef PROFILE_SUPPORT bool waitForRelease = false; ButtonState buttons = getButtonState(); @@ -22,7 +22,7 @@ void gui_solderingTempAdjust(void) { buttons = getButtonState(); if (buttons) { lastChange = xTaskGetTickCount(); -#ifndef PROFILE_MODE +#ifndef PROFILE_SUPPORT if (waitForRelease) { buttons = BUTTON_NONE; }