Startup behaviour fixes (#1306)
* Reduce PPS max to 20V to avoid instability Some PSU's cant actually run at 21V * Creating a rough draft of a "pre start check" concept * Newer alpine * Cleaning up MHP detection * Cleanup comments * PID: Run prestart based on ADC IRQ rather than times * MHP30: Far better startup for detecting tip gain * Newer alpine for github CI
This commit is contained in:
@@ -86,6 +86,10 @@ enum StatusLED {
|
||||
};
|
||||
void setStatusLED(const enum StatusLED state);
|
||||
|
||||
// preStartChecks are run until they return 0
|
||||
// By the PID, after each ADC sample comes in
|
||||
// For example, on the MHP30 this is used to figure out the resistance of the hotplate
|
||||
uint8_t preStartChecks();
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -13,13 +13,15 @@
|
||||
#include <IRQ.h>
|
||||
|
||||
WS2812<GPIOA_BASE, WS2812_Pin, 1> ws2812;
|
||||
volatile uint16_t PWMSafetyTimer = 0;
|
||||
volatile uint8_t pendingPWM = 0;
|
||||
uint16_t totalPWM = 255;
|
||||
const uint16_t powerPWM = 255;
|
||||
volatile uint16_t PWMSafetyTimer = 0;
|
||||
volatile uint8_t pendingPWM = 0;
|
||||
uint16_t totalPWM = 255;
|
||||
const uint16_t powerPWM = 255;
|
||||
uint16_t tipSenseResistancex10Ohms = 0;
|
||||
volatile bool tipMeasurementOccuring = false;
|
||||
history<uint16_t, PID_TIM_HZ> rawTempFilter = {{0}, 0, 0};
|
||||
|
||||
history<uint16_t, PID_TIM_HZ> rawTempFilter = {{0}, 0, 0};
|
||||
void resetWatchdog() { HAL_IWDG_Refresh(&hiwdg); }
|
||||
void resetWatchdog() { HAL_IWDG_Refresh(&hiwdg); }
|
||||
|
||||
#ifdef TEMP_NTC
|
||||
// Lookup table for the NTC
|
||||
@@ -208,7 +210,8 @@ uint16_t getHandleTemperature(uint8_t sample) {
|
||||
uint16_t getTipInstantTemperature() { return getADC(2); }
|
||||
|
||||
uint16_t getTipRawTemp(uint8_t refresh) {
|
||||
if (refresh) {
|
||||
if (refresh && (tipMeasurementOccuring == false)) {
|
||||
|
||||
uint16_t lastSample = getTipInstantTemperature();
|
||||
rawTempFilter.update(lastSample);
|
||||
return lastSample;
|
||||
@@ -348,69 +351,82 @@ void setPlatePullup(bool pullingUp) {
|
||||
HAL_GPIO_Init(PLATE_SENSOR_PULLUP_GPIO_Port, &GPIO_InitStruct);
|
||||
}
|
||||
|
||||
uint16_t tipSenseResistancex10Ohms = 0;
|
||||
bool isTipDisconnected() {
|
||||
static bool lastTipDisconnectedState = true;
|
||||
static uint16_t adcReadingPD1Set = 0;
|
||||
static TickType_t lastMeas = 0;
|
||||
void performTipMeasurementStep(bool start) {
|
||||
static uint16_t adcReadingPD1Set = 0;
|
||||
static TickType_t lastMeas = 0;
|
||||
// Inter state that performs the steps to measure the resistor on the tip
|
||||
// Return 1 if a measurement is ongoing
|
||||
|
||||
// We want to perform our startup measurements of the tip resistance until we detect one fitted
|
||||
|
||||
// Step 1; if not setup, we turn on pullup and then wait
|
||||
if (tipMeasurementOccuring == false && (start || tipSenseResistancex10Ohms == 0 || lastMeas == 0)) {
|
||||
tipMeasurementOccuring = true;
|
||||
tipSenseResistancex10Ohms = 0;
|
||||
lastMeas = xTaskGetTickCount();
|
||||
adcReadingPD1Set = 0;
|
||||
setPlatePullup(true);
|
||||
return;
|
||||
}
|
||||
|
||||
// Wait 100ms for settle time
|
||||
if ((xTaskGetTickCount() - lastMeas) < (TICKS_100MS)) {
|
||||
return;
|
||||
}
|
||||
|
||||
lastMeas = xTaskGetTickCount();
|
||||
// We are sensing the resistance
|
||||
if (adcReadingPD1Set == 0) {
|
||||
// We will record the reading for PD1 being set
|
||||
adcReadingPD1Set = getADC(3);
|
||||
setPlatePullup(false);
|
||||
return;
|
||||
}
|
||||
// Taking reading two
|
||||
uint16_t adcReadingPD1Cleared = getADC(3);
|
||||
uint32_t a = ((int)adcReadingPD1Set - (int)adcReadingPD1Cleared);
|
||||
a *= 10000;
|
||||
uint32_t b = ((int)adcReadingPD1Cleared + (32768 - (int)adcReadingPD1Set));
|
||||
if (b) {
|
||||
tipSenseResistancex10Ohms = a / b;
|
||||
} else {
|
||||
tipSenseResistancex10Ohms = adcReadingPD1Set = lastMeas = 0;
|
||||
}
|
||||
if (tipSenseResistancex10Ohms > 1100 || tipSenseResistancex10Ohms < 900) {
|
||||
tipSenseResistancex10Ohms = 0; // out of range
|
||||
adcReadingPD1Set = 0;
|
||||
lastMeas = 0;
|
||||
return;
|
||||
}
|
||||
tipMeasurementOccuring = false;
|
||||
}
|
||||
bool isTipDisconnected() {
|
||||
static bool lastDisconnectedState = false;
|
||||
// For the MHP30 we want to include a little extra logic in here
|
||||
// As when the tip is first connected we want to measure the ~100 ohm resistor on the base of the tip
|
||||
// And likewise if its removed we want to clear that measurement
|
||||
/*
|
||||
* plate_sensor_res = ((adc5_value_PD1_set - adc5_value_PD1_cleared) / (adc5_value_PD1_cleared + 4096 - adc5_value_PD1_set)) * 1000.0;
|
||||
* */
|
||||
|
||||
bool tipDisconnected = getADC(2) > (4090 * 8);
|
||||
// We have to handle here that this ^ will trip while measuring the gain resistor
|
||||
if (xTaskGetTickCount() - lastMeas < (TICKS_100MS * 2 + (TICKS_100MS / 2))) {
|
||||
tipDisconnected = false;
|
||||
if (tipMeasurementOccuring) {
|
||||
performTipMeasurementStep(false);
|
||||
return true; // We fake no tip disconnection during the measurement cycle to mask it
|
||||
}
|
||||
|
||||
if (tipDisconnected != lastTipDisconnectedState) {
|
||||
if (tipDisconnected) {
|
||||
// Tip is now disconnected
|
||||
tipSenseResistancex10Ohms = 0; // zero out the resistance
|
||||
adcReadingPD1Set = 0;
|
||||
lastMeas = 0;
|
||||
}
|
||||
lastTipDisconnectedState = tipDisconnected;
|
||||
// If we are too close to the top, most likely disconnected tip
|
||||
bool tipDisconnected = getTipInstantTemperature() > (4090 * 8);
|
||||
if (tipDisconnected == false && lastDisconnectedState == true) {
|
||||
// Tip is now disconnected
|
||||
performTipMeasurementStep(true);
|
||||
}
|
||||
if (!tipDisconnected) {
|
||||
if (tipSenseResistancex10Ohms == 0) {
|
||||
if (lastMeas == 0) {
|
||||
lastMeas = xTaskGetTickCount();
|
||||
setPlatePullup(true);
|
||||
} else if (xTaskGetTickCount() - lastMeas > (TICKS_100MS)) {
|
||||
lastMeas = xTaskGetTickCount();
|
||||
// We are sensing the resistance
|
||||
if (adcReadingPD1Set == 0) {
|
||||
// We will record the reading for PD1 being set
|
||||
adcReadingPD1Set = getADC(3);
|
||||
setPlatePullup(false);
|
||||
} else {
|
||||
// We have taken reading one
|
||||
uint16_t adcReadingPD1Cleared = getADC(3);
|
||||
uint32_t a = ((int)adcReadingPD1Set - (int)adcReadingPD1Cleared);
|
||||
a *= 10000;
|
||||
uint32_t b = ((int)adcReadingPD1Cleared + (32768 - (int)adcReadingPD1Set));
|
||||
if (b) {
|
||||
tipSenseResistancex10Ohms = a / b;
|
||||
} else {
|
||||
tipSenseResistancex10Ohms = adcReadingPD1Set = lastMeas = 0;
|
||||
}
|
||||
if (tipSenseResistancex10Ohms > 1100 || tipSenseResistancex10Ohms < 900) {
|
||||
tipSenseResistancex10Ohms = 0; // out of range
|
||||
adcReadingPD1Set = 0;
|
||||
lastMeas = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return true; // we fake tip being disconnected until this is measured
|
||||
}
|
||||
}
|
||||
|
||||
lastDisconnectedState = tipDisconnected;
|
||||
return tipDisconnected;
|
||||
}
|
||||
|
||||
uint8_t preStartChecks() {
|
||||
performTipMeasurementStep(false);
|
||||
return tipMeasurementOccuring ? 1 : 0;
|
||||
}
|
||||
void setBuzzer(bool on) {
|
||||
if (on) {
|
||||
htim3.Instance->CCR2 = 128;
|
||||
|
||||
@@ -10,7 +10,8 @@
|
||||
#include "configuration.h"
|
||||
extern uint16_t tipSenseResistancex10Ohms;
|
||||
uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) {
|
||||
// For the MHP30, we are mimicing the original code and using the resistor fitted to the base of the heater head, this is measured in the isTipDisconnected() function
|
||||
// For the MHP30, we are mimicing the original code and using the resistor fitted to the base of the heater head,
|
||||
// this is measured at boot in pid task and in the disconnected tip check if tip is removed
|
||||
if (tipSenseResistancex10Ohms > 900 && tipSenseResistancex10Ohms <= 1100) {
|
||||
int32_t a = ((tipSenseResistancex10Ohms / 10) + 300) * (3300000 - tipuVDelta);
|
||||
int32_t b = a / 1000000;
|
||||
|
||||
@@ -282,4 +282,5 @@ bool isTipDisconnected() {
|
||||
return tipTemp > tipDisconnectedThres;
|
||||
}
|
||||
|
||||
void setStatusLED(const enum StatusLED state) {}
|
||||
void setStatusLED(const enum StatusLED state) {}
|
||||
uint8_t preStartChecks() { return 0; }
|
||||
@@ -90,3 +90,5 @@ bool isTipDisconnected() {
|
||||
}
|
||||
|
||||
void setStatusLED(const enum StatusLED state) {}
|
||||
|
||||
uint8_t preStartChecks() { return 0; }
|
||||
@@ -124,7 +124,7 @@
|
||||
#define POWER_LIMIT_STEPS 5 //
|
||||
#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_PINECIL // Uses TS100 resistors
|
||||
#define TEMP_uV_LOOKUP_HAKKO // Use Hakko lookup table
|
||||
#define USB_PD_VMAX 21 // Maximum voltage for PD to negotiate
|
||||
#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
|
||||
|
||||
@@ -172,7 +172,7 @@ static void gui_drawBatteryIcon() {
|
||||
}
|
||||
static void gui_solderingTempAdjust() {
|
||||
uint32_t lastChange = xTaskGetTickCount();
|
||||
currentTempTargetDegC = 0;
|
||||
currentTempTargetDegC = 0; // Turn off header while adjusting temp
|
||||
uint32_t autoRepeatTimer = 0;
|
||||
uint8_t autoRepeatAcceleration = 0;
|
||||
bool waitForRelease = false;
|
||||
@@ -511,12 +511,8 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
boostModeOn = false;
|
||||
break;
|
||||
case BUTTON_BOTH:
|
||||
// exit
|
||||
return;
|
||||
break;
|
||||
case BUTTON_B_LONG:
|
||||
return; // exit on back long hold
|
||||
break;
|
||||
case BUTTON_F_LONG:
|
||||
// if boost mode is enabled turn it on
|
||||
if (getSettingValue(SettingsOptions::BoostTemp))
|
||||
@@ -665,8 +661,6 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
// If we have tripped thermal runaway, turn off heater and show warning
|
||||
if (heaterThermalRunaway) {
|
||||
currentTempTargetDegC = 0; // heater control off
|
||||
// TODO WARNING
|
||||
|
||||
warnUser(translatedString(Tr->WarningThermalRunaway), 10 * TICKS_SECOND);
|
||||
heaterThermalRunaway = false;
|
||||
return;
|
||||
|
||||
@@ -39,21 +39,26 @@ void startPIDTask(void const *argument __unused) {
|
||||
pidTaskNotification = xTaskGetCurrentTaskHandle();
|
||||
uint32_t PIDTempTarget = 0;
|
||||
// Pre-seed the adc filters
|
||||
for (int i = 0; i < 128; i++) {
|
||||
osDelay(5);
|
||||
for (int i = 0; i < 32; i++) {
|
||||
ulTaskNotifyTake(pdTRUE, 5);
|
||||
TipThermoModel::getTipInC(true);
|
||||
getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 1);
|
||||
}
|
||||
|
||||
while (preStartChecks() != 0) {
|
||||
ulTaskNotifyTake(pdTRUE, 2000);
|
||||
}
|
||||
|
||||
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)) {
|
||||
if (ulTaskNotifyTake(pdTRUE, TICKS_SECOND * 2)) {
|
||||
// Do the reading here to keep the temp calculations churning along
|
||||
uint32_t currentTipTempInC = TipThermoModel::getTipInC(true);
|
||||
PIDTempTarget = currentTempTargetDegC;
|
||||
if (PIDTempTarget) {
|
||||
if (PIDTempTarget > 0) {
|
||||
// Cap the max set point to 450C
|
||||
if (PIDTempTarget > (450)) {
|
||||
// Maximum allowed output
|
||||
|
||||
Reference in New Issue
Block a user