From 3220fdeeffb3b1eb2502aae51ede2d0a7e238489 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 12 Sep 2021 19:56:27 +1000 Subject: [PATCH 01/25] Update PIDThread.cpp --- source/Core/Threads/PIDThread.cpp | 58 ++++++++++++++++++------------- 1 file changed, 33 insertions(+), 25 deletions(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index 3352e21c..cdc79126 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -20,6 +20,9 @@ TaskHandle_t pidTaskNotification = NULL; uint32_t currentTempTargetDegC = 0; // Current temperature target in C int32_t powerSupplyWattageLimit = 0; bool heaterThermalRunaway = false; + +static void detectThermalRunaway(int16_t currentTipTempInC, int tError); + /* StartPIDTask function */ void startPIDTask(void const *argument __unused) { /* @@ -100,32 +103,9 @@ void startPIDTask(void const *argument __unused) { // basically: temp - lastTemp // Unfortunately, our temp signal is too noisy to really help. - // Check for thermal runaway, where it has been x seconds with negligible (y) temp rise - // While trying to actively heat - if ((tError > THERMAL_RUNAWAY_TEMP_C)) { - // Temp error is high - int16_t delta = (int16_t)currentTipTempInC - (int16_t)tipTempCRunawayTemp; - if (delta < 0) { - delta = -delta; - } - if (delta > THERMAL_RUNAWAY_TEMP_C) { - // We have heated up more than the threshold, reset the timer - tipTempCRunawayTemp = currentTipTempInC; - runawaylastChangeTime = xTaskGetTickCount(); - } else { - if ((xTaskGetTickCount() - runawaylastChangeTime) > (THERMAL_RUNAWAY_TIME_SEC * TICKS_SECOND)) { - // It has taken too long to rise - heaterThermalRunaway = true; - } - } - } else { - tipTempCRunawayTemp = currentTipTempInC; - runawaylastChangeTime = xTaskGetTickCount(); - } - + detectThermalRunaway(currentTipTempInC, tError); } else { - tipTempCRunawayTemp = currentTipTempInC; - runawaylastChangeTime = xTaskGetTickCount(); + detectThermalRunaway(currentTipTempInC, 0); } // If the user turns on the option of using an occasional pulse to keep the power bank on @@ -176,3 +156,31 @@ void startPIDTask(void const *argument __unused) { } } } + +void detectThermalRunaway(int16_t currentTipTempInC, int tError) { + static uint16_t tipTempCRunawayTemp = 0; + static TickType_t runawaylastChangeTime = 0; + + // Check for thermal runaway, where it has been x seconds with negligible (y) temp rise + // While trying to actively heat + if ((tError > THERMAL_RUNAWAY_TEMP_C)) { + // Temp error is high + int16_t delta = (int16_t)currentTipTempInC - (int16_t)tipTempCRunawayTemp; + if (delta < 0) { + delta = -delta; + } + if (delta > THERMAL_RUNAWAY_TEMP_C) { + // We have heated up more than the threshold, reset the timer + tipTempCRunawayTemp = currentTipTempInC; + runawaylastChangeTime = xTaskGetTickCount(); + } else { + if ((xTaskGetTickCount() - runawaylastChangeTime) > (THERMAL_RUNAWAY_TIME_SEC * TICKS_SECOND)) { + // It has taken too long to rise + heaterThermalRunaway = true; + } + } + } else { + tipTempCRunawayTemp = currentTipTempInC; + runawaylastChangeTime = xTaskGetTickCount(); + } +} \ No newline at end of file From 3165fbe5928ffe902dad8a034baa3b2e3599015c Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 12 Sep 2021 20:06:12 +1000 Subject: [PATCH 02/25] Pull out PID irrelevant filters --- source/Core/Threads/PIDThread.cpp | 107 +++++++++++++++--------------- 1 file changed, 55 insertions(+), 52 deletions(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index cdc79126..1fc615ca 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -21,7 +21,8 @@ uint32_t currentTempTargetDegC = 0; // Current temperature target in int32_t powerSupplyWattageLimit = 0; bool heaterThermalRunaway = false; -static void detectThermalRunaway(int16_t currentTipTempInC, int tError); +static void detectThermalRunaway(const int16_t currentTipTempInC, const int tError); +static void setOutputx10WattsViaFilters(int32_t x10Watts); /* StartPIDTask function */ void startPIDTask(void const *argument __unused) { @@ -29,17 +30,13 @@ void startPIDTask(void const *argument __unused) { * We take the current tip temperature & evaluate the next step for the tip * control PWM. */ - setTipX10Watts(0); // disable the output driver if the output is set to be off - TickType_t lastPowerPulseStart = 0; - TickType_t lastPowerPulseEnd = 0; + setTipX10Watts(0); // disable the output at startup history tempError = {{0}, 0, 0}; currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will // be over-ridden rapidly - pidTaskNotification = xTaskGetCurrentTaskHandle(); - uint32_t PIDTempTarget = 0; - uint16_t tipTempCRunawayTemp = 0; - TickType_t runawaylastChangeTime = 0; + pidTaskNotification = xTaskGetCurrentTaskHandle(); + uint32_t PIDTempTarget = 0; // Pre-seed the adc filters for (int i = 0; i < 64; i++) { vTaskDelay(2); @@ -107,49 +104,7 @@ void startPIDTask(void const *argument __unused) { } else { detectThermalRunaway(currentTipTempInC, 0); } - - // If the user turns on the option of using an occasional pulse to keep the power bank on - if (getSettingValue(SettingsOptions::KeepAwakePulse)) { - const TickType_t powerPulseWait = powerPulseWaitUnit * getSettingValue(SettingsOptions::KeepAwakePulseWait); - if (xTaskGetTickCount() - lastPowerPulseStart > powerPulseWait) { - const TickType_t powerPulseDuration = powerPulseDurationUnit * getSettingValue(SettingsOptions::KeepAwakePulseDuration); - lastPowerPulseStart = xTaskGetTickCount(); - lastPowerPulseEnd = lastPowerPulseStart + powerPulseDuration; - } - - // If current PID is less than the pulse level, check if we want to constrain to the pulse as the floor - if (x10WattsOut < getSettingValue(SettingsOptions::KeepAwakePulse) && xTaskGetTickCount() < lastPowerPulseEnd) { - x10WattsOut = getSettingValue(SettingsOptions::KeepAwakePulse); - } - } - - // Secondary safety check to forcefully disable header when within ADC noise of top of ADC - if (getTipRawTemp(0) > (0x7FFF - 32)) { - x10WattsOut = 0; - } - if (heaterThermalRunaway) { - x10WattsOut = 0; - } - if (getSettingValue(SettingsOptions::PowerLimit) && x10WattsOut > (getSettingValue(SettingsOptions::PowerLimit) * 10)) { - x10WattsOut = getSettingValue(SettingsOptions::PowerLimit) * 10; - } - if (powerSupplyWattageLimit && x10WattsOut > powerSupplyWattageLimit * 10) { - x10WattsOut = powerSupplyWattageLimit * 10; - } -#ifdef SLEW_LIMIT - if (x10WattsOut - x10WattsOutLast > SLEW_LIMIT) { - x10WattsOut = x10WattsOutLast + SLEW_LIMIT; - } - if (x10WattsOut < 0) { - x10WattsOut = 0; - } - x10WattsOutLast = x10WattsOut; -#endif - setTipX10Watts(x10WattsOut); -#ifdef DEBUG_UART_OUTPUT - log_system_state(x10WattsOut); -#endif - resetWatchdog(); + setOutputx10WattsViaFilters(x10WattsOut); } else { // ADC interrupt timeout setTipPWM(0); @@ -157,7 +112,7 @@ void startPIDTask(void const *argument __unused) { } } -void detectThermalRunaway(int16_t currentTipTempInC, int tError) { +void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { static uint16_t tipTempCRunawayTemp = 0; static TickType_t runawaylastChangeTime = 0; @@ -183,4 +138,52 @@ void detectThermalRunaway(int16_t currentTipTempInC, int tError) { tipTempCRunawayTemp = currentTipTempInC; runawaylastChangeTime = xTaskGetTickCount(); } +} + +void setOutputx10WattsViaFilters(int32_t x10WattsOut) { + static TickType_t lastPowerPulseStart = 0; + static TickType_t lastPowerPulseEnd = 0; + + // If the user turns on the option of using an occasional pulse to keep the power bank on + if (getSettingValue(SettingsOptions::KeepAwakePulse)) { + const TickType_t powerPulseWait = powerPulseWaitUnit * getSettingValue(SettingsOptions::KeepAwakePulseWait); + if (xTaskGetTickCount() - lastPowerPulseStart > powerPulseWait) { + const TickType_t powerPulseDuration = powerPulseDurationUnit * getSettingValue(SettingsOptions::KeepAwakePulseDuration); + lastPowerPulseStart = xTaskGetTickCount(); + lastPowerPulseEnd = lastPowerPulseStart + powerPulseDuration; + } + + // If current PID is less than the pulse level, check if we want to constrain to the pulse as the floor + if (x10WattsOut < getSettingValue(SettingsOptions::KeepAwakePulse) && xTaskGetTickCount() < lastPowerPulseEnd) { + x10WattsOut = getSettingValue(SettingsOptions::KeepAwakePulse); + } + } + + // Secondary safety check to forcefully disable header when within ADC noise of top of ADC + if (getTipRawTemp(0) > (0x7FFF - 32)) { + x10WattsOut = 0; + } + if (heaterThermalRunaway) { + x10WattsOut = 0; + } + if (getSettingValue(SettingsOptions::PowerLimit) && x10WattsOut > (getSettingValue(SettingsOptions::PowerLimit) * 10)) { + x10WattsOut = getSettingValue(SettingsOptions::PowerLimit) * 10; + } + if (powerSupplyWattageLimit && x10WattsOut > powerSupplyWattageLimit * 10) { + x10WattsOut = powerSupplyWattageLimit * 10; + } +#ifdef SLEW_LIMIT + if (x10WattsOut - x10WattsOutLast > SLEW_LIMIT) { + x10WattsOut = x10WattsOutLast + SLEW_LIMIT; + } + if (x10WattsOut < 0) { + x10WattsOut = 0; + } + x10WattsOutLast = x10WattsOut; +#endif + setTipX10Watts(x10WattsOut); +#ifdef DEBUG_UART_OUTPUT + log_system_state(x10WattsOut); +#endif + resetWatchdog(); } \ No newline at end of file From 9c3cc12726bd7ea0508085f0e1ec1a6fbb71e6fc Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 12 Sep 2021 20:10:09 +1000 Subject: [PATCH 03/25] Update PIDThread.cpp --- source/Core/Threads/PIDThread.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index 1fc615ca..824f1a06 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -42,13 +42,11 @@ void startPIDTask(void const *argument __unused) { vTaskDelay(2); TipThermoModel::getTipInC(true); } -#ifdef SLEW_LIMIT - int32_t x10WattsOutLast = 0; -#endif for (;;) { + // This is a call to block this thread until the ADC does its samples if (ulTaskNotifyTake(pdTRUE, 2000)) { - // This is a call to block this thread until the ADC does its samples + int32_t x10WattsOut = 0; // Do the reading here to keep the temp calculations churning along uint32_t currentTipTempInC = TipThermoModel::getTipInC(true); @@ -63,7 +61,6 @@ void startPIDTask(void const *argument __unused) { if (PIDTempTarget > TipThermoModel::getTipMaxInC()) { PIDTempTarget = TipThermoModel::getTipMaxInC(); } - // Convert the current tip to degree's C // As we get close to our target, temp noise causes the system // to be unstable. Use a rolling average to dampen it. @@ -143,6 +140,9 @@ void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { void setOutputx10WattsViaFilters(int32_t x10WattsOut) { static TickType_t lastPowerPulseStart = 0; static TickType_t lastPowerPulseEnd = 0; +#ifdef SLEW_LIMIT + static int32_t x10WattsOutLast = 0; +#endif // If the user turns on the option of using an occasional pulse to keep the power bank on if (getSettingValue(SettingsOptions::KeepAwakePulse)) { From c99d6b731e57980e16c330aaafda43653ff6d5d2 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 12 Sep 2021 20:37:05 +1000 Subject: [PATCH 04/25] Update PIDThread.cpp --- source/Core/Threads/PIDThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index 824f1a06..fdb8e482 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -66,7 +66,7 @@ void startPIDTask(void const *argument __unused) { // to be unstable. Use a rolling average to dampen it. // We overshoot by roughly 1 degree C. // This helps stabilize the display. - int32_t tError = PIDTempTarget - currentTipTempInC + 1; + int32_t tError = PIDTempTarget - currentTipTempInC; tError = tError > INT16_MAX ? INT16_MAX : tError; tError = tError < INT16_MIN ? INT16_MIN : tError; tempError.update(tError); From 416af2ff70fc159b39c40e2c0b2a13646c1b2d03 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 12 Sep 2021 20:44:09 +1000 Subject: [PATCH 05/25] Refactor PID inner core out --- source/Core/Threads/PIDThread.cpp | 77 +++++++++++++++---------------- 1 file changed, 38 insertions(+), 39 deletions(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index fdb8e482..fd587838 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -21,8 +21,9 @@ uint32_t currentTempTargetDegC = 0; // Current temperature target in int32_t powerSupplyWattageLimit = 0; bool heaterThermalRunaway = false; -static void detectThermalRunaway(const int16_t currentTipTempInC, const int tError); -static void setOutputx10WattsViaFilters(int32_t x10Watts); +static int32_t getPIDResultX10Watts(int32_t tError); +static void detectThermalRunaway(const int16_t currentTipTempInC, const int tError); +static void setOutputx10WattsViaFilters(int32_t x10Watts); /* StartPIDTask function */ void startPIDTask(void const *argument __unused) { @@ -32,9 +33,8 @@ void startPIDTask(void const *argument __unused) { */ setTipX10Watts(0); // disable the output at startup - history tempError = {{0}, 0, 0}; - currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will - // be over-ridden rapidly + currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will + // be over-ridden rapidly pidTaskNotification = xTaskGetCurrentTaskHandle(); uint32_t PIDTempTarget = 0; // Pre-seed the adc filters @@ -42,12 +42,12 @@ void startPIDTask(void const *argument __unused) { vTaskDelay(2); TipThermoModel::getTipInC(true); } + int32_t x10WattsOut = 0; for (;;) { - + x10WattsOut = 0; // This is a call to block this thread until the ADC does its samples if (ulTaskNotifyTake(pdTRUE, 2000)) { - int32_t x10WattsOut = 0; // Do the reading here to keep the temp calculations churning along uint32_t currentTipTempInC = TipThermoModel::getTipInC(true); PIDTempTarget = currentTempTargetDegC; @@ -61,43 +61,12 @@ void startPIDTask(void const *argument __unused) { if (PIDTempTarget > TipThermoModel::getTipMaxInC()) { PIDTempTarget = TipThermoModel::getTipMaxInC(); } - - // As we get close to our target, temp noise causes the system - // to be unstable. Use a rolling average to dampen it. - // We overshoot by roughly 1 degree C. - // This helps stabilize the display. int32_t tError = PIDTempTarget - currentTipTempInC; tError = tError > INT16_MAX ? INT16_MAX : tError; tError = tError < INT16_MIN ? INT16_MIN : tError; - tempError.update(tError); - - // Now for the PID! - - // P term - total power needed to hit target temp next cycle. - // thermal mass = 1690 milliJ/*C for my tip. - // = Watts*Seconds to raise Temp from room temp to +100*C, divided by 100*C. - // we divide milliWattsNeeded by 20 to let the I term dominate near the set point. - // This is necessary because of the temp noise and thermal lag in the system. - // Once we have feed-forward temp estimation we should be able to better tune this. - - int32_t x10WattsNeeded = tempToX10Watts(tError); - // note that milliWattsNeeded is sometimes negative, this counters overshoot - // from I term's inertia. - x10WattsOut += x10WattsNeeded; - - // I term - energy needed to compensate for heat loss. - // We track energy put into the system over some window. - // Assuming the temp is stable, energy in = energy transfered. - // (If it isn't, P will dominate). - x10WattsOut += x10WattHistory.average(); - - // D term - use sudden temp change to counter fast cooling/heating. - // In practice, this provides an early boost if temp is dropping - // and counters extra power if the iron is no longer losing temp. - // basically: temp - lastTemp - // Unfortunately, our temp signal is too noisy to really help. detectThermalRunaway(currentTipTempInC, tError); + x10WattsOut = getPIDResultX10Watts(tError); } else { detectThermalRunaway(currentTipTempInC, 0); } @@ -109,6 +78,36 @@ void startPIDTask(void const *argument __unused) { } } +int32_t getPIDResultX10Watts(int32_t tError) { + + // Now for the PID! + + // P term - total power needed to hit target temp next cycle. + // thermal mass = 1690 milliJ/*C for my tip. + // = Watts*Seconds to raise Temp from room temp to +100*C, divided by 100*C. + // we divide milliWattsNeeded by 20 to let the I term dominate near the set point. + // This is necessary because of the temp noise and thermal lag in the system. + // Once we have feed-forward temp estimation we should be able to better tune this. + + int32_t x10WattsNeeded = tempToX10Watts(tError); + // note that milliWattsNeeded is sometimes negative, this counters overshoot + // from I term's inertia. + int32_t x10WattsOut = x10WattsNeeded; + + // I term - energy needed to compensate for heat loss. + // We track energy put into the system over some window. + // Assuming the temp is stable, energy in = energy transfered. + // (If it isn't, P will dominate). + x10WattsOut += x10WattHistory.average(); + + // D term - use sudden temp change to counter fast cooling/heating. + // In practice, this provides an early boost if temp is dropping + // and counters extra power if the iron is no longer losing temp. + // basically: temp - lastTemp + // Unfortunately, our temp signal is too noisy to really help. + return x10WattsOut; +} + void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { static uint16_t tipTempCRunawayTemp = 0; static TickType_t runawaylastChangeTime = 0; From 159ae7a8e23a02db3f583646baa222744224464c Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Sun, 12 Sep 2021 20:59:40 +1000 Subject: [PATCH 06/25] Rough pass new PID --- source/Core/Threads/PIDThread.cpp | 69 ++++++++++++++++++++++++++++--- 1 file changed, 63 insertions(+), 6 deletions(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index fd587838..1e81feb1 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -24,6 +24,7 @@ bool heaterThermalRunaway = false; static int32_t getPIDResultX10Watts(int32_t tError); static void detectThermalRunaway(const int16_t currentTipTempInC, const int tError); static void setOutputx10WattsViaFilters(int32_t x10Watts); +static int32_t getX10WattageLimits(); /* StartPIDTask function */ void startPIDTask(void const *argument __unused) { @@ -77,7 +78,55 @@ void startPIDTask(void const *argument __unused) { } } } +#define TRIAL_NEW_PID +#ifdef TRIAL_NEW_PID +int32_t getPIDResultX10Watts(int32_t setpointDelta) { + static int32_t runningSum = 0; + ////////////////////////////////////////////////////////////////////////////////////////////////////////// + // Sandman note: + // PID Challenge - we have a small thermal mass that we to want heat up as fast as possible but we don't // + // want to overshot excessively (if at all) the setpoint temperature. In the same time we have 'imprecise' // + // instant temperature measurements. The nature of temperature reading imprecision is not necessarily // + // related to the sensor (thermocouple) or DAQ system, that otherwise are fairly decent. The real issue is // + // the thermal inertia. We basically read the temperature in the window between two heating sessions when // + // the output is off. However, the heater temperature does not dissipate instantly into the tip mass so // + // at any moment right after heating, the thermocouple would sense a temperature significantly higher than // + // moments later. We could use longer delays but that would slow the PID loop and that would lead to other // + // negative side effects. As a result, we can only rely on the I term but with a twist. Instead of a simple // + // integrator we are going to use a self decaying integrator that acts more like a dual I term / P term // + // rather than a plain I term. Depending on the circumstances, like when the delta temperature is large, // + // it acts more like a P term whereas on closing to setpoint it acts increasingly closer to a plain I term. // + // So in a sense, we have a bit of both. // + // So there we go... + //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + // P = (Thermal Mass) x (Delta Temperature / T_FACTOR) / 1sec, where thermal mass is in X10 J / °C and + // delta temperature is in T_FACTOR x °C. The result is the power in X10 W needed to raise (or decrease!) the + // tip temperature with (Delta Temperature / T_FACTOR) °C in 1 second. + // Note on powerStore. On update, if the value is provided in X10 (W) units then inertia shall be provided + // in X10 (J / °C) units as well. Also, powerStore is updated with a gain of 2. Where this comes from: The actual + // power CMOS is controlled by TIM3->CTR1 (that is software modulated - on/off - by TIM2-CTR4 interrupts). However, + // TIM3->CTR1 is configured with a duty cycle of 50% so, in real, we get only 50% of the presumed power output + // so we basically double the need (gain = 2) to get what we want. + + // Decay the old value. This is a simplified formula that still works with decent results + // Ideally we would have used an exponential decay but the computational effort required + // by exp function is just not justified here in respect to the outcome + const int gain = 2; + runningSum = runningSum * (100 - tipMass / 10) / 100; + // Add the new value x integration interval ( 1 / rate) + runningSum += (gain * tempToX10Watts(setpointDelta)) / 10; + + int32_t limit = getX10WattageLimits(); + // limit the output + if (runningSum > limit) + runningSum = limit; + else if (runningSum < -limit) + runningSum = -limit; + + return runningSum; +} +#else int32_t getPIDResultX10Watts(int32_t tError) { // Now for the PID! @@ -107,7 +156,7 @@ int32_t getPIDResultX10Watts(int32_t tError) { // Unfortunately, our temp signal is too noisy to really help. return x10WattsOut; } - +#endif void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { static uint16_t tipTempCRunawayTemp = 0; static TickType_t runawaylastChangeTime = 0; @@ -136,6 +185,17 @@ void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { } } +int32_t getX10WattageLimits() { + int32_t limit = 900; // 90W + if (getSettingValue(SettingsOptions::PowerLimit) && limit > (getSettingValue(SettingsOptions::PowerLimit) * 10)) { + limit = getSettingValue(SettingsOptions::PowerLimit) * 10; + } + if (powerSupplyWattageLimit && limit > powerSupplyWattageLimit * 10) { + limit = powerSupplyWattageLimit * 10; + } + return limit; +} + void setOutputx10WattsViaFilters(int32_t x10WattsOut) { static TickType_t lastPowerPulseStart = 0; static TickType_t lastPowerPulseEnd = 0; @@ -165,11 +225,8 @@ void setOutputx10WattsViaFilters(int32_t x10WattsOut) { if (heaterThermalRunaway) { x10WattsOut = 0; } - if (getSettingValue(SettingsOptions::PowerLimit) && x10WattsOut > (getSettingValue(SettingsOptions::PowerLimit) * 10)) { - x10WattsOut = getSettingValue(SettingsOptions::PowerLimit) * 10; - } - if (powerSupplyWattageLimit && x10WattsOut > powerSupplyWattageLimit * 10) { - x10WattsOut = powerSupplyWattageLimit * 10; + if (x10WattsOut > getX10WattageLimits()) { + x10WattsOut = getX10WattageLimits(); } #ifdef SLEW_LIMIT if (x10WattsOut - x10WattsOutLast > SLEW_LIMIT) { From a57449ed0fb0166eecce68a82e5adee6cd6233c7 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 14 Sep 2021 21:48:37 +1000 Subject: [PATCH 07/25] Retiming all the PWM's --- source/Core/BSP/BSP.h | 5 +- source/Core/BSP/MHP30/BSP.cpp | 6 +- source/Core/BSP/Miniware/BSP.cpp | 56 +++++------- source/Core/BSP/Miniware/Setup.cpp | 5 +- source/Core/BSP/Pine64/BSP.cpp | 4 +- source/Core/BSP/Pine64/IRQ.cpp | 89 ++++++++----------- source/Core/BSP/Pine64/Setup.cpp | 6 +- .../Common/Source/system_gd32vf103.c | 2 +- 8 files changed, 71 insertions(+), 102 deletions(-) diff --git a/source/Core/BSP/BSP.h b/source/Core/BSP/BSP.h index e0739c60..fce1fe2e 100644 --- a/source/Core/BSP/BSP.h +++ b/source/Core/BSP/BSP.h @@ -33,16 +33,13 @@ void BSPInit(void); // Called to reset the hardware watchdog unit void resetWatchdog(); // Accepts a output level of 0.. to use to control the tip output PWM -void setTipPWM(uint8_t pulse); +void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM); // Returns the Handle temp in C, X10 uint16_t getHandleTemperature(uint8_t sample); // Returns the Tip temperature ADC reading in raw units uint16_t getTipRawTemp(uint8_t refresh); // Returns the main DC input voltage, using the adjustable divisor + sample flag uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample); -// Switch to the most suitable PWM freq given the desired period; -// returns true if the switch was performed and totalPWM changed -bool tryBetterPWM(uint8_t pwm); // Readers for the two buttons // !! Returns 1 if held down, 0 if released diff --git a/source/Core/BSP/MHP30/BSP.cpp b/source/Core/BSP/MHP30/BSP.cpp index 4757f3d3..ffff19ee 100644 --- a/source/Core/BSP/MHP30/BSP.cpp +++ b/source/Core/BSP/MHP30/BSP.cpp @@ -246,11 +246,7 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) { } return sum * 4 / divisor; } -bool tryBetterPWM(uint8_t pwm) { - // We dont need this for the MHP30 - return false; -} -void setTipPWM(uint8_t pulse) { +void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) { // We can just set the timer directly if (htim3.Instance->PSC > 20) { htim3.Instance->CCR1 = 0; diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index 7a75d989..397ec521 100644 --- a/source/Core/BSP/Miniware/BSP.cpp +++ b/source/Core/BSP/Miniware/BSP.cpp @@ -135,48 +135,36 @@ uint16_t getInputVoltageX10(uint16_t divisor, uint8_t sample) { return res; } -void setTipPWM(uint8_t pulse) { - PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is - // disabled if the PID task is not scheduled often enough. - - pendingPWM = pulse; -} - static void switchToFastPWM(void) { - fastPWM = true; - totalPWM = powerPWM + tempMeasureTicks * 2 + holdoffTicks; - htim2.Instance->ARR = totalPWM; - // ~3.5 Hz rate - htim2.Instance->CCR1 = powerPWM + holdoffTicks * 2; - // 2 MHz timer clock/2000 = 1 kHz tick rate - htim2.Instance->PSC = 2000; + // 10Hz + fastPWM = true; + totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; + htim2.Instance->ARR = totalPWM; + htim2.Instance->CCR1 = powerPWM + holdoffTicks; + htim2.Instance->PSC = 2690; } static void switchToSlowPWM(void) { - fastPWM = false; - totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; - htim2.Instance->ARR = totalPWM; - // ~1.84 Hz rate - htim2.Instance->CCR1 = powerPWM + holdoffTicks; - // 2 MHz timer clock/4000 = 500 Hz tick rate - htim2.Instance->PSC = 4000; + // 5Hz + fastPWM = false; + totalPWM = powerPWM + tempMeasureTicks / 2 + holdoffTicks / 2; + htim2.Instance->ARR = totalPWM; + htim2.Instance->CCR1 = powerPWM + holdoffTicks / 2; + htim2.Instance->PSC = 2690 * 2; } -bool tryBetterPWM(uint8_t pwm) { - if (fastPWM && pwm == powerPWM) { - // maximum power for fast PWM reached, need to go slower to get more - switchToSlowPWM(); - return true; - } else if (!fastPWM && pwm < 230) { - // 254 in fast PWM mode gives the same power as 239 in slow - // allow for some reasonable hysteresis by switching only when it goes - // below 230 (equivalent to 245 in fast mode) - switchToFastPWM(); - return true; +void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) { + PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is + // disabled if the PID task is not scheduled often enough. + pendingPWM = pulse; + if (fastPWM != shouldUseFastModePWM) { + if (shouldUseFastModePWM) { + switchToFastPWM(); + } else { + switchToSlowPWM(); + } } - return false; } - // These are called by the HAL after the corresponding events from the system // timers. diff --git a/source/Core/BSP/Miniware/Setup.cpp b/source/Core/BSP/Miniware/Setup.cpp index 9532503e..93b7a6e6 100644 --- a/source/Core/BSP/Miniware/Setup.cpp +++ b/source/Core/BSP/Miniware/Setup.cpp @@ -326,7 +326,8 @@ static void MX_TIM2_Init(void) { // These values give a rate of around 3.5 Hz for "fast" mode and 1.84 Hz for "slow" htim2.Init.CounterMode = TIM_COUNTERMODE_UP; // dummy value, will be reconfigured by BSPInit() - htim2.Init.Period = 255 + 17 * 2; + htim2.Init.Period = powerPWM + 14 * 2; + htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 8 MHz (x2 APB1) before divide htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; htim2.Init.RepetitionCounter = 0; @@ -344,7 +345,7 @@ static void MX_TIM2_Init(void) { sConfigOC.OCMode = TIM_OCMODE_PWM1; // dummy value, will be reconfigured by BSPInit() in the BSP.cpp - sConfigOC.Pulse = 255 + 13 * 2; // 13 -> Delay of 7 ms + sConfigOC.Pulse = powerPWM + 14; // 13 -> Delay of 7 ms // 255 is the largest time period of the drive signal, and then offset ADC sample to be a bit delayed after this /* * It takes 4 milliseconds for output to be stable after PWM turns off. diff --git a/source/Core/BSP/Pine64/BSP.cpp b/source/Core/BSP/Pine64/BSP.cpp index a1978bd3..a4526712 100644 --- a/source/Core/BSP/Pine64/BSP.cpp +++ b/source/Core/BSP/Pine64/BSP.cpp @@ -12,8 +12,8 @@ #include "main.hpp" const uint16_t powerPWM = 255; -const uint8_t holdoffTicks = 25; // delay of 7 ms -const uint8_t tempMeasureTicks = 25; +const uint8_t holdoffTicks = 10; +const uint8_t tempMeasureTicks = 14; uint16_t totalPWM; // htim2.Init.Period, the full PWM cycle diff --git a/source/Core/BSP/Pine64/IRQ.cpp b/source/Core/BSP/Pine64/IRQ.cpp index 9285bb16..e0fff8f4 100644 --- a/source/Core/BSP/Pine64/IRQ.cpp +++ b/source/Core/BSP/Pine64/IRQ.cpp @@ -18,6 +18,9 @@ volatile uint16_t i2c_nbytes; volatile uint16_t i2c_write_dress; volatile uint16_t i2c_read_dress; volatile uint8_t i2c_process_flag = 0; +static bool fastPWM; +static void switchToSlowPWM(void); +static void switchToFastPWM(void); void ADC0_1_IRQHandler(void) { adc_interrupt_flag_clear(ADC0, ADC_INT_FLAG_EOIC); @@ -34,74 +37,58 @@ void ADC0_1_IRQHandler(void) { volatile uint16_t PWMSafetyTimer = 0; volatile uint8_t pendingPWM = 0; void TIMER1_IRQHandler(void) { + static bool lastPeriodWasFast = false; if (timer_interrupt_flag_get(TIMER1, TIMER_INT_UP) == SET) { timer_interrupt_flag_clear(TIMER1, TIMER_INT_UP); // rollover turn on output if required - if (PWMSafetyTimer && pendingPWM) { - timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 50); - } if (PWMSafetyTimer) { PWMSafetyTimer--; + if (lastPeriodWasFast != fastPWM) { + if (fastPWM) { + switchToFastPWM(); + } else { + switchToSlowPWM(); + } + } + if (pendingPWM) { + timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, pendingPWM); + timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 50); + } else { + timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 0); + } } } if (timer_interrupt_flag_get(TIMER1, TIMER_INT_CH1) == SET) { timer_interrupt_flag_clear(TIMER1, TIMER_INT_CH1); - // This is triggered on pwm setpoint trigger; we want to copy the pending - // PWM value into the output control reg - timer_channel_output_pulse_value_config(TIMER2, TIMER_CH_0, 0); - if (pendingPWM) { - timer_channel_output_pulse_value_config(TIMER1, TIMER_CH_1, pendingPWM); - } } } -void setTipPWM(uint8_t pulse) { +void switchToFastPWM(void) { + fastPWM = true; + totalPWM = powerPWM + tempMeasureTicks + holdoffTicks; + TIMER_CAR(TIMER1) = (uint32_t)totalPWM; + + // ~10Hz + TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks; + // 1 kHz tick rate + TIMER_PSC(TIMER1) = 18000; +} + +void switchToSlowPWM(void) { + // 5Hz + fastPWM = false; + totalPWM = powerPWM + tempMeasureTicks / 2 + holdoffTicks / 2; + TIMER_CAR(TIMER1) = (uint32_t)totalPWM; + TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks / 2; + TIMER_PSC(TIMER1) = 36000; +} +void setTipPWM(const uint8_t pulse, const bool shouldUseFastModePWM) { PWMSafetyTimer = 10; // This is decremented in the handler for PWM so that the tip pwm is // disabled if the PID task is not scheduled often enough. pendingPWM = pulse; -} - -static bool fastPWM; -static void switchToFastPWM(void) { - fastPWM = true; - totalPWM = powerPWM + tempMeasureTicks * 2; - TIMER_CAR(TIMER1) = (uint32_t)totalPWM; - - // ~3.5 Hz rate - TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks * 2; - // 1 kHz tick rate - TIMER_PSC(TIMER1) = 12000; - /* generate an update event */ - TIMER_SWEVG(TIMER1) |= (uint32_t)TIMER_SWEVG_UPG; -} - -static void switchToSlowPWM(void) { - fastPWM = false; - totalPWM = powerPWM + tempMeasureTicks; - TIMER_CAR(TIMER1) = (uint32_t)totalPWM; - // ~1.84 Hz rate - TIMER_CH0CV(TIMER1) = powerPWM + holdoffTicks; - // 500 Hz tick rate - TIMER_PSC(TIMER1) = 24000; - /* generate an update event */ - TIMER_SWEVG(TIMER1) |= (uint32_t)TIMER_SWEVG_UPG; -} - -bool tryBetterPWM(uint8_t pwm) { - if (fastPWM && pwm == powerPWM) { - // maximum power for fast PWM reached, need to go slower to get more - switchToSlowPWM(); - return true; - } else if (!fastPWM && pwm < 230) { - // 254 in fast PWM mode gives the same power as 239 in slow - // allow for some reasonable hysteresis by switching only when it goes - // below 230 (equivalent to 245 in fast mode) - switchToFastPWM(); - return true; - } - return false; + fastPWM = shouldUseFastModePWM; } void EXTI5_9_IRQHandler(void) { diff --git a/source/Core/BSP/Pine64/Setup.cpp b/source/Core/BSP/Pine64/Setup.cpp index 826dbdc4..0b683036 100644 --- a/source/Core/BSP/Pine64/Setup.cpp +++ b/source/Core/BSP/Pine64/Setup.cpp @@ -12,7 +12,7 @@ #include "history.hpp" #include #define ADC_NORM_SAMPLES 16 -#define ADC_FILTER_LEN 32 +#define ADC_FILTER_LEN 4 uint16_t ADCReadings[ADC_NORM_SAMPLES]; // room for 32 lots of the pair of readings // Functions @@ -264,10 +264,10 @@ void setup_timers() { /* initialize TIMER init parameter struct */ timer_struct_para_init(&timer_initpara); /* TIMER1 configuration */ - timer_initpara.prescaler = 5000; + timer_initpara.prescaler = 30000; timer_initpara.alignedmode = TIMER_COUNTER_EDGE; timer_initpara.counterdirection = TIMER_COUNTER_UP; - timer_initpara.period = powerPWM + tempMeasureTicks; + timer_initpara.period = powerPWM + tempMeasureTicks + holdoffTicks; timer_initpara.clockdivision = TIMER_CKDIV_DIV4; timer_initpara.repetitioncounter = 0; timer_init(TIMER1, &timer_initpara); diff --git a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c index fcb8786c..b34e55a4 100644 --- a/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c +++ b/source/Core/BSP/Pine64/Vendor/SoC/gd32vf103/Common/Source/system_gd32vf103.c @@ -118,7 +118,7 @@ static void system_clock_108m_hxtal(void) { /* APB2 = AHB/1 */ RCU_CFG0 |= RCU_APB2_CKAHB_DIV1; /* APB1 = AHB/2 */ - RCU_CFG0 |= RCU_APB1_CKAHB_DIV2; + RCU_CFG0 |= RCU_APB1_CKAHB_DIV4; /* CK_PLL = (CK_PREDIV0) * 27 = 108 MHz */ RCU_CFG0 &= ~(RCU_CFG0_PLLMF | RCU_CFG0_PLLMF_4); From 811446fcb183b0041acef093785c4c7f800735b9 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 14 Sep 2021 21:48:41 +1000 Subject: [PATCH 08/25] Update TipThermoModel.cpp --- source/Core/Drivers/TipThermoModel.cpp | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/source/Core/Drivers/TipThermoModel.cpp b/source/Core/Drivers/TipThermoModel.cpp index f283f3bf..cd4076d4 100644 --- a/source/Core/Drivers/TipThermoModel.cpp +++ b/source/Core/Drivers/TipThermoModel.cpp @@ -72,9 +72,10 @@ uint32_t TipThermoModel::convertFtoC(uint32_t degF) { uint32_t TipThermoModel::getTipInC(bool sampleNow) { int32_t currentTipTempInC = TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(sampleNow)); currentTipTempInC += getHandleTemperature(sampleNow) / 10; // Add handle offset - // Power usage indicates that our tip temp is lower than our thermocouple temp. - // I found a number that doesn't unbalance the existing PID, causing overshoot. - // This could be tuned in concert with PID parameters... + + // Power usage indicates that our tip temp is lower than our thermocouple temp. + // I found a number that doesn't unbalance the existing PID, causing overshoot. + // This could be tuned in concert with PID parameters... #ifdef THERMAL_MASS_OVERSHOOTS currentTipTempInC += x10WattHistory.average() / 25; #else From 1b0c3bcb67dd56f8aa574fdeac7a9244c8eba0d2 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 14 Sep 2021 21:48:58 +1000 Subject: [PATCH 09/25] Cleaning up fast/slow PWM change --- source/Core/Inc/configuration.h | 25 +++++++++++-------- source/Core/Src/power.cpp | 43 ++++++++++++++++++++------------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/source/Core/Inc/configuration.h b/source/Core/Inc/configuration.h index 0f85e170..d4864556 100644 --- a/source/Core/Inc/configuration.h +++ b/source/Core/Inc/configuration.h @@ -227,28 +227,33 @@ #endif #ifdef MODEL_TS100 -const int32_t tipMass = 65; // X10 watts to raise 1 deg C in 1 second -const uint8_t tipResistance = 75; // x10 ohms, 7.5 typical for ts100 tips +const int32_t HARDWARE_MAX_WATTAGE_X10 = 750; +const int32_t TIP_THERMAL_MASS = 65; // X10 watts to raise 1 deg C in 1 second +const uint8_t tipResistance = 75; // x10 ohms, 7.5 typical for ts100 tips #endif #ifdef MODEL_Pinecil -const int32_t tipMass = 45; // X10 watts to raise 1 deg C in 1 second -const uint8_t tipResistance = 75; // x10 ohms, 7.5 typical for ts100 tips +const int32_t HARDWARE_MAX_WATTAGE_X10 = 750; +const int32_t TIP_THERMAL_MASS = 65; // X10 watts to raise 1 deg C in 1 second +const uint8_t tipResistance = 75; // x10 ohms, 7.5 typical for ts100 tips #endif #ifdef MODEL_TS80 -const uint32_t tipMass = 40; -const uint8_t tipResistance = 45; // x10 ohms, 4.5 typical for ts80 tips +const int32_t HARDWARE_MAX_WATTAGE_X10 = 180; +const uint32_t TIP_THERMAL_MASS = 40; +const uint8_t tipResistance = 45; // x10 ohms, 4.5 typical for ts80 tips #endif #ifdef MODEL_TS80P -const uint32_t tipMass = 40; -const uint8_t tipResistance = 45; // x10 ohms, 4.5 typical for ts80 tips +const int32_t HARDWARE_MAX_WATTAGE_X10 = 300; +const uint32_t TIP_THERMAL_MASS = 40; +const uint8_t tipResistance = 45; // x10 ohms, 4.5 typical for ts80 tips #endif #ifdef MODEL_MHP30 -const uint32_t tipMass = 45; // TODO -const uint8_t tipResistance = 60; // x10 ohms, ~6 typical +const int32_t HARDWARE_MAX_WATTAGE_X10 = 650; +const uint32_t TIP_THERMAL_MASS = 65; // TODO, needs refinement +const uint8_t tipResistance = 60; // x10 ohms, ~6 typical #endif #ifdef POW_QC_20V diff --git a/source/Core/Src/power.cpp b/source/Core/Src/power.cpp index 97e4472a..dec27147 100644 --- a/source/Core/Src/power.cpp +++ b/source/Core/Src/power.cpp @@ -13,18 +13,31 @@ static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample); expMovingAverage x10WattHistory = {0}; +bool shouldBeUsingFastPWMMode(const uint8_t pwmTicks) { + // Determine if we should use slow or fast PWM mode + // Crossover between modes set around the midpoint of the PWM control point + static bool lastPWMWasFast = true; + if (pwmTicks > (128 + 8) && lastPWMWasFast) { + lastPWMWasFast = false; + } else if (pwmTicks < (128 - 8) && !lastPWMWasFast) { + lastPWMWasFast = true; + } + return lastPWMWasFast; +} + int32_t tempToX10Watts(int32_t rawTemp) { - // mass is in milliJ/*C, rawC is raw per degree C - // returns milliWatts needed to raise/lower a mass by rawTemp + // mass is in x10J/*C, rawC is raw per degree C + // returns x10Watts needed to raise/lower a mass by rawTemp // degrees in one cycle. - int32_t milliJoules = tipMass * rawTemp; - return milliJoules; + int32_t x10Watts = TIP_THERMAL_MASS * rawTemp; + return x10Watts; } void setTipX10Watts(int32_t mw) { - int32_t output = X10WattsToPWM(mw, 1); - setTipPWM(output); - uint32_t actualMilliWatts = PWMToX10Watts(output, 0); + int32_t outputPWMLevel = X10WattsToPWM(mw, 1); + const bool shouldUseFastPWM = shouldBeUsingFastPWMMode(outputPWMLevel); + setTipPWM(outputPWMLevel, shouldUseFastPWM); + uint32_t actualMilliWatts = PWMToX10Watts(outputPWMLevel, 0); x10WattHistory.update(actualMilliWatts); } @@ -45,7 +58,6 @@ static uint32_t availableW10(uint8_t sample) { // availableMilliWattsX10 is now an accurate representation return availableWattsX10; } - uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) { // Scale input milliWatts to the pwm range available if (milliWatts < 1) { @@ -56,15 +68,12 @@ uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) { // Calculate desired milliwatts as a percentage of availableW10 uint32_t pwm; - do { - pwm = (powerPWM * milliWatts) / availableW10(sample); - if (pwm > powerPWM) { - // constrain to max PWM counter, shouldn't be possible, - // but small cost for safety to avoid wraps - pwm = powerPWM; - } - } while (tryBetterPWM(pwm)); - + pwm = (powerPWM * milliWatts) / availableW10(sample); + if (pwm > powerPWM) { + // constrain to max PWM counter, shouldn't be possible, + // but small cost for safety to avoid wraps + pwm = powerPWM; + } return pwm; } From 0f3aff66199999153e9d0d7cd6542d3f716fc761 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 14 Sep 2021 21:52:10 +1000 Subject: [PATCH 10/25] Cleaning up new PID --- source/Core/Threads/PIDThread.cpp | 109 +++++++++++++++++------------- 1 file changed, 62 insertions(+), 47 deletions(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index 1e81feb1..718fd9ee 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -39,16 +39,17 @@ void startPIDTask(void const *argument __unused) { pidTaskNotification = xTaskGetCurrentTaskHandle(); uint32_t PIDTempTarget = 0; // Pre-seed the adc filters - for (int i = 0; i < 64; i++) { - vTaskDelay(2); + for (int i = 0; i < 128; i++) { + vTaskDelay(5); TipThermoModel::getTipInC(true); + getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 1); } int32_t x10WattsOut = 0; + for (;;) { x10WattsOut = 0; // This is a call to block this thread until the ADC does its samples if (ulTaskNotifyTake(pdTRUE, 2000)) { - // Do the reading here to keep the temp calculations churning along uint32_t currentTipTempInC = TipThermoModel::getTipInC(true); PIDTempTarget = currentTempTargetDegC; @@ -74,57 +75,72 @@ void startPIDTask(void const *argument __unused) { setOutputx10WattsViaFilters(x10WattsOut); } else { // ADC interrupt timeout - setTipPWM(0); + setTipPWM(0, false); } } } #define TRIAL_NEW_PID #ifdef TRIAL_NEW_PID -int32_t getPIDResultX10Watts(int32_t setpointDelta) { - static int32_t runningSum = 0; - ////////////////////////////////////////////////////////////////////////////////////////////////////////// - // Sandman note: - // PID Challenge - we have a small thermal mass that we to want heat up as fast as possible but we don't // - // want to overshot excessively (if at all) the setpoint temperature. In the same time we have 'imprecise' // - // instant temperature measurements. The nature of temperature reading imprecision is not necessarily // - // related to the sensor (thermocouple) or DAQ system, that otherwise are fairly decent. The real issue is // - // the thermal inertia. We basically read the temperature in the window between two heating sessions when // - // the output is off. However, the heater temperature does not dissipate instantly into the tip mass so // - // at any moment right after heating, the thermocouple would sense a temperature significantly higher than // - // moments later. We could use longer delays but that would slow the PID loop and that would lead to other // - // negative side effects. As a result, we can only rely on the I term but with a twist. Instead of a simple // - // integrator we are going to use a self decaying integrator that acts more like a dual I term / P term // - // rather than a plain I term. Depending on the circumstances, like when the delta temperature is large, // - // it acts more like a P term whereas on closing to setpoint it acts increasingly closer to a plain I term. // - // So in a sense, we have a bit of both. // - // So there we go... - //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - // P = (Thermal Mass) x (Delta Temperature / T_FACTOR) / 1sec, where thermal mass is in X10 J / °C and - // delta temperature is in T_FACTOR x °C. The result is the power in X10 W needed to raise (or decrease!) the - // tip temperature with (Delta Temperature / T_FACTOR) °C in 1 second. +template struct Integrator { + T sum; + + T update(const T val, const int32_t inertia, const int32_t gain, const int32_t rate, const int32_t limit) { + // Decay the old value. This is a simplified formula that still works with decent results + // Ideally we would have used an exponential decay but the computational effort required + // by exp function is just not justified here in respect to the outcome + sum = sum * (100 - inertia / rate) / 100; + // Add the new value x integration interval ( 1 / rate) + sum += gain * val / rate; + + // limit the output + if (sum > limit) + sum = limit; + else if (sum < -limit) + sum = -limit; + + return sum; + } + + void set(T const val) { sum = val; } + + T get(bool positiveOnly = true) const { return (positiveOnly) ? ((sum > 0) ? sum : 0) : sum; } +}; +int32_t getPIDResultX10Watts(int32_t setpointDelta) { + static TickType_t lastCall = 0; + static Integrator powerStore = {0}; + + const int rate = 1000 / (xTaskGetTickCount() - lastCall); + lastCall = xTaskGetTickCount(); + // Sandman note: + // PID Challenge - we have a small thermal mass that we to want heat up as fast as possible but we don't + // want to overshot excessively (if at all) the setpoint temperature. In the same time we have 'imprecise' + // instant temperature measurements. The nature of temperature reading imprecision is not necessarily + // related to the sensor (thermocouple) or DAQ system, that otherwise are fairly decent. The real issue is + // the thermal inertia. We basically read the temperature in the window between two heating sessions when + // the output is off. However, the heater temperature does not dissipate instantly into the tip mass so + // at any moment right after heating, the thermocouple would sense a temperature significantly higher than + // moments later. We could use longer delays but that would slow the PID loop and that would lead to other + // negative side effects. As a result, we can only rely on the I term but with a twist. Instead of a simple + // integrator we are going to use a self decaying integrator that acts more like a dual I term / P term + // rather than a plain I term. Depending on the circumstances, like when the delta temperature is large, + // it acts more like a P term whereas on closing to setpoint it acts increasingly closer to a plain I term. + // So in a sense, we have a bit of both. + // So there we go... + + // P = (Thermal Mass) x (Delta Temperature ) / 1sec, where thermal mass is in X10 J / °C and + // delta temperature is in °C. The result is the power in X10 W needed to raise (or decrease!) the + // tip temperature with (Delta Temperature ) °C in 1 second. // Note on powerStore. On update, if the value is provided in X10 (W) units then inertia shall be provided // in X10 (J / °C) units as well. Also, powerStore is updated with a gain of 2. Where this comes from: The actual // power CMOS is controlled by TIM3->CTR1 (that is software modulated - on/off - by TIM2-CTR4 interrupts). However, // TIM3->CTR1 is configured with a duty cycle of 50% so, in real, we get only 50% of the presumed power output // so we basically double the need (gain = 2) to get what we want. - - // Decay the old value. This is a simplified formula that still works with decent results - // Ideally we would have used an exponential decay but the computational effort required - // by exp function is just not justified here in respect to the outcome - const int gain = 2; - runningSum = runningSum * (100 - tipMass / 10) / 100; - // Add the new value x integration interval ( 1 / rate) - runningSum += (gain * tempToX10Watts(setpointDelta)) / 10; - - int32_t limit = getX10WattageLimits(); - // limit the output - if (runningSum > limit) - runningSum = limit; - else if (runningSum < -limit) - runningSum = -limit; - - return runningSum; + return powerStore.update(TIP_THERMAL_MASS * setpointDelta, // the required power + TIP_THERMAL_MASS, // inertia factor + 2, // gain + rate, // PID cycle frequency + getX10WattageLimits()); } #else int32_t getPIDResultX10Watts(int32_t tError) { @@ -186,7 +202,9 @@ void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { } int32_t getX10WattageLimits() { - int32_t limit = 900; // 90W + const auto vin = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0); + int32_t limit = (vin * vin) * tipResistance / 10; + if (getSettingValue(SettingsOptions::PowerLimit) && limit > (getSettingValue(SettingsOptions::PowerLimit) * 10)) { limit = getSettingValue(SettingsOptions::PowerLimit) * 10; } @@ -225,9 +243,6 @@ void setOutputx10WattsViaFilters(int32_t x10WattsOut) { if (heaterThermalRunaway) { x10WattsOut = 0; } - if (x10WattsOut > getX10WattageLimits()) { - x10WattsOut = getX10WattageLimits(); - } #ifdef SLEW_LIMIT if (x10WattsOut - x10WattsOutLast > SLEW_LIMIT) { x10WattsOut = x10WattsOutLast + SLEW_LIMIT; From ad857a08ab7fc2212c1da5a56bc980f6f4490797 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Tue, 14 Sep 2021 22:01:10 +1000 Subject: [PATCH 11/25] QC code does not get control of vin filter --- source/Core/BSP/Miniware/Setup.cpp | 2 +- source/Core/Src/QC3.cpp | 8 ++++---- source/Core/Threads/PIDThread.cpp | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/source/Core/BSP/Miniware/Setup.cpp b/source/Core/BSP/Miniware/Setup.cpp index 93b7a6e6..b86c86ff 100644 --- a/source/Core/BSP/Miniware/Setup.cpp +++ b/source/Core/BSP/Miniware/Setup.cpp @@ -20,7 +20,7 @@ DMA_HandleTypeDef hdma_i2c1_tx; IWDG_HandleTypeDef hiwdg; TIM_HandleTypeDef htim2; TIM_HandleTypeDef htim3; -#define ADC_FILTER_LEN 32 +#define ADC_FILTER_LEN 4 #define ADC_SAMPLES 16 uint16_t ADCReadings[ADC_SAMPLES]; // Used to store the adc readings for the handle cold junction temp diff --git a/source/Core/Src/QC3.cpp b/source/Core/Src/QC3.cpp index 6a11c5de..4fa0bf4f 100644 --- a/source/Core/Src/QC3.cpp +++ b/source/Core/Src/QC3.cpp @@ -70,7 +70,7 @@ void seekQC(int16_t Vx10, uint16_t divisor) { // try and step towards the wanted value // 1. Measure current voltage - int16_t vStart = getInputVoltageX10(divisor, 1); + int16_t vStart = getInputVoltageX10(divisor, 0); int difference = Vx10 - vStart; // 2. calculate ideal steps (0.2V changes) @@ -94,7 +94,7 @@ void seekQC(int16_t Vx10, uint16_t divisor) { #ifdef ENABLE_QC2 // Re-measure /* Disabled due to nothing to test and code space of around 1k*/ - steps = vStart - getInputVoltageX10(divisor, 1); + steps = vStart - getInputVoltageX10(divisor, 0); if (steps < 0) steps = -steps; if (steps > 4) { @@ -118,7 +118,7 @@ void seekQC(int16_t Vx10, uint16_t divisor) { void startQC(uint16_t divisor) { // Pre check that the input could be >5V already, and if so, dont both // negotiating as someone is feeding in hv - if (getInputVoltageX10(divisor, 1) > 80) { + if (getInputVoltageX10(divisor, 0) > 80) { QCTries = 11; QCMode = QCState::NO_QC; return; @@ -160,7 +160,7 @@ void startQC(uint16_t divisor) { // Wait for frontend ADC to stabilise QCMode = QCState::QC_2; for (uint8_t i = 0; i < 10; i++) { - if (getInputVoltageX10(divisor, 1) > 80) { + if (getInputVoltageX10(divisor, 0) > 80) { // yay we have at least QC2.0 or QC3.0 QCMode = QCState::QC_3; // We have at least QC2, pray for 3 return; diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index 718fd9ee..fbd03d56 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -64,8 +64,8 @@ void startPIDTask(void const *argument __unused) { PIDTempTarget = TipThermoModel::getTipMaxInC(); } int32_t tError = PIDTempTarget - currentTipTempInC; - tError = tError > INT16_MAX ? INT16_MAX : tError; - tError = tError < INT16_MIN ? INT16_MIN : tError; + // tError = tError > INT16_MAX ? INT16_MAX : tError; + // tError = tError < INT16_MIN ? INT16_MIN : tError; detectThermalRunaway(currentTipTempInC, tError); x10WattsOut = getPIDResultX10Watts(tError); @@ -138,7 +138,7 @@ int32_t getPIDResultX10Watts(int32_t setpointDelta) { // so we basically double the need (gain = 2) to get what we want. return powerStore.update(TIP_THERMAL_MASS * setpointDelta, // the required power TIP_THERMAL_MASS, // inertia factor - 2, // gain + 1, // gain rate, // PID cycle frequency getX10WattageLimits()); } From e18c877a96728bdc5810c9b4d9da58ea241a0ef8 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 18:53:07 +1000 Subject: [PATCH 12/25] Removed unused --- source/Core/BSP/Miniware/BSP.cpp | 4 +--- source/Core/BSP/Pine64/BSP.cpp | 6 ++---- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index 397ec521..378c1b9d 100644 --- a/source/Core/BSP/Miniware/BSP.cpp +++ b/source/Core/BSP/Miniware/BSP.cpp @@ -21,9 +21,7 @@ uint16_t totalPWM; // htim2.Init.Period, the full PWM cycle static bool fastPWM; -// 2 second filter (ADC is PID_TIM_HZ Hz) -history rawTempFilter = {{0}, 0, 0}; -void resetWatchdog() { HAL_IWDG_Refresh(&hiwdg); } +void resetWatchdog() { HAL_IWDG_Refresh(&hiwdg); } #ifdef TEMP_NTC // Lookup table for the NTC // Stored as ADCReading,Temp in degC diff --git a/source/Core/BSP/Pine64/BSP.cpp b/source/Core/BSP/Pine64/BSP.cpp index a4526712..4b06fae3 100644 --- a/source/Core/BSP/Pine64/BSP.cpp +++ b/source/Core/BSP/Pine64/BSP.cpp @@ -15,11 +15,9 @@ const uint16_t powerPWM = 255; const uint8_t holdoffTicks = 10; const uint8_t tempMeasureTicks = 14; -uint16_t totalPWM; // htim2.Init.Period, the full PWM cycle +uint16_t totalPWM; // Total length of the cycle's ticks -// 2 second filter (ADC is PID_TIM_HZ Hz) -history rawTempFilter = {{0}, 0, 0}; -void resetWatchdog() { fwdgt_counter_reload(); } +void resetWatchdog() { fwdgt_counter_reload(); } uint16_t getHandleTemperature(uint8_t sample) { #ifdef TEMP_TMP36 From bd703c7d51d4fde09967fd4d460e5e673f770a54 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 18:53:34 +1000 Subject: [PATCH 13/25] Dont need history compensation for delay --- source/Core/Drivers/TipThermoModel.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/source/Core/Drivers/TipThermoModel.cpp b/source/Core/Drivers/TipThermoModel.cpp index cd4076d4..4e708d54 100644 --- a/source/Core/Drivers/TipThermoModel.cpp +++ b/source/Core/Drivers/TipThermoModel.cpp @@ -76,11 +76,7 @@ uint32_t TipThermoModel::getTipInC(bool sampleNow) { // Power usage indicates that our tip temp is lower than our thermocouple temp. // I found a number that doesn't unbalance the existing PID, causing overshoot. // This could be tuned in concert with PID parameters... -#ifdef THERMAL_MASS_OVERSHOOTS - currentTipTempInC += x10WattHistory.average() / 25; -#else - currentTipTempInC -= x10WattHistory.average() / 25; -#endif + if (currentTipTempInC < 0) return 0; return currentTipTempInC; @@ -93,7 +89,7 @@ uint32_t TipThermoModel::getTipInF(bool sampleNow) { } uint32_t TipThermoModel::getTipMaxInC() { - uint32_t maximumTipTemp = TipThermoModel::convertTipRawADCToDegC(0x7FFF - (21 * 5)); // back off approx 5 deg c from ADC max + uint32_t maximumTipTemp = TipThermoModel::convertTipRawADCToDegC(0x7FFF - (21 * 3)); // back off approx 5 deg c from ADC max maximumTipTemp += getHandleTemperature(0) / 10; // Add handle offset return maximumTipTemp - 1; } From 4a11b81d0849cc0d1d99c75aa27a4184c5d2a12c Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 18:54:03 +1000 Subject: [PATCH 14/25] Cleanup pwm changeover point --- source/Core/Src/power.cpp | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/source/Core/Src/power.cpp b/source/Core/Src/power.cpp index dec27147..3fcaa302 100644 --- a/source/Core/Src/power.cpp +++ b/source/Core/Src/power.cpp @@ -10,6 +10,8 @@ #include static int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample); +const int fastPWMChangeoverPoint = 128; +const int fastPWMChangeoverTolerance = 16; expMovingAverage x10WattHistory = {0}; @@ -17,9 +19,9 @@ bool shouldBeUsingFastPWMMode(const uint8_t pwmTicks) { // Determine if we should use slow or fast PWM mode // Crossover between modes set around the midpoint of the PWM control point static bool lastPWMWasFast = true; - if (pwmTicks > (128 + 8) && lastPWMWasFast) { + if (pwmTicks > (fastPWMChangeoverPoint + fastPWMChangeoverTolerance) && lastPWMWasFast) { lastPWMWasFast = false; - } else if (pwmTicks < (128 - 8) && !lastPWMWasFast) { + } else if (pwmTicks < (fastPWMChangeoverPoint - fastPWMChangeoverTolerance) && !lastPWMWasFast) { lastPWMWasFast = true; } return lastPWMWasFast; @@ -58,20 +60,19 @@ static uint32_t availableW10(uint8_t sample) { // availableMilliWattsX10 is now an accurate representation return availableWattsX10; } -uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) { - // Scale input milliWatts to the pwm range available - if (milliWatts < 1) { +uint8_t X10WattsToPWM(int32_t x10Watts, uint8_t sample) { + // Scale input x10Watts to the pwm range available + if (x10Watts < 0) { // keep the battery voltage updating the filter getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), sample); return 0; } - // Calculate desired milliwatts as a percentage of availableW10 + // Calculate desired x10Watts as a percentage of availableW10 uint32_t pwm; - pwm = (powerPWM * milliWatts) / availableW10(sample); + pwm = (powerPWM * x10Watts) / availableW10(sample); if (pwm > powerPWM) { - // constrain to max PWM counter, shouldn't be possible, - // but small cost for safety to avoid wraps + // constrain to max PWM counter pwm = powerPWM; } return pwm; From 6989f108297229bf37bec108b3eaf0016bfb6a69 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 18:54:11 +1000 Subject: [PATCH 15/25] Remove old PID --- source/Core/Threads/PIDThread.cpp | 50 ++++++------------------------- 1 file changed, 9 insertions(+), 41 deletions(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index fbd03d56..fd921b3a 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -64,8 +64,6 @@ void startPIDTask(void const *argument __unused) { PIDTempTarget = TipThermoModel::getTipMaxInC(); } int32_t tError = PIDTempTarget - currentTipTempInC; - // tError = tError > INT16_MAX ? INT16_MAX : tError; - // tError = tError < INT16_MIN ? INT16_MIN : tError; detectThermalRunaway(currentTipTempInC, tError); x10WattsOut = getPIDResultX10Watts(tError); @@ -77,10 +75,11 @@ void startPIDTask(void const *argument __unused) { // ADC interrupt timeout setTipPWM(0, false); } +#ifdef DEBUG_UART_OUTPUT + log_system_state(x10WattsOut); +#endif } } -#define TRIAL_NEW_PID -#ifdef TRIAL_NEW_PID template struct Integrator { T sum; @@ -89,9 +88,9 @@ template struct Integrator { // Decay the old value. This is a simplified formula that still works with decent results // Ideally we would have used an exponential decay but the computational effort required // by exp function is just not justified here in respect to the outcome - sum = sum * (100 - inertia / rate) / 100; + sum = (sum * (100 - (inertia / rate))) / 100; // Add the new value x integration interval ( 1 / rate) - sum += gain * val / rate; + sum += (gain * val) / rate; // limit the output if (sum > limit) @@ -137,42 +136,12 @@ int32_t getPIDResultX10Watts(int32_t setpointDelta) { // TIM3->CTR1 is configured with a duty cycle of 50% so, in real, we get only 50% of the presumed power output // so we basically double the need (gain = 2) to get what we want. return powerStore.update(TIP_THERMAL_MASS * setpointDelta, // the required power - TIP_THERMAL_MASS, // inertia factor + TIP_THERMAL_MASS, // Inertia, smaller numbers increase dominance of the previous value 1, // gain rate, // PID cycle frequency getX10WattageLimits()); } -#else -int32_t getPIDResultX10Watts(int32_t tError) { - // Now for the PID! - - // P term - total power needed to hit target temp next cycle. - // thermal mass = 1690 milliJ/*C for my tip. - // = Watts*Seconds to raise Temp from room temp to +100*C, divided by 100*C. - // we divide milliWattsNeeded by 20 to let the I term dominate near the set point. - // This is necessary because of the temp noise and thermal lag in the system. - // Once we have feed-forward temp estimation we should be able to better tune this. - - int32_t x10WattsNeeded = tempToX10Watts(tError); - // note that milliWattsNeeded is sometimes negative, this counters overshoot - // from I term's inertia. - int32_t x10WattsOut = x10WattsNeeded; - - // I term - energy needed to compensate for heat loss. - // We track energy put into the system over some window. - // Assuming the temp is stable, energy in = energy transfered. - // (If it isn't, P will dominate). - x10WattsOut += x10WattHistory.average(); - - // D term - use sudden temp change to counter fast cooling/heating. - // In practice, this provides an early boost if temp is dropping - // and counters extra power if the iron is no longer losing temp. - // basically: temp - lastTemp - // Unfortunately, our temp signal is too noisy to really help. - return x10WattsOut; -} -#endif void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { static uint16_t tipTempCRunawayTemp = 0; static TickType_t runawaylastChangeTime = 0; @@ -203,7 +172,9 @@ void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { int32_t getX10WattageLimits() { const auto vin = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0); - int32_t limit = (vin * vin) * tipResistance / 10; + int32_t limit = ((vin * vin) * tipResistance); + limit *= 12; // Default to 20% over + limit /= 100; if (getSettingValue(SettingsOptions::PowerLimit) && limit > (getSettingValue(SettingsOptions::PowerLimit) * 10)) { limit = getSettingValue(SettingsOptions::PowerLimit) * 10; @@ -253,8 +224,5 @@ void setOutputx10WattsViaFilters(int32_t x10WattsOut) { x10WattsOutLast = x10WattsOut; #endif setTipX10Watts(x10WattsOut); -#ifdef DEBUG_UART_OUTPUT - log_system_state(x10WattsOut); -#endif resetWatchdog(); } \ No newline at end of file From a213f4bd97be54d8c1e23f92dbd4592edbd2ed7a Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 18:59:17 +1000 Subject: [PATCH 16/25] Update gui.cpp --- source/Core/Src/gui.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Core/Src/gui.cpp b/source/Core/Src/gui.cpp index 1d5c2821..c4ffa8c3 100644 --- a/source/Core/Src/gui.cpp +++ b/source/Core/Src/gui.cpp @@ -641,7 +641,7 @@ static void setTipOffset() { OLED::refresh(); osDelay(100); } - setoffset = TipThermoModel::convertTipRawADCTouV(offset / 16); + setoffset = TipThermoModel::convertTipRawADCTouV(offset / 16, true); } setSettingValue(SettingsOptions::CalibrationOffset, setoffset); OLED::clearScreen(); From bfca4c93368400a534d217acb2985b6e8fb64215 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 19:05:11 +1000 Subject: [PATCH 17/25] Better limiter in the PID --- source/Core/Inc/power.hpp | 7 ++++--- source/Core/Src/power.cpp | 2 +- source/Core/Threads/PIDThread.cpp | 5 +---- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/source/Core/Inc/power.hpp b/source/Core/Inc/power.hpp index 786fb979..f8d35f67 100644 --- a/source/Core/Inc/power.hpp +++ b/source/Core/Inc/power.hpp @@ -22,7 +22,8 @@ const uint8_t wattHistoryFilter = 24; // I term look back weighting extern expMovingAverage x10WattHistory; -int32_t tempToX10Watts(int32_t rawTemp); -void setTipX10Watts(int32_t mw); -uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample = 0); +uint32_t availableW10(uint8_t sample); +int32_t tempToX10Watts(int32_t rawTemp); +void setTipX10Watts(int32_t mw); +uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample = 0); #endif /* POWER_HPP_ */ diff --git a/source/Core/Src/power.cpp b/source/Core/Src/power.cpp index 3fcaa302..d6665bd0 100644 --- a/source/Core/Src/power.cpp +++ b/source/Core/Src/power.cpp @@ -44,7 +44,7 @@ void setTipX10Watts(int32_t mw) { x10WattHistory.update(actualMilliWatts); } -static uint32_t availableW10(uint8_t sample) { +uint32_t availableW10(uint8_t sample) { // P = V^2 / R, v*v = v^2 * 100 // R = R*10 // P therefore is in V^2*100/R*10 = W*10. diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index fd921b3a..f7721303 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -171,10 +171,7 @@ void detectThermalRunaway(const int16_t currentTipTempInC, const int tError) { } int32_t getX10WattageLimits() { - const auto vin = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 0); - int32_t limit = ((vin * vin) * tipResistance); - limit *= 12; // Default to 20% over - limit /= 100; + int32_t limit = availableW10(0); if (getSettingValue(SettingsOptions::PowerLimit) && limit > (getSettingValue(SettingsOptions::PowerLimit) * 10)) { limit = getSettingValue(SettingsOptions::PowerLimit) * 10; From ebde786ca1499cdfa3fe1bb92e4d5e199a09bdee Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 19:24:19 +1000 Subject: [PATCH 18/25] Bugfixes for settings menu --- source/Core/Src/Settings.cpp | 2 +- source/Core/Src/gui.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/source/Core/Src/Settings.cpp b/source/Core/Src/Settings.cpp index fddc3de6..b838ba76 100644 --- a/source/Core/Src/Settings.cpp +++ b/source/Core/Src/Settings.cpp @@ -144,7 +144,7 @@ bool nextSettingValue(const enum SettingsOptions option) { } else { systemSettings.settingsValues[(int)option] += constants.increment; } - return (constants.max - systemSettings.settingsValues[(int)option]) < constants.increment; + return (constants.max - systemSettings.settingsValues[(int)option]) <= constants.increment; } bool prevSettingValue(const enum SettingsOptions option) { diff --git a/source/Core/Src/gui.cpp b/source/Core/Src/gui.cpp index c4ffa8c3..f9855d4d 100644 --- a/source/Core/Src/gui.cpp +++ b/source/Core/Src/gui.cpp @@ -409,7 +409,7 @@ static bool settings_displayShutdownTime(void) { return false; } static bool settings_setTempF(void) { - nextSettingValue(SettingsOptions::TemperatureInF); + bool res = nextSettingValue(SettingsOptions::TemperatureInF); uint16_t BoostTemp = getSettingValue(SettingsOptions::BoostTemp); uint16_t SolderingTemp = getSettingValue(SettingsOptions::SolderingTemp); uint16_t SleepTemp = getSettingValue(SettingsOptions::SleepTemp); @@ -438,7 +438,7 @@ static bool settings_setTempF(void) { setSettingValue(SettingsOptions::SolderingTemp, SolderingTemp); setSettingValue(SettingsOptions::SleepTemp, SleepTemp); - return false; + return res; } static bool settings_displayTempF(void) { From 2bfb8a65353dc893416b12635ec3ea4a9a8d9336 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 20:24:41 +1000 Subject: [PATCH 19/25] Unify settings for each model into once place --- source/Core/BSP/BSP.h | 2 +- source/Core/BSP/MHP30/BSP.cpp | 2 +- source/Core/BSP/MHP30/Model_Config.h | 30 ---- source/Core/BSP/MHP30/Pins.h | 2 +- source/Core/BSP/MHP30/Power.cpp | 2 +- source/Core/BSP/MHP30/QC_GPIO.cpp | 3 +- source/Core/BSP/MHP30/Software_I2C.h | 2 +- source/Core/BSP/MHP30/configuration.h | 157 ++++++++++++++++++ source/Core/BSP/MHP30/fusb_user.cpp | 2 +- source/Core/BSP/MHP30/preRTOS.cpp | 3 +- source/Core/BSP/Miniware/BSP.cpp | 2 +- source/Core/BSP/Miniware/Model_Config.h | 49 ------ source/Core/BSP/Miniware/Pins.h | 2 +- source/Core/BSP/Miniware/Power.cpp | 2 +- source/Core/BSP/Miniware/QC_GPIO.cpp | 3 +- source/Core/BSP/Miniware/Software_I2C.h | 2 +- .../{Inc => BSP/Miniware}/configuration.h | 114 ++++--------- source/Core/BSP/Miniware/fusb_user.cpp | 2 +- source/Core/BSP/Miniware/preRTOS.cpp | 3 +- source/Core/BSP/Pine64/Model_Config.h | 33 ---- source/Core/BSP/Pine64/Power.cpp | 2 +- source/Core/BSP/Pine64/configuration.h | 151 +++++++++++++++++ source/Core/BSP/Pine64/fusb_user.cpp | 2 +- source/Core/Drivers/FUSB302/fusbpd.cpp | 2 +- source/Core/Drivers/I2CBB.cpp | 2 +- source/Core/Drivers/I2CBB.hpp | 2 +- source/Core/Drivers/OLED.hpp | 2 +- source/Core/Src/Settings.cpp | 6 + source/Core/Threads/MOVThread.cpp | 3 +- 29 files changed, 377 insertions(+), 212 deletions(-) delete mode 100644 source/Core/BSP/MHP30/Model_Config.h create mode 100644 source/Core/BSP/MHP30/configuration.h delete mode 100644 source/Core/BSP/Miniware/Model_Config.h rename source/Core/{Inc => BSP/Miniware}/configuration.h (63%) delete mode 100644 source/Core/BSP/Pine64/Model_Config.h create mode 100644 source/Core/BSP/Pine64/configuration.h diff --git a/source/Core/BSP/BSP.h b/source/Core/BSP/BSP.h index fce1fe2e..0caf21bb 100644 --- a/source/Core/BSP/BSP.h +++ b/source/Core/BSP/BSP.h @@ -2,7 +2,7 @@ #include "BSP_Power.h" #include "BSP_QC.h" #include "Defines.h" -#include "Model_Config.h" +#include "configuration.h" #include #include /* diff --git a/source/Core/BSP/MHP30/BSP.cpp b/source/Core/BSP/MHP30/BSP.cpp index ffff19ee..1561ec06 100644 --- a/source/Core/BSP/MHP30/BSP.cpp +++ b/source/Core/BSP/MHP30/BSP.cpp @@ -2,7 +2,6 @@ #include "BSP.h" #include "I2C_Wrapper.hpp" -#include "Model_Config.h" #include "Pins.h" #include "Setup.h" #include "TipThermoModel.h" @@ -13,6 +12,7 @@ #include "main.hpp" #include + WS2812 ws2812; volatile uint16_t PWMSafetyTimer = 0; volatile uint8_t pendingPWM = 0; diff --git a/source/Core/BSP/MHP30/Model_Config.h b/source/Core/BSP/MHP30/Model_Config.h deleted file mode 100644 index ecc0460c..00000000 --- a/source/Core/BSP/MHP30/Model_Config.h +++ /dev/null @@ -1,30 +0,0 @@ -/* - * Model_Config.h - * - * Created on: 25 Jul 2020 - * Author: Ralim - */ - -#ifndef BSP_MINIWARE_MODEL_CONFIG_H_ -#define BSP_MINIWARE_MODEL_CONFIG_H_ -/* - * Lookup for mapping features <-> Models - */ - -#ifndef MODEL_MHP30 -#error "No model defined!" -#endif - -#ifdef MODEL_MHP30 -#define ACCEL_MSA -#define POW_PD -#define TEMP_NTC -#define I2C_SOFT -#define BATTFILTERDEPTH 8 -#define OLED_I2CBB -#define ACCEL_EXITS_ON_MOVEMENT -#endif -#ifdef ACCEL_EXITS_ON_MOVEMENT -#define NO_SLEEP_MODE -#endif -#endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */ diff --git a/source/Core/BSP/MHP30/Pins.h b/source/Core/BSP/MHP30/Pins.h index d649c14b..610322ed 100644 --- a/source/Core/BSP/MHP30/Pins.h +++ b/source/Core/BSP/MHP30/Pins.h @@ -7,7 +7,7 @@ #ifndef BSP_MINIWARE_PINS_H_ #define BSP_MINIWARE_PINS_H_ -#include "Model_Config.h" +#include "configuration.h" // MHP30 pin map #define KEY_B_Pin GPIO_PIN_0 diff --git a/source/Core/BSP/MHP30/Power.cpp b/source/Core/BSP/MHP30/Power.cpp index 72a64017..80455d2b 100644 --- a/source/Core/BSP/MHP30/Power.cpp +++ b/source/Core/BSP/MHP30/Power.cpp @@ -1,9 +1,9 @@ #include "BSP.h" #include "BSP_Power.h" -#include "Model_Config.h" #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "configuration.h" #include "fusb_user.h" #include "fusbpd.h" #include "int_n.h" diff --git a/source/Core/BSP/MHP30/QC_GPIO.cpp b/source/Core/BSP/MHP30/QC_GPIO.cpp index b48ba1f3..8adc603b 100644 --- a/source/Core/BSP/MHP30/QC_GPIO.cpp +++ b/source/Core/BSP/MHP30/QC_GPIO.cpp @@ -5,11 +5,12 @@ * Author: Ralim */ #include "BSP.h" -#include "Model_Config.h" #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "configuration.h" #include "stm32f1xx_hal.h" + #ifdef POW_QC void QC_DPlusZero_Six() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+ diff --git a/source/Core/BSP/MHP30/Software_I2C.h b/source/Core/BSP/MHP30/Software_I2C.h index 99f3a2e9..411362f5 100644 --- a/source/Core/BSP/MHP30/Software_I2C.h +++ b/source/Core/BSP/MHP30/Software_I2C.h @@ -8,7 +8,7 @@ #ifndef BSP_MINIWARE_SOFTWARE_I2C_H_ #define BSP_MINIWARE_SOFTWARE_I2C_H_ #include "BSP.h" -#include "Model_Config.h" +#include "configuration.h" #include "stm32f1xx_hal.h" #ifdef I2C_SOFT diff --git a/source/Core/BSP/MHP30/configuration.h b/source/Core/BSP/MHP30/configuration.h new file mode 100644 index 00000000..b6f4104c --- /dev/null +++ b/source/Core/BSP/MHP30/configuration.h @@ -0,0 +1,157 @@ +#ifndef CONFIGURATION_H_ +#define CONFIGURATION_H_ +#include "Settings.h" +#include "configuration.h" +#include +/** + * Configuration.h + * Define here your default pre settings for TS80 or TS100 + * + */ + +//=========================================================================== +//============================= Default Settings ============================ +//=========================================================================== +/** + * Default soldering temp is 320.0 C + * Temperature the iron sleeps at - default 150.0 C + */ + +#define SLEEP_TEMP 150 // Default sleep temperature +#define BOOST_TEMP 420 // Default boost temp. +#define BOOST_MODE_ENABLED 1 // 0: Disable 1: Enable + +/** + * Blink the temperature on the cooling screen when its > 50C + */ +#define COOLING_TEMP_BLINK 0 // 0: Disable 1: Enable + +/** + * How many seconds/minutes we wait until going to sleep/shutdown. + * Values -> SLEEP_TIME * 10; i.e. 5*10 = 50 Seconds! + */ +#define SLEEP_TIME 5 // x10 Seconds +#define SHUTDOWN_TIME 10 // Minutes + +/** + * Auto start off for safety. + * Pissible values are: + * 0 - none + * 1 - Soldering Temperature + * 2 - Sleep Temperature + * 3 - Sleep Off Temperature + */ +#define AUTO_START_MODE 0 // Default to none + +/** + * Locking Mode + * When in soldering mode a long press on both keys toggle the lock of the buttons + * Possible values are: + * 0 - Desactivated + * 1 - Lock except boost + * 2 - Full lock + */ +#define LOCKING_MODE 0 // Default to desactivated for safety + +/** + * OLED Orientation + * + */ +#define ORIENTATION_MODE 0 // 0: Right 1:Left 2:Automatic - Default right +#define REVERSE_BUTTON_TEMP_CHANGE 0 // 0:Default 1:Reverse - Reverse the plus and minus button assigment for temperature change + +/** + * Temp change settings + */ +#define TEMP_CHANGE_SHORT_STEP 1 // Default temp change short step +1 +#define TEMP_CHANGE_LONG_STEP 10 // Default temp change long step +10 +#define TEMP_CHANGE_SHORT_STEP_MAX 50 // Temp change short step MAX value +#define TEMP_CHANGE_LONG_STEP_MAX 90 // Temp change long step MAX value + +/* Power pulse for keeping power banks awake*/ +#define POWER_PULSE_INCREMENT 1 +#define POWER_PULSE_MAX 100 // x10 max watts +#define POWER_PULSE_WAIT_MAX 9 // 9*2.5s = 22.5 seconds +#define POWER_PULSE_DURATION_MAX 9 // 9*250ms = 2.25 seconds + +#ifdef MODEL_TS100 +#define POWER_PULSE_DEFAULT 0 +#else +#define POWER_PULSE_DEFAULT 5 +#endif +#define POWER_PULSE_WAIT_DEFAULT 4 // Default rate of the power pulse: 4*2500 = 10000 ms = 10 s +#define POWER_PULSE_DURATION_DEFAULT 1 // Default duration of the power pulse: 1*250 = 250 ms + +/** + * OLED Orientation Sensitivity on Automatic mode! + * Motion Sensitivity <0=Off 1=Least Sensitive 9=Most Sensitive> + */ +#define SENSITIVITY 7 // Default 7 + +/** + * Detailed soldering screen + * Detailed idle screen (off for first time users) + */ +#define DETAILED_SOLDERING 0 // 0: Disable 1: Enable - Default 0 +#define DETAILED_IDLE 0 // 0: Disable 1: Enable - Default 0 + +#define THERMAL_RUNAWAY_TIME_SEC 20 +#define THERMAL_RUNAWAY_TEMP_C 20 + +#define CUT_OUT_SETTING 0 // default to no cut-off voltage +#define RECOM_VOL_CELL 33 // Minimum voltage per cell (Recommended 3.3V (33)) +#define TEMPERATURE_INF 0 // default to 0 +#define DESCRIPTION_SCROLL_SPEED 0 // 0: Slow 1: Fast - default to slow +#define ANIMATION_LOOP 1 // 0: off 1: on +#define ANIMATION_SPEED settingOffSpeed_t::MEDIUM + +#define OP_AMP_Rf_MHP30 268500 // 268.5 Kilo-ohms -> Measured +#define OP_AMP_Rin_MHP30 1600 // 1.6 Kilo-ohms -> Measured + +#define OP_AMP_GAIN_STAGE_MHP30 (1 + (OP_AMP_Rf_MHP30 / OP_AMP_Rin_MHP30)) +// Deriving the Voltage div: +// Vin_max = (3.3*(r1+r2))/(r2) +// vdiv = (32768*4)/(vin_max*10) + +#ifndef MODEL_MHP30 +#error "No model defined!" +#endif + +#ifdef MODEL_MHP30 +#define SOLDERING_TEMP 200 // Default soldering temp is 200.0 °C +#define VOLTAGE_DIV 360 // Default for MHP30 +#define PID_POWER_LIMIT 65 // Sets the max pwm power limit +#define CALIBRATION_OFFSET 0 // the adc offset in uV - MHP compensates automagically +#define POWER_LIMIT 65 // 65 watts default power limit +#define MAX_POWER_LIMIT 65 // +#define POWER_LIMIT_STEPS 1 // +#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_MHP30 // +#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate +#define MODEL_HAS_DCDC // Has inductor to current filter +#define PID_TIM_HZ (16) // +#define THERMAL_MASS_OVERSHOOTS // We have overshoot so reverse direction of compensation +#define MAX_TEMP_C 300 // Max soldering temp selectable °C +#define MAX_TEMP_F 570 // Max soldering temp selectable °F +#define MIN_TEMP_C 10 // Min soldering temp selectable °C +#define MIN_TEMP_F 60 // Min soldering temp selectable °F +#define MIN_BOOST_TEMP_C 150 // The min settable temp for boost mode °C +#define MIN_BOOST_TEMP_F 300 // The min settable temp for boost mode °F +#define NO_DISPLAY_ROTATE // Disable OLED rotation by accel +#define SLEW_LIMIT 50 // Limit to 3.0 Watts per 64ms pid loop update rate slew rate +#define ACCEL_MSA +#define POW_PD +#define TEMP_NTC +#define I2C_SOFT +#define BATTFILTERDEPTH 8 +#define OLED_I2CBB +#define ACCEL_EXITS_ON_MOVEMENT + +#define HARDWARE_MAX_WATTAGE_X10 650 +#define TIP_THERMAL_MASS 65 // TODO, needs refinement +#define tipResistance 60 // x10 ohms, ~6 typical +#endif + +#ifdef ACCEL_EXITS_ON_MOVEMENT +#define NO_SLEEP_MODE +#endif +#endif diff --git a/source/Core/BSP/MHP30/fusb_user.cpp b/source/Core/BSP/MHP30/fusb_user.cpp index bddf5a72..e3dfa13c 100644 --- a/source/Core/BSP/MHP30/fusb_user.cpp +++ b/source/Core/BSP/MHP30/fusb_user.cpp @@ -1,4 +1,4 @@ -#include "Model_Config.h" +#include "configuration.h" #ifdef POW_PD #include "BSP.h" #include "I2C_Wrapper.hpp" diff --git a/source/Core/BSP/MHP30/preRTOS.cpp b/source/Core/BSP/MHP30/preRTOS.cpp index 44ac337f..7efd4da8 100644 --- a/source/Core/BSP/MHP30/preRTOS.cpp +++ b/source/Core/BSP/MHP30/preRTOS.cpp @@ -7,11 +7,12 @@ #include "BSP.h" #include "I2CBB.hpp" -#include "Model_Config.h" #include "Pins.h" #include "Setup.h" +#include "configuration.h" #include "fusbpd.h" #include + void preRToSInit() { /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ diff --git a/source/Core/BSP/Miniware/BSP.cpp b/source/Core/BSP/Miniware/BSP.cpp index 378c1b9d..327cf05f 100644 --- a/source/Core/BSP/Miniware/BSP.cpp +++ b/source/Core/BSP/Miniware/BSP.cpp @@ -2,7 +2,6 @@ #include "BSP.h" #include "I2C_Wrapper.hpp" -#include "Model_Config.h" #include "Pins.h" #include "Setup.h" #include "TipThermoModel.h" @@ -10,6 +9,7 @@ #include "history.hpp" #include "main.hpp" #include + volatile uint16_t PWMSafetyTimer = 0; volatile uint8_t pendingPWM = 0; diff --git a/source/Core/BSP/Miniware/Model_Config.h b/source/Core/BSP/Miniware/Model_Config.h deleted file mode 100644 index 27ea0899..00000000 --- a/source/Core/BSP/Miniware/Model_Config.h +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Model_Config.h - * - * Created on: 25 Jul 2020 - * Author: Ralim - */ - -#ifndef BSP_MINIWARE_MODEL_CONFIG_H_ -#define BSP_MINIWARE_MODEL_CONFIG_H_ -/* - * Lookup for mapping features <-> Models - */ - -#if defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) > 1 -#error "Multiple models defined!" -#elif defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) == 0 -#error "No model defined!" -#endif - -#ifdef MODEL_TS100 -#define POW_DC -#define ACCEL_MMA -#define ACCEL_LIS -#define TEMP_TMP36 -#define BATTFILTERDEPTH 32 -#endif - -#ifdef MODEL_TS80 -#define ACCEL_LIS -#define POW_QC -#define TEMP_TMP36 -#define LIS_ORI_FLIP -#define OLED_FLIP -#define BATTFILTERDEPTH 8 -#endif - -#ifdef MODEL_TS80P -#define ACCEL_LIS -#define ACCEL_MSA -#define POW_PD -#define POW_QC -#define TEMP_NTC -#define I2C_SOFT -#define LIS_ORI_FLIP -#define OLED_FLIP -#define BATTFILTERDEPTH 8 -#endif - -#endif /* BSP_MINIWARE_MODEL_CONFIG_H_ */ diff --git a/source/Core/BSP/Miniware/Pins.h b/source/Core/BSP/Miniware/Pins.h index 4e4c9085..e8851d26 100644 --- a/source/Core/BSP/Miniware/Pins.h +++ b/source/Core/BSP/Miniware/Pins.h @@ -7,7 +7,7 @@ #ifndef BSP_MINIWARE_PINS_H_ #define BSP_MINIWARE_PINS_H_ -#include "Model_Config.h" +#include "configuration.h" #ifdef MODEL_TS100 diff --git a/source/Core/BSP/Miniware/Power.cpp b/source/Core/BSP/Miniware/Power.cpp index 2fcbdcb1..5aa42b42 100644 --- a/source/Core/BSP/Miniware/Power.cpp +++ b/source/Core/BSP/Miniware/Power.cpp @@ -1,9 +1,9 @@ #include "BSP.h" #include "BSP_Power.h" -#include "Model_Config.h" #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "configuration.h" #include "fusb_user.h" #include "fusbpd.h" #include "int_n.h" diff --git a/source/Core/BSP/Miniware/QC_GPIO.cpp b/source/Core/BSP/Miniware/QC_GPIO.cpp index 288e61ac..84edd842 100644 --- a/source/Core/BSP/Miniware/QC_GPIO.cpp +++ b/source/Core/BSP/Miniware/QC_GPIO.cpp @@ -5,11 +5,12 @@ * Author: Ralim */ #include "BSP.h" -#include "Model_Config.h" #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "configuration.h" #include "stm32f1xx_hal.h" + #ifdef POW_QC void QC_DPlusZero_Six() { HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); // pull down D+ diff --git a/source/Core/BSP/Miniware/Software_I2C.h b/source/Core/BSP/Miniware/Software_I2C.h index 214faa5a..ceca0131 100644 --- a/source/Core/BSP/Miniware/Software_I2C.h +++ b/source/Core/BSP/Miniware/Software_I2C.h @@ -8,7 +8,7 @@ #ifndef BSP_MINIWARE_SOFTWARE_I2C_H_ #define BSP_MINIWARE_SOFTWARE_I2C_H_ #include "BSP.h" -#include "Model_Config.h" +#include "configuration.h" #include "stm32f1xx_hal.h" #ifdef I2C_SOFT diff --git a/source/Core/Inc/configuration.h b/source/Core/BSP/Miniware/configuration.h similarity index 63% rename from source/Core/Inc/configuration.h rename to source/Core/BSP/Miniware/configuration.h index d4864556..6f5ab5a4 100644 --- a/source/Core/Inc/configuration.h +++ b/source/Core/BSP/Miniware/configuration.h @@ -1,10 +1,10 @@ -#pragma once -#include "Model_Config.h" +#ifndef CONFIGURATION_H_ +#define CONFIGURATION_H_ #include "Settings.h" #include /** * Configuration.h - * Define here your default pre settings for TS80 or TS100 + * Define here your default pre settings for TS80(P) or TS100 * */ @@ -57,7 +57,7 @@ * */ #define ORIENTATION_MODE 0 // 0: Right 1:Left 2:Automatic - Default right -#define REVERSE_BUTTON_TEMP_CHANGE 0 // 0:Default 1:Reverse - Reverse the plus and minus button assigment for temperatur change +#define REVERSE_BUTTON_TEMP_CHANGE 0 // 0:Default 1:Reverse - Reverse the plus and minus button assigment for temperature change /** * Temp change settings @@ -114,14 +114,16 @@ #define OP_AMP_GAIN_STAGE_TS80 (1 + (OP_AMP_Rf_TS80 / OP_AMP_Rin_TS80)) -#define OP_AMP_Rf_MHP30 268500 // 268.5 Kilo-ohms -> Measured -#define OP_AMP_Rin_MHP30 1600 // 1.6 Kilo-ohms -> Measured - -#define OP_AMP_GAIN_STAGE_MHP30 (1 + (OP_AMP_Rf_MHP30 / OP_AMP_Rin_MHP30)) // Deriving the Voltage div: // Vin_max = (3.3*(r1+r2))/(r2) // vdiv = (32768*4)/(vin_max*10) +#if defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) > 1 +#error "Multiple models defined!" +#elif defined(MODEL_TS100) + defined(MODEL_TS80) + defined(MODEL_TS80P) == 0 +#error "No model defined!" +#endif + #ifdef MODEL_TS100 #define SOLDERING_TEMP 320 // Default soldering temp is 320.0 °C #define VOLTAGE_DIV 467 // 467 - Default divider from schematic @@ -140,26 +142,10 @@ #define MIN_TEMP_F 60 // Min soldering temp selectable °F #define MIN_BOOST_TEMP_C 250 // The min settable temp for boost mode °C #define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F -#endif - -#ifdef MODEL_Pinecil -#define SOLDERING_TEMP 320 // Default soldering temp is 320.0 °C -#define VOLTAGE_DIV 467 // 467 - Default divider from schematic -#define CALIBRATION_OFFSET 900 // 900 - Default adc offset in uV -#define PID_POWER_LIMIT 70 // Sets the max pwm power limit -#define POWER_LIMIT 0 // 0 watts default limit -#define MAX_POWER_LIMIT 65 // -#define POWER_LIMIT_STEPS 5 // -#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_TS100 // Uses TS100 resistors -#define TEMP_uV_LOOKUP_HAKKO // Use Hakko lookup table -#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate -#define PID_TIM_HZ (8) // Tick rate of the PID loop -#define MAX_TEMP_C 450 // Max soldering temp selectable °C -#define MAX_TEMP_F 850 // Max soldering temp selectable °F -#define MIN_TEMP_C 10 // Min soldering temp selectable °C -#define MIN_TEMP_F 60 // Min soldering temp selectable °F -#define MIN_BOOST_TEMP_C 250 // The min settable temp for boost mode °C -#define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F +#define POW_DC +#define ACCEL_MMA +#define ACCEL_LIS +#define TEMP_TMP36 #endif #ifdef MODEL_TS80 @@ -180,6 +166,11 @@ #define MIN_TEMP_F 60 // Min soldering temp selectable °F #define MIN_BOOST_TEMP_C 250 // The min settable temp for boost mode °C #define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F +#define ACCEL_LIS +#define POW_QC +#define TEMP_TMP36 +#define LIS_ORI_FLIP +#define OLED_FLIP #endif #ifdef MODEL_TS80P @@ -200,64 +191,31 @@ #define MIN_TEMP_F 60 // Min soldering temp selectable °F #define MIN_BOOST_TEMP_C 250 // The min settable temp for boost mode °C #define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F - -#endif - -#ifdef MODEL_MHP30 -#define SOLDERING_TEMP 200 // Default soldering temp is 200.0 °C -#define VOLTAGE_DIV 360 // Default for MHP30 -#define PID_POWER_LIMIT 65 // Sets the max pwm power limit -#define CALIBRATION_OFFSET 0 // the adc offset in uV - MHP compensates automagically -#define POWER_LIMIT 65 // 65 watts default power limit -#define MAX_POWER_LIMIT 65 // -#define POWER_LIMIT_STEPS 1 // -#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_MHP30 // -#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate -#define MODEL_HAS_DCDC // Has inductor to current filter -#define PID_TIM_HZ (16) // -#define THERMAL_MASS_OVERSHOOTS // We have overshoot so reverse direction of compensation -#define MAX_TEMP_C 300 // Max soldering temp selectable °C -#define MAX_TEMP_F 570 // Max soldering temp selectable °F -#define MIN_TEMP_C 10 // Min soldering temp selectable °C -#define MIN_TEMP_F 60 // Min soldering temp selectable °F -#define MIN_BOOST_TEMP_C 150 // The min settable temp for boost mode °C -#define MIN_BOOST_TEMP_F 300 // The min settable temp for boost mode °F -#define NO_DISPLAY_ROTATE // Disable OLED rotation by accel -#define SLEW_LIMIT 50 // Limit to 3.0 Watts per 64ms pid loop update rate slew rate +#define ACCEL_LIS +#define ACCEL_MSA +#define POW_PD +#define POW_QC +#define TEMP_NTC +#define I2C_SOFT +#define LIS_ORI_FLIP +#define OLED_FLIP #endif #ifdef MODEL_TS100 -const int32_t HARDWARE_MAX_WATTAGE_X10 = 750; -const int32_t TIP_THERMAL_MASS = 65; // X10 watts to raise 1 deg C in 1 second -const uint8_t tipResistance = 75; // x10 ohms, 7.5 typical for ts100 tips -#endif - -#ifdef MODEL_Pinecil -const int32_t HARDWARE_MAX_WATTAGE_X10 = 750; -const int32_t TIP_THERMAL_MASS = 65; // X10 watts to raise 1 deg C in 1 second -const uint8_t tipResistance = 75; // x10 ohms, 7.5 typical for ts100 tips +#define HARDWARE_MAX_WATTAGE_X10 750 +#define TIP_THERMAL_MASS 65 // X10 watts to raise 1 deg C in 1 second +#define tipResistance 75 // x10 ohms, 7.5 typical for ts100 tips #endif #ifdef MODEL_TS80 -const int32_t HARDWARE_MAX_WATTAGE_X10 = 180; -const uint32_t TIP_THERMAL_MASS = 40; -const uint8_t tipResistance = 45; // x10 ohms, 4.5 typical for ts80 tips +#define HARDWARE_MAX_WATTAGE_X10 180 +#define TIP_THERMAL_MASS 40 +#define tipResistance 45 // x10 ohms, 4.5 typical for ts80 tips #endif #ifdef MODEL_TS80P -const int32_t HARDWARE_MAX_WATTAGE_X10 = 300; -const uint32_t TIP_THERMAL_MASS = 40; -const uint8_t tipResistance = 45; // x10 ohms, 4.5 typical for ts80 tips +#define HARDWARE_MAX_WATTAGE_X10 300 +#define TIP_THERMAL_MASS 40 +#define tipResistance 45 // x10 ohms, 4.5 typical for ts80 tips #endif - -#ifdef MODEL_MHP30 -const int32_t HARDWARE_MAX_WATTAGE_X10 = 650; -const uint32_t TIP_THERMAL_MASS = 65; // TODO, needs refinement -const uint8_t tipResistance = 60; // x10 ohms, ~6 typical #endif - -#ifdef POW_QC_20V -#define QC_SETTINGS_MAX 3 -#else -#define QC_SETTINGS_MAX 2 -#endif \ No newline at end of file diff --git a/source/Core/BSP/Miniware/fusb_user.cpp b/source/Core/BSP/Miniware/fusb_user.cpp index c37bb5ff..13454db7 100644 --- a/source/Core/BSP/Miniware/fusb_user.cpp +++ b/source/Core/BSP/Miniware/fusb_user.cpp @@ -1,4 +1,4 @@ -#include "Model_Config.h" +#include "configuration.h" #ifdef POW_PD #include "BSP.h" #include "I2CBB.hpp" diff --git a/source/Core/BSP/Miniware/preRTOS.cpp b/source/Core/BSP/Miniware/preRTOS.cpp index 5d9852b4..931df14e 100644 --- a/source/Core/BSP/Miniware/preRTOS.cpp +++ b/source/Core/BSP/Miniware/preRTOS.cpp @@ -7,11 +7,12 @@ #include "BSP.h" #include "I2CBB.hpp" -#include "Model_Config.h" #include "Pins.h" #include "Setup.h" +#include "configuration.h" #include "fusbpd.h" #include + void preRToSInit() { /* Reset of all peripherals, Initializes the Flash interface and the Systick. */ diff --git a/source/Core/BSP/Pine64/Model_Config.h b/source/Core/BSP/Pine64/Model_Config.h deleted file mode 100644 index 1a63894e..00000000 --- a/source/Core/BSP/Pine64/Model_Config.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Model_Config.h - * - * Created on: 25 Jul 2020 - * Author: Ralim - */ - -#ifndef BSP_PINE64_MODEL_CONFIG_H_ -#define BSP_PINE64_MODEL_CONFIG_H_ -/* - * Lookup for mapping features <-> Models - */ - -#if defined(MODEL_Pinecil) == 0 -#error "No model defined!" -#endif - -#ifdef MODEL_Pinecil -#define POW_PD -#define POW_QC -#define POW_DC -#define POW_QC_20V -#define ENABLE_QC2 -#define TEMP_TMP36 -#define ACCEL_BMA -#define ACCEL_SC7 -#define HALL_SENSOR -#define HALL_SI7210 -#define BATTFILTERDEPTH 32 -#define DEBUG_UART_OUTPUT -#endif - -#endif /* BSP_PINE64_MODEL_CONFIG_H_ */ diff --git a/source/Core/BSP/Pine64/Power.cpp b/source/Core/BSP/Pine64/Power.cpp index 22fe53e0..5e60764e 100644 --- a/source/Core/BSP/Pine64/Power.cpp +++ b/source/Core/BSP/Pine64/Power.cpp @@ -1,9 +1,9 @@ #include "BSP.h" #include "BSP_Power.h" -#include "Model_Config.h" #include "Pins.h" #include "QC3.h" #include "Settings.h" +#include "configuration.h" #include "fusb_user.h" #include "fusbpd.h" #include "int_n.h" diff --git a/source/Core/BSP/Pine64/configuration.h b/source/Core/BSP/Pine64/configuration.h new file mode 100644 index 00000000..9d8c7f75 --- /dev/null +++ b/source/Core/BSP/Pine64/configuration.h @@ -0,0 +1,151 @@ +#ifndef CONFIGURATION_H_ +#define CONFIGURATION_H_ +#include "Settings.h" +#include +/** + * Configuration.h + * Define here your default pre settings for Pinecil + * + */ + +//=========================================================================== +//============================= Default Settings ============================ +//=========================================================================== +/** + * Default soldering temp is 320.0 C + * Temperature the iron sleeps at - default 150.0 C + */ + +#define SLEEP_TEMP 150 // Default sleep temperature +#define BOOST_TEMP 420 // Default boost temp. +#define BOOST_MODE_ENABLED 1 // 0: Disable 1: Enable + +/** + * Blink the temperature on the cooling screen when its > 50C + */ +#define COOLING_TEMP_BLINK 0 // 0: Disable 1: Enable + +/** + * How many seconds/minutes we wait until going to sleep/shutdown. + * Values -> SLEEP_TIME * 10; i.e. 5*10 = 50 Seconds! + */ +#define SLEEP_TIME 5 // x10 Seconds +#define SHUTDOWN_TIME 10 // Minutes + +/** + * Auto start off for safety. + * Pissible values are: + * 0 - none + * 1 - Soldering Temperature + * 2 - Sleep Temperature + * 3 - Sleep Off Temperature + */ +#define AUTO_START_MODE 0 // Default to none + +/** + * Locking Mode + * When in soldering mode a long press on both keys toggle the lock of the buttons + * Possible values are: + * 0 - Desactivated + * 1 - Lock except boost + * 2 - Full lock + */ +#define LOCKING_MODE 0 // Default to desactivated for safety + +/** + * OLED Orientation + * + */ +#define ORIENTATION_MODE 0 // 0: Right 1:Left 2:Automatic - Default right +#define REVERSE_BUTTON_TEMP_CHANGE 0 // 0:Default 1:Reverse - Reverse the plus and minus button assigment for temperature change + +/** + * Temp change settings + */ +#define TEMP_CHANGE_SHORT_STEP 1 // Default temp change short step +1 +#define TEMP_CHANGE_LONG_STEP 10 // Default temp change long step +10 +#define TEMP_CHANGE_SHORT_STEP_MAX 50 // Temp change short step MAX value +#define TEMP_CHANGE_LONG_STEP_MAX 90 // Temp change long step MAX value + +/* Power pulse for keeping power banks awake*/ +#define POWER_PULSE_INCREMENT 1 +#define POWER_PULSE_MAX 100 // x10 max watts +#define POWER_PULSE_WAIT_MAX 9 // 9*2.5s = 22.5 seconds +#define POWER_PULSE_DURATION_MAX 9 // 9*250ms = 2.25 seconds + +#ifdef MODEL_Pinecil +#define POWER_PULSE_DEFAULT 0 +#else +#define POWER_PULSE_DEFAULT 5 +#endif +#define POWER_PULSE_WAIT_DEFAULT 4 // Default rate of the power pulse: 4*2500 = 10000 ms = 10 s +#define POWER_PULSE_DURATION_DEFAULT 1 // Default duration of the power pulse: 1*250 = 250 ms + +/** + * OLED Orientation Sensitivity on Automatic mode! + * Motion Sensitivity <0=Off 1=Least Sensitive 9=Most Sensitive> + */ +#define SENSITIVITY 7 // Default 7 + +/** + * Detailed soldering screen + * Detailed idle screen (off for first time users) + */ +#define DETAILED_SOLDERING 0 // 0: Disable 1: Enable - Default 0 +#define DETAILED_IDLE 0 // 0: Disable 1: Enable - Default 0 + +#define THERMAL_RUNAWAY_TIME_SEC 20 +#define THERMAL_RUNAWAY_TEMP_C 20 + +#define CUT_OUT_SETTING 0 // default to no cut-off voltage +#define RECOM_VOL_CELL 33 // Minimum voltage per cell (Recommended 3.3V (33)) +#define TEMPERATURE_INF 0 // default to 0 +#define DESCRIPTION_SCROLL_SPEED 0 // 0: Slow 1: Fast - default to slow +#define ANIMATION_LOOP 1 // 0: off 1: on +#define ANIMATION_SPEED settingOffSpeed_t::MEDIUM + +#define OP_AMP_Rf_Pinecil 750 * 1000 // 750 Kilo-ohms -> From schematic, R1 +#define OP_AMP_Rin_Pinecil 2370 // 2.37 Kilo-ohms -> From schematic, R2 + +#define OP_AMP_GAIN_STAGE_PINECIL (1 + (OP_AMP_Rf_Pinecil / OP_AMP_Rin_Pinecil)) + +#if defined(MODEL_Pinecil) == 0 +#error "No model defined!" +#endif + +#ifdef MODEL_Pinecil +#define SOLDERING_TEMP 320 // Default soldering temp is 320.0 °C +#define VOLTAGE_DIV 467 // 467 - Default divider from schematic +#define CALIBRATION_OFFSET 900 // 900 - Default adc offset in uV +#define PID_POWER_LIMIT 70 // Sets the max pwm power limit +#define POWER_LIMIT 0 // 0 watts default limit +#define MAX_POWER_LIMIT 65 // +#define POWER_LIMIT_STEPS 5 // +#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_PINECIL // Uses Pinecil resistors +#define TEMP_uV_LOOKUP_HAKKO // Use Hakko lookup table +#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate +#define PID_TIM_HZ (8) // Tick rate of the PID loop +#define MAX_TEMP_C 450 // Max soldering temp selectable °C +#define MAX_TEMP_F 850 // Max soldering temp selectable °F +#define MIN_TEMP_C 10 // Min soldering temp selectable °C +#define MIN_TEMP_F 60 // Min soldering temp selectable °F +#define MIN_BOOST_TEMP_C 250 // The min settable temp for boost mode °C +#define MIN_BOOST_TEMP_F 480 // The min settable temp for boost mode °F + +#define POW_PD +#define POW_QC +#define POW_DC +#define POW_QC_20V +#define ENABLE_QC2 +#define TEMP_TMP36 +#define ACCEL_BMA +#define ACCEL_SC7 +#define HALL_SENSOR +#define HALL_SI7210 +#define DEBUG_UART_OUTPUT + +#define HARDWARE_MAX_WATTAGE_X10 750 +#define TIP_THERMAL_MASS 65 // X10 watts to raise 1 deg C in 1 second +#define tipResistance 75 // x10 ohms, 7.5 typical for Pinecil tips +#endif +#endif diff --git a/source/Core/BSP/Pine64/fusb_user.cpp b/source/Core/BSP/Pine64/fusb_user.cpp index 2d566399..5b9137ec 100644 --- a/source/Core/BSP/Pine64/fusb_user.cpp +++ b/source/Core/BSP/Pine64/fusb_user.cpp @@ -1,4 +1,4 @@ -#include "Model_Config.h" +#include "configuration.h" #ifdef POW_PD #include "BSP.h" #include "I2C_Wrapper.hpp" diff --git a/source/Core/Drivers/FUSB302/fusbpd.cpp b/source/Core/Drivers/FUSB302/fusbpd.cpp index f8a74155..18920c03 100644 --- a/source/Core/Drivers/FUSB302/fusbpd.cpp +++ b/source/Core/Drivers/FUSB302/fusbpd.cpp @@ -4,7 +4,7 @@ * Created on: 13 Jun 2020 * Author: Ralim */ -#include "Model_Config.h" +#include "configuration.h" #ifdef POW_PD #include "BSP.h" #include "I2CBB.hpp" diff --git a/source/Core/Drivers/I2CBB.cpp b/source/Core/Drivers/I2CBB.cpp index f90b09fc..b1fd6b7d 100644 --- a/source/Core/Drivers/I2CBB.cpp +++ b/source/Core/Drivers/I2CBB.cpp @@ -4,7 +4,7 @@ * Created on: 12 Jun 2020 * Author: Ralim */ -#include "Model_Config.h" +#include "configuration.h" #ifdef I2C_SOFT #include "FreeRTOS.h" #include diff --git a/source/Core/Drivers/I2CBB.hpp b/source/Core/Drivers/I2CBB.hpp index cf2e4df1..a66d5954 100644 --- a/source/Core/Drivers/I2CBB.hpp +++ b/source/Core/Drivers/I2CBB.hpp @@ -7,7 +7,7 @@ #ifndef BSP_MINIWARE_I2CBB_HPP_ #define BSP_MINIWARE_I2CBB_HPP_ -#include "Model_Config.h" +#include "configuration.h" #ifdef I2C_SOFT #include "BSP.h" #include "FreeRTOS.h" diff --git a/source/Core/Drivers/OLED.hpp b/source/Core/Drivers/OLED.hpp index f9d63a5a..a13e02a3 100644 --- a/source/Core/Drivers/OLED.hpp +++ b/source/Core/Drivers/OLED.hpp @@ -10,7 +10,7 @@ #ifndef OLED_HPP_ #define OLED_HPP_ #include "Font.h" -#include "Model_Config.h" +#include "configuration.h" #include #include #include diff --git a/source/Core/Src/Settings.cpp b/source/Core/Src/Settings.cpp index b838ba76..bf4f4ef4 100644 --- a/source/Core/Src/Settings.cpp +++ b/source/Core/Src/Settings.cpp @@ -15,6 +15,12 @@ #include // for memset bool sanitiseSettings(); +#ifdef POW_QC_20V +#define QC_SETTINGS_MAX 3 +#else +#define QC_SETTINGS_MAX 2 +#endif + /* * This struct must be a multiple of 2 bytes as it is saved / restored from * flash in uint16_t chunks diff --git a/source/Core/Threads/MOVThread.cpp b/source/Core/Threads/MOVThread.cpp index c929e8bd..e0e7c86e 100644 --- a/source/Core/Threads/MOVThread.cpp +++ b/source/Core/Threads/MOVThread.cpp @@ -12,17 +12,18 @@ #include "LIS2DH12.hpp" #include "MMA8652FC.hpp" #include "MSA301.h" -#include "Model_Config.h" #include "QC3.h" #include "SC7A20.hpp" #include "Settings.h" #include "TipThermoModel.h" #include "cmsis_os.h" +#include "configuration.h" #include "history.hpp" #include "main.hpp" #include "power.hpp" #include "stdlib.h" #include "task.h" + #define MOVFilter 8 uint8_t accelInit = 0; TickType_t lastMovementTime = 0; From 6f46fc0bed777055fc8d77eb2c6a2adee375cb2d Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 20:27:03 +1000 Subject: [PATCH 20/25] style --- source/Core/BSP/MHP30/BSP.cpp | 1 - source/Core/BSP/MHP30/configuration.h | 39 +++++++++++++-------------- 2 files changed, 19 insertions(+), 21 deletions(-) diff --git a/source/Core/BSP/MHP30/BSP.cpp b/source/Core/BSP/MHP30/BSP.cpp index 1561ec06..12dac966 100644 --- a/source/Core/BSP/MHP30/BSP.cpp +++ b/source/Core/BSP/MHP30/BSP.cpp @@ -12,7 +12,6 @@ #include "main.hpp" #include - WS2812 ws2812; volatile uint16_t PWMSafetyTimer = 0; volatile uint8_t pendingPWM = 0; diff --git a/source/Core/BSP/MHP30/configuration.h b/source/Core/BSP/MHP30/configuration.h index b6f4104c..21e39fd9 100644 --- a/source/Core/BSP/MHP30/configuration.h +++ b/source/Core/BSP/MHP30/configuration.h @@ -118,26 +118,25 @@ #endif #ifdef MODEL_MHP30 -#define SOLDERING_TEMP 200 // Default soldering temp is 200.0 °C -#define VOLTAGE_DIV 360 // Default for MHP30 -#define PID_POWER_LIMIT 65 // Sets the max pwm power limit -#define CALIBRATION_OFFSET 0 // the adc offset in uV - MHP compensates automagically -#define POWER_LIMIT 65 // 65 watts default power limit -#define MAX_POWER_LIMIT 65 // -#define POWER_LIMIT_STEPS 1 // -#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_MHP30 // -#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate -#define MODEL_HAS_DCDC // Has inductor to current filter -#define PID_TIM_HZ (16) // -#define THERMAL_MASS_OVERSHOOTS // We have overshoot so reverse direction of compensation -#define MAX_TEMP_C 300 // Max soldering temp selectable °C -#define MAX_TEMP_F 570 // Max soldering temp selectable °F -#define MIN_TEMP_C 10 // Min soldering temp selectable °C -#define MIN_TEMP_F 60 // Min soldering temp selectable °F -#define MIN_BOOST_TEMP_C 150 // The min settable temp for boost mode °C -#define MIN_BOOST_TEMP_F 300 // The min settable temp for boost mode °F -#define NO_DISPLAY_ROTATE // Disable OLED rotation by accel -#define SLEW_LIMIT 50 // Limit to 3.0 Watts per 64ms pid loop update rate slew rate +#define SOLDERING_TEMP 200 // Default soldering temp is 200.0 °C +#define VOLTAGE_DIV 360 // Default for MHP30 +#define PID_POWER_LIMIT 65 // Sets the max pwm power limit +#define CALIBRATION_OFFSET 0 // the adc offset in uV - MHP compensates automagically +#define POWER_LIMIT 65 // 65 watts default power limit +#define MAX_POWER_LIMIT 65 // +#define POWER_LIMIT_STEPS 1 // +#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_MHP30 // +#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate +#define MODEL_HAS_DCDC // Has inductor to current filter +#define PID_TIM_HZ (16) // +#define MAX_TEMP_C 300 // Max soldering temp selectable °C +#define MAX_TEMP_F 570 // Max soldering temp selectable °F +#define MIN_TEMP_C 10 // Min soldering temp selectable °C +#define MIN_TEMP_F 60 // Min soldering temp selectable °F +#define MIN_BOOST_TEMP_C 150 // The min settable temp for boost mode °C +#define MIN_BOOST_TEMP_F 300 // The min settable temp for boost mode °F +#define NO_DISPLAY_ROTATE // Disable OLED rotation by accel +#define SLEW_LIMIT 50 // Limit to 3.0 Watts per 64ms pid loop update rate slew rate #define ACCEL_MSA #define POW_PD #define TEMP_NTC From 7c014062be20b048157aae0f10408eaf2d8fe9f0 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 21:16:09 +1000 Subject: [PATCH 21/25] Update QC3.cpp --- source/Core/Src/QC3.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Core/Src/QC3.cpp b/source/Core/Src/QC3.cpp index 4fa0bf4f..311d1b73 100644 --- a/source/Core/Src/QC3.cpp +++ b/source/Core/Src/QC3.cpp @@ -7,9 +7,9 @@ // Quick charge 3.0 supporting functions #include "QC3.h" - #include "BSP.h" #include "cmsis_os.h" +#include "configuration.h" #include "stdint.h" enum QCState { NOT_STARTED = 0, // Have not checked From f88e6bccf41890978435191884991fe9ec02e922 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 21:18:23 +1000 Subject: [PATCH 22/25] Update Setup.cpp --- source/Core/BSP/Pine64/Setup.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Core/BSP/Pine64/Setup.cpp b/source/Core/BSP/Pine64/Setup.cpp index 0b683036..96532b85 100644 --- a/source/Core/BSP/Pine64/Setup.cpp +++ b/source/Core/BSP/Pine64/Setup.cpp @@ -274,7 +274,7 @@ void setup_timers() { /* CH0 configured to implement the PWM irq's for the output control*/ timer_channel_output_struct_para_init(&timer_ocintpara); - timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_HIGH; + timer_ocintpara.ocpolarity = TIMER_OC_POLARITY_LOW; timer_ocintpara.outputstate = TIMER_CCX_ENABLE; timer_channel_output_config(TIMER1, TIMER_CH_0, &timer_ocintpara); From b1479733ca4032563fcc13002399e8177b32297b Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 21:24:18 +1000 Subject: [PATCH 23/25] Move detailed display options For @discip :joy: --- source/Core/Src/gui.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/source/Core/Src/gui.cpp b/source/Core/Src/gui.cpp index f9855d4d..78627bb6 100644 --- a/source/Core/Src/gui.cpp +++ b/source/Core/Src/gui.cpp @@ -187,6 +187,8 @@ const menuitem UIMenu[] = { * Display orientation * Cooldown blink * Reverse Temp change buttons + - + * Detailed IDLE + * Detailed Soldering */ {SETTINGS_DESC(SettingsItemIndex::TemperatureUnit), settings_setTempF, settings_displayTempF, SettingsOptions::SettingsOptionsLength}, /* Temperature units, this has to be the first element in the array to work with the logic in settings_enterUIMenu() */ @@ -196,12 +198,14 @@ const menuitem UIMenu[] = { {SETTINGS_DESC(SettingsItemIndex::CooldownBlink), nullptr, settings_displayCoolingBlinkEnabled, SettingsOptions::CoolingTempBlink}, /*Cooling blink warning*/ {SETTINGS_DESC(SettingsItemIndex::ScrollingSpeed), nullptr, settings_displayScrollSpeed, SettingsOptions::DescriptionScrollSpeed}, /*Scroll Speed for descriptions*/ {SETTINGS_DESC(SettingsItemIndex::ReverseButtonTempChange), nullptr, settings_displayReverseButtonTempChangeEnabled, - SettingsOptions::ReverseButtonTempChangeEnabled}, /* Reverse Temp change buttons + - */ - {SETTINGS_DESC(SettingsItemIndex::AnimSpeed), nullptr, settings_displayAnimationSpeed, SettingsOptions::AnimationSpeed}, /*Animation Speed adjustment */ - {SETTINGS_DESC(SettingsItemIndex::AnimLoop), nullptr, settings_displayAnimationLoop, SettingsOptions::AnimationLoop}, /*Animation Loop switch */ - {SETTINGS_DESC(SettingsItemIndex::Brightness), nullptr, settings_displayBrightnessLevel, SettingsOptions::OLEDBrightness}, /*Brightness Level*/ - {SETTINGS_DESC(SettingsItemIndex::ColourInversion), nullptr, settings_displayInvertColor, SettingsOptions::OLEDInversion}, /*Invert screen colour*/ - {0, nullptr, nullptr, SettingsOptions::SettingsOptionsLength} // end of menu marker. DO NOT REMOVE + SettingsOptions::ReverseButtonTempChangeEnabled}, /* Reverse Temp change buttons + - */ + {SETTINGS_DESC(SettingsItemIndex::AnimSpeed), nullptr, settings_displayAnimationSpeed, SettingsOptions::AnimationSpeed}, /*Animation Speed adjustment */ + {SETTINGS_DESC(SettingsItemIndex::AnimLoop), nullptr, settings_displayAnimationLoop, SettingsOptions::AnimationLoop}, /*Animation Loop switch */ + {SETTINGS_DESC(SettingsItemIndex::Brightness), nullptr, settings_displayBrightnessLevel, SettingsOptions::OLEDBrightness}, /*Brightness Level*/ + {SETTINGS_DESC(SettingsItemIndex::ColourInversion), nullptr, settings_displayInvertColor, SettingsOptions::OLEDInversion}, /*Invert screen colour*/ + {SETTINGS_DESC(SettingsItemIndex::AdvancedIdle), nullptr, settings_displayAdvancedIDLEScreens, SettingsOptions::DetailedIDLE}, /* Advanced idle screen*/ + {SETTINGS_DESC(SettingsItemIndex::AdvancedSoldering), nullptr, settings_displayAdvancedSolderingScreens, SettingsOptions::DetailedSoldering}, /* Advanced soldering screen*/ + {0, nullptr, nullptr, SettingsOptions::SettingsOptionsLength} // end of menu marker. DO NOT REMOVE }; const menuitem PowerSavingMenu[] = { /* @@ -225,8 +229,6 @@ const menuitem advancedMenu[] = { /* * Power limit - * Detailed IDLE - * Detailed Soldering * Calibrate Temperature * Calibrate Input V * Reset Settings @@ -237,8 +239,6 @@ const menuitem advancedMenu[] = { * Power Pulse Duration */ {SETTINGS_DESC(SettingsItemIndex::PowerLimit), nullptr, settings_displayPowerLimit, SettingsOptions::PowerLimit}, /*Power limit*/ - {SETTINGS_DESC(SettingsItemIndex::AdvancedIdle), nullptr, settings_displayAdvancedIDLEScreens, SettingsOptions::DetailedIDLE}, /* Advanced idle screen*/ - {SETTINGS_DESC(SettingsItemIndex::AdvancedSoldering), nullptr, settings_displayAdvancedSolderingScreens, SettingsOptions::DetailedSoldering}, /* Advanced soldering screen*/ {SETTINGS_DESC(SettingsItemIndex::SettingsReset), settings_setResetSettings, settings_displayResetSettings, SettingsOptions::SettingsOptionsLength}, /*Resets settings*/ {SETTINGS_DESC(SettingsItemIndex::TemperatureCalibration), settings_setCalibrate, settings_displayCalibrate, SettingsOptions::SettingsOptionsLength}, /*Calibrate tip*/ {SETTINGS_DESC(SettingsItemIndex::VoltageCalibration), settings_setCalibrateVIN, settings_displayCalibrateVIN, SettingsOptions::SettingsOptionsLength}, /*Voltage input cal*/ From b04fcb9246672b57c9e7018a5c5d8e49dd0c3c64 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 21:28:50 +1000 Subject: [PATCH 24/25] PD negotiation timeout -> Off --- source/Core/Src/gui.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source/Core/Src/gui.cpp b/source/Core/Src/gui.cpp index 78627bb6..3b8c9c10 100644 --- a/source/Core/Src/gui.cpp +++ b/source/Core/Src/gui.cpp @@ -352,8 +352,12 @@ static bool settings_displayQCInputV(void) { static bool settings_displayPDNegTimeout(void) { printShortDescription(SettingsItemIndex::PDNegTimeout, 5); - OLED::printNumber(getSettingValue(SettingsOptions::PDNegTimeout), 2, FontStyle::LARGE); - + auto value = getSettingValue(SettingsOptions::PDNegTimeout); + if (value == 0) { + OLED::print(translatedString(Tr->OffString), FontStyle::LARGE); + } else { + OLED::printNumber(value, 2, FontStyle::LARGE); + } return false; } #endif From ed374ffb57cbc4d5e48f02a99e0bfde40757be11 Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 15 Sep 2021 21:55:43 +1000 Subject: [PATCH 25/25] Update PIDThread.cpp --- source/Core/Threads/PIDThread.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/Core/Threads/PIDThread.cpp b/source/Core/Threads/PIDThread.cpp index f7721303..b87a488e 100644 --- a/source/Core/Threads/PIDThread.cpp +++ b/source/Core/Threads/PIDThread.cpp @@ -137,7 +137,7 @@ int32_t getPIDResultX10Watts(int32_t setpointDelta) { // so we basically double the need (gain = 2) to get what we want. return powerStore.update(TIP_THERMAL_MASS * setpointDelta, // the required power TIP_THERMAL_MASS, // Inertia, smaller numbers increase dominance of the previous value - 1, // gain + 2, // gain rate, // PID cycle frequency getX10WattageLimits()); }