Update PD to support awareness of having inductor for DCDC op

+ fix voltage divider to be more on point
+ Create adjustment for thermal mass causes overshoot
This commit is contained in:
Ben V. Brown
2021-05-03 22:36:25 +10:00
parent dd5daf51e3
commit ee12c99d9e
7 changed files with 54 additions and 25 deletions

View File

@@ -19,7 +19,7 @@ void HAL_ADC_ConvCpltCallback(ADC_HandleTypeDef *hadc) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
if (hadc == &hadc1) {
counter++;
if (counter % 64 == 0) {
if (counter % 32 == 0) { // 64 = 128ms, 32 = 64ms
if (pidTaskNotification) {
vTaskNotifyGiveFromISR(pidTaskNotification, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);

View File

@@ -58,8 +58,8 @@ typedef struct {
Note: Depending on devices, some channels may not be available on package pins. Refer to device datasheet for channels availability.
Note: On STM32F1 devices with several ADC: Only ADC1 can access internal measurement channels (VrefInt/TempSensor)
Note: On STM32F10xx8 and STM32F10xxB devices: A low-amplitude voltage glitch may be generated (on ADC input 0) on the PA0 pin, when the ADC is converting with
injection trigger. It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel. Refer to errata
sheet of these devices for more details. */
injection trigger. It is advised to distribute the analog channels so that Channel 0 is configured as an injected channel.
Refer to errata sheet of these devices for more details. */
uint32_t InjectedRank; /*!< Rank in the injected group sequencer
This parameter must be a value of @ref ADCEx_injected_rank
Note: In case of need to disable a channel or change order of conversion sequencer, rank containing a previous channel setting can be overwritten by the new channel

View File

@@ -6,6 +6,7 @@
*/
#include "BSP_PD.h"
#include "configuration.h"
#include "main.hpp"
#include "pd.h"
#include "policy_engine.h"
@@ -60,6 +61,7 @@ bool PolicyEngine::pdbs_dpm_evaluate_capability(const union pd_msg *capabilities
int bestIndexVoltage = 0;
int bestIndexCurrent = 0;
bool bestIsPPS = false;
powerSupplyWattageLimit = 0;
for (uint8_t i = 0; i < numobj; i++) {
/* If we have a fixed PDO, its V equals our desired V, and its I is
* at least our desired I */
@@ -72,7 +74,15 @@ bool PolicyEngine::pdbs_dpm_evaluate_capability(const union pd_msg *capabilities
int current_a_x100 = PD_PDO_SRC_FIXED_CURRENT_GET(capabilities->obj[i]); // current in 10mA units
int min_resistance_ohmsx10 = voltage_mv / current_a_x100;
if (voltage_mv <= (USB_PD_VMAX * 1000)) {
if (min_resistance_ohmsx10 <= tipResistance) {
#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
if (voltage_mv <= (USB_PD_VMAX * 1000)) {
min_resistance_ohmsx10 = tipResistance;
}
#endif
// Fudge of 0.5 ohms to round up a little to account for other losses
if (min_resistance_ohmsx10 <= (tipResistance + 5)) {
// This is a valid power source we can select as
if (voltage_mv > bestIndexVoltage || bestIndex == 0xFF) {
// Higher voltage and valid, select this instead
@@ -80,6 +90,10 @@ bool PolicyEngine::pdbs_dpm_evaluate_capability(const union pd_msg *capabilities
bestIndexVoltage = voltage_mv;
bestIndexCurrent = current_a_x100;
bestIsPPS = false;
#ifdef MODEL_HAS_DCDC
// set limiter for wattage
powerSupplyWattageLimit = (voltage_mv * current_a_x100) / 100 / 1000;
#endif
}
}
}
@@ -103,6 +117,10 @@ bool PolicyEngine::pdbs_dpm_evaluate_capability(const union pd_msg *capabilities
bestIndexVoltage = ideal_voltage_mv;
bestIndexCurrent = max_current;
bestIsPPS = true;
#ifdef MODEL_HAS_DCDC
// set limiter for wattage
powerSupplyWattageLimit = (ideal_voltage_mv * max_current) / 100 / 1000;
#endif
}
}
}

View File

@@ -72,10 +72,12 @@ uint32_t TipThermoModel::convertFtoC(uint32_t degF) {
uint32_t TipThermoModel::getTipInC(bool sampleNow) {
int32_t currentTipTempInC = TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(sampleNow));
currentTipTempInC += getHandleTemperature() / 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...
#ifndef NO_THERMAL_MASS_COMP
// 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)

View File

@@ -15,7 +15,7 @@
* Default soldering temp is 320.0 C
* Temperature the iron sleeps at - default 150.0 C
*/
#define SOLDERING_TEMP 320 // Default soldering temp is 320.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
@@ -120,6 +120,7 @@
// vdiv = (32768*4)/(vin_max*10)
#ifdef MODEL_TS100
#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
@@ -133,6 +134,7 @@
#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
@@ -146,6 +148,7 @@
#endif
#ifdef MODEL_TS80
#define SOLDERING_TEMP 320 // Default soldering temp is 320.0 °C
#define VOLTAGE_DIV 780 // Default divider from schematic
#define PID_POWER_LIMIT 24 // Sets the max pwm power limit
#define CALIBRATION_OFFSET 900 // the adc offset in uV
@@ -159,6 +162,7 @@
#endif
#ifdef MODEL_TS80P
#define SOLDERING_TEMP 320 // Default soldering temp is 320.0 °C
#define VOLTAGE_DIV 650 // Default for TS80P with slightly different resistors
#define PID_POWER_LIMIT 35 // Sets the max pwm power limit
#define CALIBRATION_OFFSET 1500 // the adc offset in uV
@@ -172,16 +176,18 @@
#endif
#ifdef MODEL_MHP30
#define VOLTAGE_DIV 355 // 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 2 //
#define OP_AMP_GAIN_STAGE OP_AMP_GAIN_STAGE_MHP30 //
#define USB_PD_VMAX 20 // Maximum voltage for PD to negotiate
#define PID_TIM_HZ (32) // We run a faster update rate (ballpark no for now)
#define NO_THERMAL_MASS_COMP // The temp sensor is mounted seperate to the heater so we dont need this
#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 2 //
#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
#endif
#ifdef MODEL_TS100
@@ -206,5 +212,5 @@ const uint8_t tipResistance = 45; // x10 ohms, 4.5 typical for ts80 tips
#ifdef MODEL_MHP30
const uint32_t tipMass = 45; // TODO
const uint8_t tipResistance = 75; // x10 ohms, ~6 typical
const uint8_t tipResistance = 60; // x10 ohms, ~6 typical
#endif

View File

@@ -21,6 +21,7 @@ void startPIDTask(void const *argument);
void startMOVTask(void const *argument);
void startPOWTask(void const *argument);
extern TaskHandle_t pidTaskNotification;
extern int32_t powerSupplyWattageLimit;
extern uint8_t accelInit;
extern TickType_t lastMovementTime;
#ifdef __cplusplus

View File

@@ -14,11 +14,11 @@
#include "main.hpp"
#include "power.hpp"
#include "task.h"
static TickType_t powerPulseWaitUnit = 25 * TICKS_100MS; // 2.5 s
static TickType_t powerPulseDurationUnit = (5 * TICKS_100MS) / 2; // 250 ms
TaskHandle_t pidTaskNotification = NULL;
uint32_t currentTempTargetDegC = 0; // Current temperature target in C
static TickType_t powerPulseWaitUnit = 25 * TICKS_100MS; // 2.5 s
static TickType_t powerPulseDurationUnit = (5 * TICKS_100MS) / 2; // 250 ms
TaskHandle_t pidTaskNotification = NULL;
uint32_t currentTempTargetDegC = 0; // Current temperature target in C
int32_t powerSupplyWattageLimit = 0;
/* StartPIDTask function */
void startPIDTask(void const *argument __unused) {
/*
@@ -110,6 +110,8 @@ void startPIDTask(void const *argument __unused) {
}
if (systemSettings.powerLimit && x10WattsOut > (systemSettings.powerLimit * 10)) {
setTipX10Watts(systemSettings.powerLimit * 10);
} else if (powerSupplyWattageLimit && x10WattsOut > powerSupplyWattageLimit * 10) {
setTipX10Watts(powerSupplyWattageLimit * 10);
} else {
setTipX10Watts(x10WattsOut);
}