Merge pull request #2012 from Ralim/issue-1946-thermal-runaway-update
Rewrite Thermal Runaway detection
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -215,3 +215,4 @@ Logo GUI/TS100 Logo Editor/TS100 Logo Editor/bin/
|
|||||||
|
|
||||||
# Tests/linters/sanitizers
|
# Tests/linters/sanitizers
|
||||||
source/check-style.log
|
source/check-style.log
|
||||||
|
.ash_history
|
||||||
|
|||||||
@@ -103,8 +103,8 @@
|
|||||||
#define DETAILED_IDLE 0 // 0: Disable 1: Enable - Default 0
|
#define DETAILED_IDLE 0 // 0: Disable 1: Enable - Default 0
|
||||||
|
|
||||||
// Due to large thermal mass of the PCB being heated we need to pull this back a bit
|
// Due to large thermal mass of the PCB being heated we need to pull this back a bit
|
||||||
#define THERMAL_RUNAWAY_TIME_SEC 45
|
#define THERMAL_RUNAWAY_TIME_SEC 20
|
||||||
#define THERMAL_RUNAWAY_TEMP_C 3
|
#define THERMAL_RUNAWAY_TEMP_C 2
|
||||||
|
|
||||||
#define CUT_OUT_SETTING 0 // default to no cut-off voltage
|
#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 RECOM_VOL_CELL 33 // Minimum voltage per cell (Recommended 3.3V (33))
|
||||||
|
|||||||
@@ -109,7 +109,7 @@
|
|||||||
#define DETAILED_IDLE 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_TIME_SEC 20
|
||||||
#define THERMAL_RUNAWAY_TEMP_C 10
|
#define THERMAL_RUNAWAY_TEMP_C 3
|
||||||
|
|
||||||
#define CUT_OUT_SETTING 0 // default to no cut-off voltage
|
#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 RECOM_VOL_CELL 33 // Minimum voltage per cell (Recommended 3.3V (33))
|
||||||
|
|||||||
@@ -104,7 +104,7 @@
|
|||||||
#define DETAILED_IDLE 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_TIME_SEC 20
|
||||||
#define THERMAL_RUNAWAY_TEMP_C 20
|
#define THERMAL_RUNAWAY_TEMP_C 3
|
||||||
|
|
||||||
#define CUT_OUT_SETTING 0 // default to no cut-off voltage
|
#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 RECOM_VOL_CELL 33 // Minimum voltage per cell (Recommended 3.3V (33))
|
||||||
|
|||||||
@@ -105,7 +105,7 @@
|
|||||||
#define DETAILED_IDLE 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_TIME_SEC 20
|
||||||
#define THERMAL_RUNAWAY_TEMP_C 20
|
#define THERMAL_RUNAWAY_TEMP_C 3
|
||||||
|
|
||||||
#define CUT_OUT_SETTING 0 // default to no cut-off voltage
|
#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 RECOM_VOL_CELL 33 // Minimum voltage per cell (Recommended 3.3V (33))
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
#define TEMP_uV_LOOKUP_S60
|
#define TEMP_uV_LOOKUP_S60
|
||||||
#define USB_PD_VMAX 12 // Maximum voltage for PD to negotiate
|
#define USB_PD_VMAX 12 // Maximum voltage for PD to negotiate
|
||||||
#define THERMAL_RUNAWAY_TIME_SEC 20
|
#define THERMAL_RUNAWAY_TIME_SEC 20
|
||||||
#define THERMAL_RUNAWAY_TEMP_C 10
|
#define THERMAL_RUNAWAY_TEMP_C 3
|
||||||
|
|
||||||
#define HARDWARE_MAX_WATTAGE_X10 600
|
#define HARDWARE_MAX_WATTAGE_X10 600
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@
|
|||||||
#define TEMP_uV_LOOKUP_S60
|
#define TEMP_uV_LOOKUP_S60
|
||||||
#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate
|
#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate
|
||||||
#define THERMAL_RUNAWAY_TIME_SEC 20
|
#define THERMAL_RUNAWAY_TIME_SEC 20
|
||||||
#define THERMAL_RUNAWAY_TEMP_C 10
|
#define THERMAL_RUNAWAY_TEMP_C 3
|
||||||
|
|
||||||
#define HARDWARE_MAX_WATTAGE_X10 600
|
#define HARDWARE_MAX_WATTAGE_X10 600
|
||||||
|
|
||||||
@@ -218,8 +218,8 @@
|
|||||||
|
|
||||||
#define TIP_THERMAL_MASS 30 // X10 watts to raise 1 deg C in 1 second
|
#define TIP_THERMAL_MASS 30 // X10 watts to raise 1 deg C in 1 second
|
||||||
#define TIP_THERMAL_INERTIA 10 // We use a large inertia value to smooth out the drive to the tip since its stupidly sensitive
|
#define TIP_THERMAL_INERTIA 10 // We use a large inertia value to smooth out the drive to the tip since its stupidly sensitive
|
||||||
#define THERMAL_RUNAWAY_TIME_SEC 60
|
#define THERMAL_RUNAWAY_TIME_SEC 30
|
||||||
#define THERMAL_RUNAWAY_TEMP_C 3
|
#define THERMAL_RUNAWAY_TEMP_C 2
|
||||||
|
|
||||||
#define COPPER_HEATER_COIL 1 // Have a heater coil that changes resistance on us
|
#define COPPER_HEATER_COIL 1 // Have a heater coil that changes resistance on us
|
||||||
#define TIP_RESISTANCE 52 // PCB heater, measured at ~19C. Will shift by temp a decent amount
|
#define TIP_RESISTANCE 52 // PCB heater, measured at ~19C. Will shift by temp a decent amount
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ int32_t powerSupplyWattageLimit = 0;
|
|||||||
bool heaterThermalRunaway = false;
|
bool heaterThermalRunaway = false;
|
||||||
|
|
||||||
static int32_t getPIDResultX10Watts(TemperatureType_t set_point, TemperatureType_t current_value);
|
static int32_t getPIDResultX10Watts(TemperatureType_t set_point, TemperatureType_t current_value);
|
||||||
static void detectThermalRunaway(const TemperatureType_t currentTipTempInC, const TemperatureType_t tError);
|
static void detectThermalRunaway(const TemperatureType_t currentTipTempInC, const uint32_t x10WattsOut);
|
||||||
static void setOutputx10WattsViaFilters(int32_t x10Watts);
|
static void setOutputx10WattsViaFilters(int32_t x10Watts);
|
||||||
static int32_t getX10WattageLimits();
|
static int32_t getX10WattageLimits();
|
||||||
|
|
||||||
@@ -92,8 +92,8 @@ void startPIDTask(void const *argument __unused) {
|
|||||||
PIDTempTarget = TipThermoModel::getTipMaxInC();
|
PIDTempTarget = TipThermoModel::getTipMaxInC();
|
||||||
}
|
}
|
||||||
|
|
||||||
detectThermalRunaway(currentTipTempInC, PIDTempTarget - currentTipTempInC);
|
|
||||||
x10WattsOut = getPIDResultX10Watts(PIDTempTarget, currentTipTempInC);
|
x10WattsOut = getPIDResultX10Watts(PIDTempTarget, currentTipTempInC);
|
||||||
|
detectThermalRunaway(currentTipTempInC, x10WattsOut);
|
||||||
} else {
|
} else {
|
||||||
detectThermalRunaway(currentTipTempInC, 0);
|
detectThermalRunaway(currentTipTempInC, 0);
|
||||||
}
|
}
|
||||||
@@ -228,31 +228,59 @@ int32_t getPIDResultX10Watts(TemperatureType_t set_point, TemperatureType_t curr
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void detectThermalRunaway(const TemperatureType_t currentTipTempInC, const TemperatureType_t tError) {
|
/*
|
||||||
static TemperatureType_t tipTempCRunawayTemp = 0;
|
* Detection of thermal runaway
|
||||||
static TickType_t runawaylastChangeTime = 0;
|
* The goal of this is to handle cases where something has gone wrong
|
||||||
|
* 1. The tip MOSFET is broken, so power is being constantly applied to the tip
|
||||||
|
* a. This can show as temp being stuck at max
|
||||||
|
* b. Or temp rising when the heater is off
|
||||||
|
* 2. Broken temperature sense
|
||||||
|
* a. Temp is stuck at a value
|
||||||
|
* These boil down to either a constantly rising temperature or a temperature that is stuck at a value
|
||||||
|
* These are both covered; but looking at the eye/delta between min and max temp seen
|
||||||
|
*/
|
||||||
|
void detectThermalRunaway(const TemperatureType_t currentTipTempInC, const uint32_t x10WattsOut) {
|
||||||
|
|
||||||
// Check for thermal runaway, where it has been x seconds with negligible (y) temp rise
|
static TemperatureType_t tiptempMin = 0xFFFF; // Min tip temp seen
|
||||||
// While trying to actively heat
|
static TemperatureType_t tipTempMax = 0; // Max tip temp seen while heater is on
|
||||||
|
bool thisCycleIsHeating = x10WattsOut > 0;
|
||||||
|
static TickType_t heatCycleStart = 0;
|
||||||
|
|
||||||
// If we are more than 20C below the setpoint
|
static bool haveSeenDelta = false;
|
||||||
if ((tError > THERMAL_RUNAWAY_TEMP_C)) {
|
|
||||||
|
|
||||||
// If we have heated up by more than 20C since last sample point, snapshot time and tip temp
|
// Check for readings being pegged at the top of the ADC while the heater is off
|
||||||
TemperatureType_t delta = currentTipTempInC - tipTempCRunawayTemp;
|
if (!thisCycleIsHeating && (getTipRawTemp(0) > (0x7FFF - 16))) {
|
||||||
if (delta > THERMAL_RUNAWAY_TEMP_C) {
|
heaterThermalRunaway = true;
|
||||||
// We have heated up more than the threshold, reset the timer
|
}
|
||||||
tipTempCRunawayTemp = currentTipTempInC;
|
|
||||||
runawaylastChangeTime = xTaskGetTickCount();
|
if (haveSeenDelta) {
|
||||||
} else {
|
return;
|
||||||
if ((xTaskGetTickCount() - runawaylastChangeTime) > (THERMAL_RUNAWAY_TIME_SEC * TICKS_SECOND)) {
|
}
|
||||||
// It has taken too long to rise
|
|
||||||
|
if (currentTipTempInC < tiptempMin) {
|
||||||
|
tiptempMin = currentTipTempInC;
|
||||||
|
}
|
||||||
|
if (thisCycleIsHeating && currentTipTempInC > tipTempMax) {
|
||||||
|
tipTempMax = currentTipTempInC;
|
||||||
|
}
|
||||||
|
if (thisCycleIsHeating) {
|
||||||
|
if (heatCycleStart == 0) {
|
||||||
|
heatCycleStart = xTaskGetTickCount();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
heatCycleStart = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((xTaskGetTickCount() - heatCycleStart) > (THERMAL_RUNAWAY_TIME_SEC * TICKS_SECOND)) {
|
||||||
|
if (tipTempMax > tiptempMin) {
|
||||||
|
// Have been heating for min seconds, check if the delta is large enough
|
||||||
|
TemperatureType_t delta = tipTempMax - tiptempMin;
|
||||||
|
haveSeenDelta = true;
|
||||||
|
|
||||||
|
if (delta < THERMAL_RUNAWAY_TEMP_C) {
|
||||||
heaterThermalRunaway = true;
|
heaterThermalRunaway = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
tipTempCRunawayTemp = currentTipTempInC;
|
|
||||||
runawaylastChangeTime = xTaskGetTickCount();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -138,9 +138,7 @@ OperatingMode gui_solderingMode(const ButtonState buttons, guiContext *cxt) {
|
|||||||
|
|
||||||
// Draw in the screen details
|
// Draw in the screen details
|
||||||
if (getSettingValue(SettingsOptions::DetailedSoldering)) {
|
if (getSettingValue(SettingsOptions::DetailedSoldering)) {
|
||||||
|
|
||||||
ui_draw_soldering_power_status(cxt->scratch_state.state2);
|
ui_draw_soldering_power_status(cxt->scratch_state.state2);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
ui_draw_soldering_basic_status(cxt->scratch_state.state2);
|
ui_draw_soldering_basic_status(cxt->scratch_state.state2);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user