Slow PWM drive to reduce some handle heating, Improve PWM power for ts80, add ts80 pulse for keep awake
This commit is contained in:
@@ -11,9 +11,10 @@
|
||||
#ifndef POWER_HPP_
|
||||
#define POWER_HPP_
|
||||
|
||||
const uint8_t hz = 32;
|
||||
const uint8_t oscillationPeriod = 3.5 * hz;
|
||||
const uint8_t hz = 32;//PID loop rate
|
||||
const uint8_t oscillationPeriod = 3.5 * hz; // dampening look back tuning
|
||||
extern history<uint16_t, oscillationPeriod> milliWattHistory;
|
||||
void setupPower(uint8_t resistance);
|
||||
|
||||
int32_t tempToMilliWatts(int32_t rawTemp, uint16_t mass, uint8_t rawC);
|
||||
void setTipMilliWatts(int32_t mw);
|
||||
|
||||
@@ -253,7 +253,7 @@ static void MX_TIM3_Init(void) {
|
||||
TIM_OC_InitTypeDef sConfigOC;
|
||||
|
||||
htim3.Instance = TIM3;
|
||||
htim3.Init.Prescaler = 2;
|
||||
htim3.Init.Prescaler = 4;
|
||||
htim3.Init.CounterMode = TIM_COUNTERMODE_UP;
|
||||
htim3.Init.Period = 100; // 10 Khz PWM freq
|
||||
htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV4; // 4mhz before div
|
||||
|
||||
@@ -156,16 +156,16 @@ uint16_t getInputVoltageX10(uint16_t divisor) {
|
||||
#ifdef MODEL_TS80
|
||||
uint8_t QCMode = 0;
|
||||
uint8_t QCTries = 0;
|
||||
void seekQC(int16_t Vx10,uint16_t divisor) {
|
||||
void seekQC(int16_t Vx10, uint16_t divisor) {
|
||||
if (QCMode == 5)
|
||||
startQC(divisor);
|
||||
startQC(divisor);
|
||||
if (QCMode == 0)
|
||||
return; // NOT connected to a QC Charger
|
||||
return; // NOT connected to a QC Charger
|
||||
|
||||
if (Vx10 < 45)
|
||||
return;
|
||||
if(Vx10>130)
|
||||
Vx10=130;//Cap max value at 13V
|
||||
return;
|
||||
if (Vx10 > 130)
|
||||
Vx10 = 130; //Cap max value at 13V
|
||||
// Seek the QC to the Voltage given if this adapter supports continuous mode
|
||||
// try and step towards the wanted value
|
||||
|
||||
@@ -178,11 +178,11 @@ void seekQC(int16_t Vx10,uint16_t divisor) {
|
||||
int steps = difference / 2;
|
||||
if (QCMode == 3) {
|
||||
while (steps < 0) {
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);//D+0.6
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);//D-3.3V
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);// D-3.3Vs
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET); //D+0.6
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET); //D-3.3V
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET); // D-3.3Vs
|
||||
vTaskDelay(3);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET);//-0.6V
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_RESET); //-0.6V
|
||||
HAL_Delay(1);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
@@ -237,7 +237,7 @@ void startQC(uint16_t divisor) {
|
||||
// negotiating as someone is feeding in hv
|
||||
uint16_t vin = getInputVoltageX10(divisor);
|
||||
if (vin > 150)
|
||||
return;// Over voltage
|
||||
return; // Over voltage
|
||||
if (vin > 100) {
|
||||
QCMode = 1; // ALready at ~12V
|
||||
return;
|
||||
@@ -279,7 +279,7 @@ void startQC(uint16_t divisor) {
|
||||
}
|
||||
// Check if D- is low to spot a QC charger
|
||||
if (HAL_GPIO_ReadPin(GPIOA, GPIO_PIN_11) == GPIO_PIN_RESET)
|
||||
enteredQC = 1;
|
||||
enteredQC = 1;
|
||||
if (enteredQC) {
|
||||
// We have a QC capable charger
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_SET);
|
||||
@@ -299,7 +299,7 @@ void startQC(uint16_t divisor) {
|
||||
for (uint8_t i = 0; i < 10; i++) {
|
||||
if (getInputVoltageX10(divisor) > 80) {
|
||||
// yay we have at least QC2.0 or QC3.0
|
||||
QCMode = 3;// We have at least QC2, pray for 3
|
||||
QCMode = 3; // We have at least QC2, pray for 3
|
||||
HAL_GPIO_WritePin(GPIOB, GPIO_PIN_3, GPIO_PIN_RESET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_8, GPIO_PIN_SET);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_10, GPIO_PIN_SET);
|
||||
@@ -310,17 +310,20 @@ void startQC(uint16_t divisor) {
|
||||
QCMode = 5;
|
||||
QCTries++;
|
||||
if (QCTries > 10) // 10 goes to get it going
|
||||
QCMode = 0;
|
||||
QCMode = 0;
|
||||
} else {
|
||||
// no QC
|
||||
QCMode = 0;
|
||||
|
||||
}
|
||||
if (QCTries > 10)
|
||||
QCMode = 0;
|
||||
QCMode = 0;
|
||||
}
|
||||
// Get tip resistance in milliohms
|
||||
uint32_t calculateTipR() {
|
||||
static uint32_t lastRes=0;
|
||||
if(lastRes)
|
||||
return lastRes;
|
||||
// We inject a small current into the front end of the iron,
|
||||
// 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)
|
||||
@@ -331,24 +334,27 @@ uint32_t calculateTipR() {
|
||||
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
|
||||
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
|
||||
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET);// Set low first
|
||||
HAL_GPIO_WritePin(GPIOA, GPIO_PIN_0, GPIO_PIN_RESET); // Set low first
|
||||
setTipPWM(0);
|
||||
vTaskDelay(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
|
||||
offReading += getTipRawTemp(1);
|
||||
}
|
||||
|
||||
// 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
|
||||
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
|
||||
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;
|
||||
// V = IR, therefore I = V/R
|
||||
// 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
|
||||
// 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
|
||||
return (difference / 10) + 1;// ceil
|
||||
lastRes=(difference / 21) + 1; // ceil
|
||||
return lastRes;
|
||||
}
|
||||
static unsigned int sqrt32(unsigned long n) {
|
||||
unsigned int c = 0x8000;
|
||||
@@ -364,10 +371,10 @@ static unsigned int sqrt32(unsigned long n) {
|
||||
|
||||
for (;;) {
|
||||
if (g * g > n)
|
||||
g ^= c;
|
||||
g ^= c;
|
||||
c >>= 1;
|
||||
if (c == 0)
|
||||
return g;
|
||||
return g;
|
||||
g |= c;
|
||||
}
|
||||
}
|
||||
@@ -378,26 +385,35 @@ int16_t calculateMaxVoltage(uint8_t useHP) {
|
||||
uint32_t milliOhms = calculateTipR();
|
||||
// Check no tip
|
||||
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)
|
||||
// Convert this to sqrt(18W)*sqrt(milli ohms)*sqrt(1/1000)
|
||||
|
||||
uint32_t Vx = sqrt32(milliOhms);
|
||||
if (useHP)
|
||||
Vx *= 1549;//sqrt(24)*sqrt(1/1000)
|
||||
Vx *= 1549; //sqrt(24)*sqrt(1/1000)*10000
|
||||
else
|
||||
Vx *= 1342;// sqrt(18) * sqrt(1/1000)
|
||||
Vx *= 1342; // sqrt(18) * sqrt(1/1000)*10000
|
||||
|
||||
// Round to nearest 200mV,
|
||||
// So divide by 100 to start, to get in Vxx
|
||||
Vx /= 100;
|
||||
if (Vx % 10 >= 5)
|
||||
Vx += 10;
|
||||
Vx += 10;
|
||||
Vx /= 10;
|
||||
// Round to nearest increment of 2
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -657,9 +657,11 @@ static const char *HEADERS[] = {
|
||||
__DATE__, "Heap: ", "HWMG: ", "HWMP: ", "HWMM: ", "Time: ", "Move: ", "RTip: ",
|
||||
"CTip: ", "Vin :", "THan: ", "Model: ",
|
||||
#ifdef MODEL_TS80
|
||||
"QCV: ",
|
||||
"QCV: ", "Tr ",
|
||||
#else
|
||||
"Tm ",
|
||||
"Ralim-",
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -714,6 +716,13 @@ void showVersion(void) {
|
||||
case 12:
|
||||
#ifdef MODEL_TS80
|
||||
OLED::printNumber(idealQCVoltage, 3);
|
||||
#else
|
||||
OLED::printNumber(systemSettings.tipType, 3);
|
||||
#endif
|
||||
break;
|
||||
case 13:
|
||||
#ifdef MODEL_TS80
|
||||
OLED::printNumber(calculateTipR(), 5);
|
||||
#else
|
||||
OLED::print("Tek.com");
|
||||
#endif
|
||||
@@ -728,7 +737,7 @@ void showVersion(void) {
|
||||
return;
|
||||
else if (b == BUTTON_F_SHORT) {
|
||||
screen++;
|
||||
screen = screen % 13;
|
||||
screen = screen % 14;
|
||||
}
|
||||
GUIDelay();
|
||||
}
|
||||
@@ -924,7 +933,14 @@ void startPIDTask(void const *argument __unused) {
|
||||
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
|
||||
// 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 };
|
||||
|
||||
pidTaskNotification = xTaskGetCurrentTaskHandle();
|
||||
@@ -987,7 +1003,23 @@ void startPIDTask(void const *argument __unused) {
|
||||
|
||||
setTipMilliWatts(milliWattsOut);
|
||||
} 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);
|
||||
//Then wait until the next second
|
||||
if (xTaskGetTickCount() - lastPowerPulse > 100) {
|
||||
lastPowerPulse = xTaskGetTickCount();
|
||||
}
|
||||
#else
|
||||
setTipMilliWatts(0);
|
||||
#endif
|
||||
}
|
||||
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
|
||||
@@ -9,11 +9,14 @@
|
||||
#include <Settings.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;
|
||||
|
||||
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) {
|
||||
// mass is in milliJ/*C, rawC is raw per degree C
|
||||
@@ -26,14 +29,19 @@ int32_t tempToMilliWatts(int32_t rawTemp, uint16_t mass, uint8_t rawC) {
|
||||
void setTipMilliWatts(int32_t mw) {
|
||||
int32_t output = milliWattsToPWM(mw, systemSettings.voltageDiv / 10);
|
||||
setTipPWM(output);
|
||||
uint16_t actualMilliWatts = PWMToMilliWatts(output, systemSettings.voltageDiv / 10);
|
||||
uint16_t actualMilliWatts = PWMToMilliWatts(output,
|
||||
systemSettings.voltageDiv / 10);
|
||||
|
||||
milliWattHistory.update(actualMilliWatts);
|
||||
}
|
||||
|
||||
uint8_t milliWattsToPWM(int32_t milliWatts, uint8_t divisor) {
|
||||
int32_t v = getInputVoltageX10(divisor); // 1000 = 10v
|
||||
int32_t availableMilliWatts = v*v / tipResistance;
|
||||
//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 pwm = maxPWM * milliWatts / availableMilliWatts;
|
||||
|
||||
if (pwm > maxPWM) {
|
||||
@@ -46,5 +54,5 @@ uint8_t milliWattsToPWM(int32_t milliWatts, uint8_t divisor) {
|
||||
|
||||
int32_t PWMToMilliWatts(uint8_t pwm, uint8_t divisor) {
|
||||
int32_t v = getInputVoltageX10(divisor);
|
||||
return pwm * (v*v / tipResistance) / maxPWM;
|
||||
return pwm * (v * v / tipResistance) / maxPWM;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user