Rough tip resistance progress

This commit is contained in:
Ben V. Brown
2022-05-23 21:42:56 +10:00
parent 226750df4c
commit 75b3f09438
8 changed files with 75 additions and 17 deletions

View File

@@ -16,6 +16,13 @@ extern "C" {
// Can be used to check any details for the power system
void power_check();
// Returns the tip resistance in x10 ohms, so 7.5 = 75; 14=140 etc
uint8_t getTipResitanceX10();
// Called when device is idle to allow measuring tip resistance
void startMeasureTipResistance();
void FinishMeasureTipResistance();
#ifdef __cplusplus
}
#endif

View File

@@ -223,3 +223,47 @@ bool isTipDisconnected() {
void setStatusLED(const enum StatusLED state) {
// Dont have one
}
uint8_t lastTipResistance = 75; // default safe
uint32_t lastTipReadinguV = 0;
uint8_t getTipResitanceX10() {
// Return tip resistance in x10 ohms
// We can measure this using the op-amp
return lastTipResistance;
}
void startMeasureTipResistance() {
if (isTipDisconnected()) {
return;
}
// We want to calculate lastTipResistance
// If tip is connected, and the tip is cold and the tip is not being heated
// We can use the GPIO to inject a small current into the tip and measure this
// The gpio is 5.1k -> diode -> tip -> gnd
// Which is around 0.65mA this will induce:
// 6 ohm tip -> 3.9mV (Real world ~= 3320)
// 8 ohm tip -> 5.2mV (Real world ~= 4500)
// Which is definitely measureable
// Taking shortcuts here as we know we only really have to pick apart 6 and 8 ohm tips
// These are reported as 60 and 75 respectively
lastTipReadinguV = TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0));
gpio_write(TIP_RESISTANCE_SENSE, 1);
// Wait for next ADC measurement
}
void FinishMeasureTipResistance() {
gpio_write(TIP_RESISTANCE_SENSE, 0);
if (isTipDisconnected()) {
return;
}
// read the tip uV with the current source on
uint32_t newReading = (TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0)));
if (newReading < lastTipReadinguV) {
return;
}
// newReading -= lastTipReadinguV;
MSG("Tip Delta %lu, %lu %lu \r\n", newReading - lastTipReadinguV, newReading, lastTipReadinguV);
newReading -= lastTipReadinguV;
lastTipReadinguV = newReading;
}

View File

@@ -23,6 +23,7 @@ history<uint16_t, ADC_Filter_Smooth> ADC_Vin;
history<uint16_t, ADC_Filter_Smooth> ADC_Temp;
history<uint16_t, ADC_Filter_Smooth> ADC_Tip;
void adc_fifo_irq(void) {
if (ADC_GetIntStatus(ADC_INT_FIFO_READY) == SET) {
bool wakePID = false;

View File

@@ -29,8 +29,9 @@ void hardware_init() {
gpio_set_mode(TMP36_INPUT_Pin, GPIO_INPUT_MODE);
gpio_set_mode(TIP_TEMP_Pin, GPIO_INPUT_MODE);
gpio_set_mode(VIN_Pin, GPIO_INPUT_MODE);
gpio_set_mode(TIP_RESISTANCE_SENSE, GPIO_INPUT_MODE);
gpio_set_mode(TIP_RESISTANCE_SENSE, GPIO_OUTPUT_PP_MODE);
gpio_write(TIP_RESISTANCE_SENSE, 0);
MSG("Magic Starting\r\n");
setup_timer_scheduler();
setup_adc();
setup_pwm();

View File

@@ -116,17 +116,17 @@
#ifdef MODEL_Magic
#define ADC_VDD_MV 3200 // ADC max reading millivolts
#define SOLDERING_TEMP 320 // Default soldering temp is 320.0 °C
#define VOLTAGE_DIV 600 // 290 - Default divider from schematic
#define CALIBRATION_OFFSET 900 // 900 - Default adc offset in uV
#define VOLTAGE_DIV 600 // 600 - Default divider from schematic
#define CALIBRATION_OFFSET 800 // 900 - Default adc offset in uV
#define MIN_CALIBRATION_OFFSET 100 // Min value for calibration
#define PID_POWER_LIMIT 70 // Sets the max pwm power limit
#define PID_POWER_LIMIT 220 // Sets the max pwm power limit
#define POWER_LIMIT 0 // 0 watts default limit
#define MAX_POWER_LIMIT 70 //
#define MAX_POWER_LIMIT 220 //
#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 20 // Maximum voltage for PD to negotiate
#define PID_TIM_HZ (8) // Tick rate of the PID loop
#define PID_TIM_HZ (10) // 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

View File

@@ -13,9 +13,6 @@
#ifndef USB_PD_VMAX
#error Max PD Voltage must be defined
#endif
#ifndef TIP_RESISTANCE
#error Tip resistance must be defined
#endif
void ms_delay(uint32_t delayms) {
// Convert ms -> ticks
@@ -98,10 +95,10 @@ bool pdbs_dpm_evaluate_capability(const pd_msg *capabilities, pd_msg *request) {
#ifdef MODEL_HAS_DCDC
// If this device has step down DC/DC inductor to smooth out current spikes
// We can instead ignore resistance and go for max voltage we can accept
min_resistance_ohmsx10 = TIP_RESISTANCE;
min_resistance_ohmsx10 = getTipResitanceX10();
#endif
// Fudge of 0.5 ohms to round up a little to account for other losses
if (min_resistance_ohmsx10 <= (TIP_RESISTANCE + 5)) {
if (min_resistance_ohmsx10 <= (getTipResitanceX10() + 5)) {
// This is a valid power source we can select as
if ((voltage_mv > bestIndexVoltage) || bestIndex == 0xFF) {
// Higher voltage and valid, select this instead
@@ -124,7 +121,7 @@ bool pdbs_dpm_evaluate_capability(const pd_msg *capabilities, pd_msg *request) {
// Using the current and tip resistance, calculate the ideal max voltage
// if this is range, then we will work with this voltage
// if this is not in range; then max_voltage can be safely selected
int ideal_voltage_mv = (TIP_RESISTANCE * max_current);
int ideal_voltage_mv = (getTipResitanceX10() * max_current);
if (ideal_voltage_mv > max_voltage) {
ideal_voltage_mv = max_voltage; // constrain
}
@@ -186,7 +183,7 @@ void pdbs_dpm_get_sink_capability(pd_msg *cap, const bool isPD3) {
// if (requested_voltage_mv != 5000) {
// voltage = requested_voltage_mv;
// }
// uint16_t current = (voltage) / TIP_RESISTANCE; // In centi-amps
// uint16_t current = (voltage) / getTipResitanceX10(); // In centi-amps
// /* Add a PDO for the desired power. */
// cap->obj[numobj++] = PD_PDO_TYPE_FIXED | PD_PDO_SNK_FIXED_VOLTAGE_SET(PD_MV2PDV(voltage)) | PD_PDO_SNK_FIXED_CURRENT_SET(current);

View File

@@ -49,7 +49,7 @@ uint32_t availableW10(uint8_t sample) {
// R = R*10
// P therefore is in V^2*100/R*10 = W*10.
uint32_t v = getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), sample); // 100 = 10v
uint32_t availableWattsX10 = (v * v) / TIP_RESISTANCE;
uint32_t availableWattsX10 = (v * v) / getTipResitanceX10();
// However, 100% duty cycle is not possible as there is a dead time while the ADC takes a reading
// Therefore need to scale available milliwats by this

View File

@@ -46,11 +46,14 @@ void startPIDTask(void const *argument __unused) {
getInputVoltageX10(getSettingValue(SettingsOptions::VoltageDiv), 1);
}
int32_t x10WattsOut = 0;
bool measuringTipResistance = false;
for (;;) {
x10WattsOut = 0;
// This is a call to block this thread until the ADC does its samples
if (ulTaskNotifyTake(pdTRUE, 2000)) {
if (measuringTipResistance) {
FinishMeasureTipResistance();
}
// Do the reading here to keep the temp calculations churning along
uint32_t currentTipTempInC = TipThermoModel::getTipInC(true);
PIDTempTarget = currentTempTargetDegC;
@@ -72,6 +75,11 @@ void startPIDTask(void const *argument __unused) {
detectThermalRunaway(currentTipTempInC, 0);
}
setOutputx10WattsViaFilters(x10WattsOut);
// If the output is off, take tip measurement reading
if (x10WattsOut == 0 && PIDTempTarget == 0) {
startMeasureTipResistance();
measuringTipResistance = true;
}
} else {
// ADC interrupt timeout
setTipPWM(0, false);