1
0
forked from me/IronOS

Slow PWM drive to reduce some handle heating, Improve PWM power for ts80, add ts80 pulse for keep awake

This commit is contained in:
Ben V. Brown
2018-11-11 20:43:35 +11:00
parent 5b882c819c
commit 6a1572de81
5 changed files with 95 additions and 38 deletions

View File

@@ -11,9 +11,10 @@
#ifndef POWER_HPP_ #ifndef POWER_HPP_
#define POWER_HPP_ #define POWER_HPP_
const uint8_t hz = 32; const uint8_t hz = 32;//PID loop rate
const uint8_t oscillationPeriod = 3.5 * hz; const uint8_t oscillationPeriod = 3.5 * hz; // dampening look back tuning
extern history<uint16_t, oscillationPeriod> milliWattHistory; extern history<uint16_t, oscillationPeriod> milliWattHistory;
void setupPower(uint8_t resistance);
int32_t tempToMilliWatts(int32_t rawTemp, uint16_t mass, uint8_t rawC); int32_t tempToMilliWatts(int32_t rawTemp, uint16_t mass, uint8_t rawC);
void setTipMilliWatts(int32_t mw); void setTipMilliWatts(int32_t mw);

View File

@@ -253,7 +253,7 @@ static void MX_TIM3_Init(void) {
TIM_OC_InitTypeDef sConfigOC; TIM_OC_InitTypeDef sConfigOC;
htim3.Instance = TIM3; htim3.Instance = TIM3;
htim3.Init.Prescaler = 2; htim3.Init.Prescaler = 4;
htim3.Init.CounterMode = TIM_COUNTERMODE_UP; htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
htim3.Init.Period = 100; // 10 Khz PWM freq htim3.Init.Period = 100; // 10 Khz PWM freq
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before div htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before div

View File

@@ -321,6 +321,9 @@ void startQC(uint16_t divisor) {
} }
// Get tip resistance in milliohms // Get tip resistance in milliohms
uint32_t calculateTipR() { uint32_t calculateTipR() {
static uint32_t lastRes=0;
if(lastRes)
return lastRes;
// We inject a small current into the front end of the iron, // We inject a small current into the front end of the iron,
// By measuring the Vdrop over the tip we can calculate the resistance // By measuring the Vdrop over the tip we can calculate the resistance
// Turn PA0 into an output and drive high to inject (3.3V-0.6)/(6K8+Rtip) // Turn PA0 into an output and drive high to inject (3.3V-0.6)/(6K8+Rtip)
@@ -335,20 +338,23 @@ uint32_t calculateTipR() {
setTipPWM(0); setTipPWM(0);
vTaskDelay(1); vTaskDelay(1);
uint32_t offReading = getTipRawTemp(1); uint32_t offReading = getTipRawTemp(1);
for (uint8_t i = 0; i < 24; i++) { for (uint8_t i = 0; i < 49; i++) {
vTaskDelay(1); // delay to allow it to stabilize vTaskDelay(1); // delay to allow it to stabilize
offReading += getTipRawTemp(1); offReading += getTipRawTemp(1);
} }
// Turn on // Turn on
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET);// Set low first HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_SET); // Set hgih
vTaskDelay(1); // delay to allow it too stabilize vTaskDelay(1); // delay to allow it too stabilize
uint32_t onReading = getTipInstantTemperature(); uint32_t onReading = getTipInstantTemperature();
for (uint8_t i = 0; i < 24; i++) { for (uint8_t i = 0; i < 49; i++) {
vTaskDelay(1); // delay to allow it to stabilize vTaskDelay(1); // delay to allow it to stabilize
onReading += getTipRawTemp(1); onReading += getTipRawTemp(1);
} }
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // Turn the output off finally
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
uint32_t difference = onReading - offReading; uint32_t difference = onReading - offReading;
// V = IR, therefore I = V/R // V = IR, therefore I = V/R
// We can divide this reading by a known "gain" to get the resulting // We can divide this reading by a known "gain" to get the resulting
@@ -356,7 +362,8 @@ uint32_t calculateTipR() {
// 4688 milliohms (Measured using 4 terminal measurement) 25x oversampling // 4688 milliohms (Measured using 4 terminal measurement) 25x oversampling
// reads this as around 47490 Almost perfectly 10x the milliohms value This // reads this as around 47490 Almost perfectly 10x the milliohms value This
// will drift massively with tip temp However we really only need 10x ohms // will drift massively with tip temp However we really only need 10x ohms
return (difference / 10) + 1;// ceil lastRes=(difference / 21) + 1; // ceil
return lastRes;
} }
static unsigned int sqrt32(unsigned long n) { static unsigned int sqrt32(unsigned long n) {
unsigned int c = 0x8000; unsigned int c = 0x8000;
@@ -379,15 +386,18 @@ int16_t calculateMaxVoltage(uint8_t useHP) {
// Check no tip // Check no tip
if (milliOhms > 10000) if (milliOhms > 10000)
return -1; return -1;
//Because of tolerance, if a user has asked for the higher power mode, then just goto 12V and call it a day
if (useHP)
return 120;
// //
// V = sqrt(18W*R) // V = sqrt(18W*R)
// Convert this to sqrt(18W)*sqrt(milli ohms)*sqrt(1/1000) // Convert this to sqrt(18W)*sqrt(milli ohms)*sqrt(1/1000)
uint32_t Vx = sqrt32(milliOhms); uint32_t Vx = sqrt32(milliOhms);
if (useHP) if (useHP)
Vx *= 1549;//sqrt(24)*sqrt(1/1000) Vx *= 1549; //sqrt(24)*sqrt(1/1000)*10000
else else
Vx *= 1342;// sqrt(18) * sqrt(1/1000) Vx *= 1342; // sqrt(18) * sqrt(1/1000)*10000
// Round to nearest 200mV, // Round to nearest 200mV,
// So divide by 100 to start, to get in Vxx // So divide by 100 to start, to get in Vxx
@@ -398,6 +408,12 @@ int16_t calculateMaxVoltage(uint8_t useHP) {
// Round to nearest increment of 2 // Round to nearest increment of 2
if (Vx % 2 == 1) if (Vx % 2 == 1)
Vx++; Vx++;
//Because of how bad the tolerance is on detecting the tip resistance is
//Its more functional to bin this
if (Vx < 90)
Vx = 90;
else if (Vx >= 105)
Vx = 12;
return Vx; return Vx;
} }

View File

@@ -657,9 +657,11 @@ static const char *HEADERS[] = {
__DATE__, "Heap: ", "HWMG: ", "HWMP: ", "HWMM: ", "Time: ", "Move: ", "RTip: ", __DATE__, "Heap: ", "HWMG: ", "HWMP: ", "HWMM: ", "Time: ", "Move: ", "RTip: ",
"CTip: ", "Vin :", "THan: ", "Model: ", "CTip: ", "Vin :", "THan: ", "Model: ",
#ifdef MODEL_TS80 #ifdef MODEL_TS80
"QCV: ", "QCV: ", "Tr ",
#else #else
"Tm ",
"Ralim-", "Ralim-",
#endif #endif
}; };
@@ -714,6 +716,13 @@ void showVersion(void) {
case 12: case 12:
#ifdef MODEL_TS80 #ifdef MODEL_TS80
OLED::printNumber(idealQCVoltage, 3); OLED::printNumber(idealQCVoltage, 3);
#else
OLED::printNumber(systemSettings.tipType, 3);
#endif
break;
case 13:
#ifdef MODEL_TS80
OLED::printNumber(calculateTipR(), 5);
#else #else
OLED::print("Tek.com"); OLED::print("Tek.com");
#endif #endif
@@ -728,7 +737,7 @@ void showVersion(void) {
return; return;
else if (b == BUTTON_F_SHORT) { else if (b == BUTTON_F_SHORT) {
screen++; screen++;
screen = screen % 13; screen = screen % 14;
} }
GUIDelay(); GUIDelay();
} }
@@ -924,7 +933,14 @@ void startPIDTask(void const *argument __unused) {
uint8_t rawC = ctoTipMeasurement(101) - ctoTipMeasurement(100); // 1*C change in raw. uint8_t rawC = ctoTipMeasurement(101) - ctoTipMeasurement(100); // 1*C change in raw.
currentlyActiveTemperatureTarget = 0; // Force start with no output (off). If in sleep / soldering this will currentlyActiveTemperatureTarget = 0; // Force start with no output (off). If in sleep / soldering this will
// be over-ridden rapidly // be over-ridden rapidly
#ifdef MODEL_TS80
//Set power management code to the tip resistance in ohms * 10
setupPower(calculateTipR() / 100);
size_t lastPowerPulse = 0;
#else
setupPower(85);
#endif
history<int16_t> tempError = { { 0 }, 0, 0 }; history<int16_t> tempError = { { 0 }, 0, 0 };
pidTaskNotification = xTaskGetCurrentTaskHandle(); pidTaskNotification = xTaskGetCurrentTaskHandle();
@@ -987,7 +1003,23 @@ void startPIDTask(void const *argument __unused) {
setTipMilliWatts(milliWattsOut); setTipMilliWatts(milliWattsOut);
} else { } else {
#ifdef MODEL_TS80
//If its a TS80, we want to have the option of using an occasional pulse to keep the power bank on
//~200ms @ a low wattage
//Doesnt keep all power banks awake but helps with some
if (xTaskGetTickCount() - lastPowerPulse < 20) {
// for the first 200mS turn on for a bit
setTipMilliWatts(4000); // typically its around 5W to hold the current temp, so this wont raise temp much
}else
setTipMilliWatts(0); setTipMilliWatts(0);
//Then wait until the next second
if (xTaskGetTickCount() - lastPowerPulse > 100) {
lastPowerPulse = xTaskGetTickCount();
}
#else
setTipMilliWatts(0);
#endif
} }
HAL_IWDG_Refresh(&hiwdg); HAL_IWDG_Refresh(&hiwdg);

View File

@@ -9,11 +9,14 @@
#include <Settings.h> #include <Settings.h>
#include <hardware.h> #include <hardware.h>
const uint8_t tipResistance = 87; uint8_t tipResistance = 85; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80
const uint8_t maxPWM = 255; const uint8_t maxPWM = 255;
history<uint16_t, oscillationPeriod> milliWattHistory = { { 0 }, 0, 0 }; history<uint16_t, oscillationPeriod> milliWattHistory = { { 0 }, 0, 0 };
void setupPower(uint8_t res) {
tipResistance = res;
}
int32_t tempToMilliWatts(int32_t rawTemp, uint16_t mass, uint8_t rawC) { int32_t tempToMilliWatts(int32_t rawTemp, uint16_t mass, uint8_t rawC) {
// mass is in milliJ/*C, rawC is raw per degree C // mass is in milliJ/*C, rawC is raw per degree C
@@ -26,13 +29,18 @@ int32_t tempToMilliWatts(int32_t rawTemp, uint16_t mass, uint8_t rawC) {
void setTipMilliWatts(int32_t mw) { void setTipMilliWatts(int32_t mw) {
int32_t output = milliWattsToPWM(mw, systemSettings.voltageDiv / 10); int32_t output = milliWattsToPWM(mw, systemSettings.voltageDiv / 10);
setTipPWM(output); setTipPWM(output);
uint16_t actualMilliWatts = PWMToMilliWatts(output, systemSettings.voltageDiv / 10); uint16_t actualMilliWatts = PWMToMilliWatts(output,
systemSettings.voltageDiv / 10);
milliWattHistory.update(actualMilliWatts); milliWattHistory.update(actualMilliWatts);
} }
uint8_t milliWattsToPWM(int32_t milliWatts, uint8_t divisor) { uint8_t milliWattsToPWM(int32_t milliWatts, uint8_t divisor) {
int32_t v = getInputVoltageX10(divisor); // 1000 = 10v //P = V^2 / R, v*v = v^2 * 100
// R = R*10
// P therefore is in V^2*10/R = W*10.
// Scale input milliWatts to the pwm rate
int32_t v = getInputVoltageX10(divisor);// 100 = 10v
int32_t availableMilliWatts = v * v / tipResistance; int32_t availableMilliWatts = v * v / tipResistance;
int32_t pwm = maxPWM * milliWatts / availableMilliWatts; int32_t pwm = maxPWM * milliWatts / availableMilliWatts;