Rough refactor main control loop to C
This commit is contained in:
@@ -11,7 +11,7 @@
|
||||
#define SETTINGS_H_
|
||||
#include <stdint.h>
|
||||
#include "stm32f1xx_hal.h"
|
||||
#define SETTINGSVERSION ( 0x19 )
|
||||
#define SETTINGSVERSION ( 0x1A )
|
||||
/*Change this if you change the struct below to prevent people getting \
|
||||
out of sync*/
|
||||
|
||||
@@ -39,7 +39,7 @@ typedef struct {
|
||||
uint8_t descriptionScrollSpeed :1; // Description scroll speed
|
||||
uint16_t voltageDiv; // Voltage divisor factor
|
||||
uint16_t BoostTemp; // Boost mode set point for the iron
|
||||
int16_t CalibrationOffset; // This stores the temperature offset for this tip
|
||||
uint16_t CalibrationOffset; // This stores the temperature offset for this tip
|
||||
// in the iron.
|
||||
uint8_t PID_P; // PID P Term
|
||||
uint8_t PID_I; // PID I Term
|
||||
@@ -47,7 +47,6 @@ typedef struct {
|
||||
uint8_t version; // Used to track if a reset is needed on firmware upgrade
|
||||
uint8_t customTipGain; // Tip gain value if custom tuned, or 0 if using a
|
||||
// tipType param
|
||||
uint8_t tipType;
|
||||
#ifdef MODEL_TS80
|
||||
uint8_t pidPowerLimit;
|
||||
#endif
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
#include "OLED.hpp"
|
||||
#include "Setup.h"
|
||||
extern uint8_t PCBVersion;
|
||||
extern uint32_t currentlyActiveTemperatureTarget;
|
||||
extern uint32_t currentTempTargetDegC;
|
||||
enum ButtonState {
|
||||
BUTTON_NONE = 0, /* No buttons pressed / < filter time*/
|
||||
BUTTON_F_SHORT = 1, /* User has pressed the front button*/
|
||||
|
||||
@@ -30,7 +30,7 @@ const uint8_t tipResistance = 45; //x10 ohms, 8.5 typical for ts100, 4.5 typical
|
||||
const uint8_t oscillationPeriod = 6 * PID_TIM_HZ; // I term look back value
|
||||
extern history<uint32_t, oscillationPeriod> milliWattHistory;
|
||||
|
||||
int32_t tempToMilliWatts(int32_t rawTemp, uint8_t rawC);
|
||||
int32_t tempToMilliWatts(int32_t rawTemp);
|
||||
void setTipMilliWatts(int32_t mw);
|
||||
uint8_t milliWattsToPWM(int32_t milliWatts, uint8_t divisor,
|
||||
uint8_t sample = 0);
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
#include "TipThermoModel.h"
|
||||
extern uint8_t PCBVersion;
|
||||
// File local variables
|
||||
extern uint32_t currentlyActiveTemperatureTarget;
|
||||
extern uint32_t currentTempTargetDegC;
|
||||
extern uint32_t lastMovementTime;
|
||||
extern int16_t idealQCVoltage;
|
||||
uint32_t lastButtonTime = 0;
|
||||
@@ -57,9 +57,9 @@ void gui_drawTipTemp(bool symbol) {
|
||||
uint16_t Temp = getTipRawTemp(0);
|
||||
|
||||
if (systemSettings.temperatureInF)
|
||||
Temp = tipMeasurementToF(Temp);
|
||||
Temp = TipThermoModel::convertTipRawADCToDegF(Temp);
|
||||
else
|
||||
Temp = tipMeasurementToC(Temp);
|
||||
Temp = TipThermoModel::convertTipRawADCToDegC(Temp);
|
||||
|
||||
OLED::printNumber(Temp, 3); // Draw the tip temp out finally
|
||||
if (symbol) {
|
||||
@@ -201,7 +201,7 @@ static bool checkVoltageForExit() {
|
||||
}
|
||||
|
||||
OLED::refresh();
|
||||
currentlyActiveTemperatureTarget = 0;
|
||||
currentTempTargetDegC = 0;
|
||||
waitForButtonPress();
|
||||
return true;
|
||||
}
|
||||
@@ -216,17 +216,17 @@ static void gui_drawBatteryIcon() {
|
||||
// we need to calculate which of the 10 levels they are on
|
||||
uint8_t cellCount = systemSettings.cutoutSetting + 2;
|
||||
uint32_t cellV = getInputVoltageX10(systemSettings.voltageDiv, 0)
|
||||
/ cellCount;
|
||||
/ cellCount;
|
||||
// Should give us approx cell voltage X10
|
||||
// Range is 42 -> 33 = 9 steps therefore we will use battery 1-10
|
||||
if (cellV < 33)
|
||||
cellV = 33;
|
||||
cellV -= 33;// Should leave us a number of 0-9
|
||||
cellV = 33;
|
||||
cellV -= 33; // Should leave us a number of 0-9
|
||||
if (cellV > 9)
|
||||
cellV = 9;
|
||||
cellV = 9;
|
||||
OLED::drawBattery(cellV + 1);
|
||||
} else
|
||||
OLED::drawSymbol(15); // Draw the DC Logo
|
||||
OLED::drawSymbol(15); // Draw the DC Logo
|
||||
#else
|
||||
// On TS80 we replace this symbol with the voltage we are operating on
|
||||
// If <9V then show single digit, if not show duals
|
||||
@@ -250,7 +250,7 @@ static void gui_drawBatteryIcon() {
|
||||
}
|
||||
static void gui_solderingTempAdjust() {
|
||||
uint32_t lastChange = xTaskGetTickCount();
|
||||
currentlyActiveTemperatureTarget = 0;
|
||||
currentTempTargetDegC = 0;
|
||||
uint32_t autoRepeatTimer = 0;
|
||||
uint8_t autoRepeatAcceleration = 0;
|
||||
for (;;) {
|
||||
@@ -317,7 +317,7 @@ static void gui_solderingTempAdjust() {
|
||||
#ifdef MODEL_TS80
|
||||
if (!OLED::getRotation())
|
||||
#else
|
||||
if (OLED::getRotation())
|
||||
if (OLED::getRotation())
|
||||
#endif
|
||||
OLED::print(SymbolMinus);
|
||||
else
|
||||
@@ -333,7 +333,7 @@ static void gui_solderingTempAdjust() {
|
||||
#ifdef MODEL_TS80
|
||||
if (!OLED::getRotation())
|
||||
#else
|
||||
if (OLED::getRotation())
|
||||
if (OLED::getRotation())
|
||||
#endif
|
||||
OLED::print(SymbolPlus);
|
||||
else
|
||||
@@ -354,24 +354,23 @@ static int gui_SolderingSleepingMode() {
|
||||
|| (xTaskGetTickCount() - lastButtonTime < 100))
|
||||
return 0; // user moved or pressed a button, go back to soldering
|
||||
#ifdef MODEL_TS100
|
||||
if (checkVoltageForExit())
|
||||
if (checkVoltageForExit())
|
||||
return 1; // return non-zero on error
|
||||
#endif
|
||||
if (systemSettings.temperatureInF) {
|
||||
currentlyActiveTemperatureTarget = ftoTipMeasurement(
|
||||
currentTempTargetDegC = TipThermoModel::convertFtoC(
|
||||
min(systemSettings.SleepTemp,
|
||||
systemSettings.SolderingTemp));
|
||||
} else {
|
||||
currentlyActiveTemperatureTarget = ctoTipMeasurement(
|
||||
min(systemSettings.SleepTemp,
|
||||
systemSettings.SolderingTemp));
|
||||
currentTempTargetDegC = (min(systemSettings.SleepTemp,
|
||||
systemSettings.SolderingTemp));
|
||||
}
|
||||
// draw the lcd
|
||||
uint16_t tipTemp;
|
||||
if (systemSettings.temperatureInF)
|
||||
tipTemp = tipMeasurementToF(getTipRawTemp(0));
|
||||
tipTemp = TipThermoModel::convertTipRawADCToDegF(getTipRawTemp(0));
|
||||
else
|
||||
tipTemp = tipMeasurementToC(getTipRawTemp(0));
|
||||
tipTemp = TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(0));
|
||||
|
||||
OLED::clearScreen();
|
||||
OLED::setCursor(0, 0);
|
||||
@@ -403,7 +402,7 @@ static int gui_SolderingSleepingMode() {
|
||||
if (((uint32_t) (xTaskGetTickCount() - lastMovementTime))
|
||||
> (uint32_t) (systemSettings.ShutdownTime * 60 * 100)) {
|
||||
// shutdown
|
||||
currentlyActiveTemperatureTarget = 0;
|
||||
currentTempTargetDegC = 0;
|
||||
return 1; // we want to exit soldering mode
|
||||
}
|
||||
OLED::refresh();
|
||||
@@ -561,9 +560,9 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
if (badTipCounter > 128) {
|
||||
OLED::print(BadTipString);
|
||||
OLED::refresh();
|
||||
currentlyActiveTemperatureTarget = 0;
|
||||
currentTempTargetDegC = 0;
|
||||
waitForButtonPress();
|
||||
currentlyActiveTemperatureTarget = 0;
|
||||
currentTempTargetDegC = 0;
|
||||
return;
|
||||
}
|
||||
OLED::refresh();
|
||||
@@ -571,19 +570,17 @@ static void gui_solderingMode(uint8_t jumpToSleep) {
|
||||
// Update the setpoints for the temperature
|
||||
if (boostModeOn) {
|
||||
if (systemSettings.temperatureInF)
|
||||
currentlyActiveTemperatureTarget = ftoTipMeasurement(
|
||||
currentTempTargetDegC = TipThermoModel::convertFtoC(
|
||||
systemSettings.BoostTemp);
|
||||
else
|
||||
currentlyActiveTemperatureTarget = ctoTipMeasurement(
|
||||
systemSettings.BoostTemp);
|
||||
currentTempTargetDegC = (systemSettings.BoostTemp);
|
||||
|
||||
} else {
|
||||
if (systemSettings.temperatureInF)
|
||||
currentlyActiveTemperatureTarget = ftoTipMeasurement(
|
||||
currentTempTargetDegC = TipThermoModel::convertFtoC(
|
||||
systemSettings.SolderingTemp);
|
||||
else
|
||||
currentlyActiveTemperatureTarget = ctoTipMeasurement(
|
||||
systemSettings.SolderingTemp);
|
||||
currentTempTargetDegC = (systemSettings.SolderingTemp);
|
||||
}
|
||||
|
||||
#ifdef MODEL_TS100
|
||||
@@ -648,11 +645,13 @@ void showDebugMenu(void) {
|
||||
break;
|
||||
case 6:
|
||||
//Raw Tip
|
||||
OLED::printNumber(TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(0)), 6);
|
||||
OLED::printNumber(TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0)), 6);
|
||||
break;
|
||||
case 7:
|
||||
//Temp in C
|
||||
OLED::printNumber(tipMeasurementToC(getTipRawTemp(0)), 5);
|
||||
OLED::printNumber(
|
||||
TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(0)),
|
||||
5);
|
||||
break;
|
||||
case 8:
|
||||
//Handle Temp
|
||||
@@ -756,15 +755,14 @@ void startGUITask(void const *argument __unused) {
|
||||
enterSettingsMenu(); // enter the settings menu
|
||||
saveSettings();
|
||||
buttonLockout = true;
|
||||
setCalibrationOffset(systemSettings.CalibrationOffset); // ensure cal offset is applied
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
currentlyActiveTemperatureTarget = 0; // ensure tip is off
|
||||
currentTempTargetDegC = 0; // ensure tip is off
|
||||
getInputVoltageX10(systemSettings.voltageDiv, 0);
|
||||
uint16_t tipTemp = tipMeasurementToC(getTipRawTemp(0));
|
||||
uint16_t tipTemp = TipThermoModel::convertTipRawADCToDegC(getTipRawTemp(0));
|
||||
|
||||
// Preemptively turn the display on. Turn it off if and only if
|
||||
// the tip temperature is below 50 degrees C *and* motion sleep
|
||||
@@ -772,9 +770,11 @@ void startGUITask(void const *argument __unused) {
|
||||
// button presses) in a while.
|
||||
OLED::setDisplayState(OLED::DisplayState::ON);
|
||||
|
||||
if ((tipTemp < 50) && systemSettings.sensitivity &&
|
||||
(((xTaskGetTickCount() - lastMovementTime) > MOVEMENT_INACTIVITY_TIME) &&
|
||||
((xTaskGetTickCount() - lastButtonTime) > BUTTON_INACTIVITY_TIME))) {
|
||||
if ((tipTemp < 50) && systemSettings.sensitivity
|
||||
&& (((xTaskGetTickCount() - lastMovementTime)
|
||||
> MOVEMENT_INACTIVITY_TIME)
|
||||
&& ((xTaskGetTickCount() - lastButtonTime)
|
||||
> BUTTON_INACTIVITY_TIME))) {
|
||||
OLED::setDisplayState(OLED::DisplayState::OFF);
|
||||
}
|
||||
|
||||
@@ -801,7 +801,7 @@ void startGUITask(void const *argument __unused) {
|
||||
#ifdef MODEL_TS80
|
||||
if (!OLED::getRotation()) {
|
||||
#else
|
||||
if (OLED::getRotation()) {
|
||||
if (OLED::getRotation()) {
|
||||
#endif
|
||||
OLED::drawArea(12, 0, 84, 16, idleScreenBG);
|
||||
OLED::setCursor(0, 0);
|
||||
@@ -822,7 +822,7 @@ void startGUITask(void const *argument __unused) {
|
||||
#ifdef MODEL_TS80
|
||||
if (!OLED::getRotation()) {
|
||||
#else
|
||||
if (OLED::getRotation()) {
|
||||
if (OLED::getRotation()) {
|
||||
#endif
|
||||
// in right handed mode we want to draw over the first part
|
||||
OLED::fillArea(55, 0, 41, 16, 0); // clear the area for the temp
|
||||
|
||||
@@ -97,7 +97,7 @@ void resetSettings() {
|
||||
systemSettings.ShutdownTime =
|
||||
10; // How many minutes until the unit turns itself off
|
||||
systemSettings.boostModeEnabled =
|
||||
1; // Default to having boost mode on as most people prefer itF
|
||||
1; // Default to having boost mode on as most people prefer it
|
||||
systemSettings.BoostTemp = 420; // default to 400C
|
||||
systemSettings.autoStartMode = 0; // Auto start off for safety
|
||||
systemSettings.coolingTempBlink =
|
||||
@@ -107,15 +107,15 @@ void resetSettings() {
|
||||
systemSettings.PID_P = 42; // PID tuning constants
|
||||
systemSettings.PID_I = 50;
|
||||
systemSettings.PID_D = 15;
|
||||
systemSettings.CalibrationOffset = 1400; // the adc offset
|
||||
systemSettings.customTipGain =
|
||||
0; // The tip type is either default or a custom gain
|
||||
|
||||
#ifdef MODEL_TS100
|
||||
systemSettings.tipType = TS_B2; // Default to the B2 Tip
|
||||
|
||||
systemSettings.CalibrationOffset = 700; // the adc offset in uV
|
||||
|
||||
#endif
|
||||
#ifdef MODEL_TS80
|
||||
systemSettings.pidPowerLimit=24; // Sets the max pwm power limit
|
||||
systemSettings.tipType = TS_B02; // Default to the B2 Tip
|
||||
systemSettings.CalibrationOffset = 700; // the adc offset in uV
|
||||
#endif
|
||||
saveSettings(); // Save defaults
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
*/
|
||||
|
||||
#include "TipThermoModel.h"
|
||||
#include "Settings.h"
|
||||
|
||||
/*
|
||||
* The hardware is laid out as a non-inverting op-amp
|
||||
@@ -48,6 +49,10 @@ uint32_t TipThermoModel::convertTipRawADCTouV(uint16_t rawADC) {
|
||||
//Now to divide this down by the gain
|
||||
valueuV = (valueuV) / op_amp_gain_stage;
|
||||
//Remove uV tipOffset
|
||||
if (valueuV > systemSettings.CalibrationOffset)
|
||||
valueuV -= systemSettings.CalibrationOffset;
|
||||
else
|
||||
valueuV = 0;
|
||||
//TODO
|
||||
return valueuV;
|
||||
}
|
||||
@@ -55,6 +60,9 @@ uint32_t TipThermoModel::convertTipRawADCTouV(uint16_t rawADC) {
|
||||
uint32_t TipThermoModel::convertTipRawADCToDegC(uint16_t rawADC) {
|
||||
return convertuVToDegC(convertTipRawADCTouV(rawADC));
|
||||
}
|
||||
uint32_t TipThermoModel::convertTipRawADCToDegF(uint16_t rawADC) {
|
||||
return convertuVToDegF(convertTipRawADCTouV(rawADC));
|
||||
}
|
||||
|
||||
//Table that is designed to be walked to find the best sample for the lookup
|
||||
|
||||
@@ -66,110 +74,112 @@ struct HakkoThermocoupleLookup {
|
||||
values() {
|
||||
values[0][0] = 0;
|
||||
values[0][1] = 0;
|
||||
values[1][0] = 175;
|
||||
values[1][1] = 100;
|
||||
values[2][0] = 381;
|
||||
values[2][1] = 200;
|
||||
values[3][0] = 587;
|
||||
values[3][1] = 300;
|
||||
values[4][0] = 804;
|
||||
values[4][1] = 400;
|
||||
values[5][0] = 1005;
|
||||
values[5][1] = 500;
|
||||
values[6][0] = 1007;
|
||||
values[6][1] = 600;
|
||||
values[7][0] = 1107;
|
||||
values[7][1] = 700;
|
||||
values[8][0] = 1310;
|
||||
values[8][1] = 800;
|
||||
values[9][0] = 1522;
|
||||
values[9][1] = 900;
|
||||
values[10][0] = 1731;
|
||||
values[10][1] = 1000;
|
||||
values[11][0] = 1939;
|
||||
values[11][1] = 1100;
|
||||
values[12][0] = 2079;
|
||||
values[12][1] = 1200;
|
||||
values[13][0] = 2265;
|
||||
values[13][1] = 1300;
|
||||
values[14][0] = 2470;
|
||||
values[14][1] = 1400;
|
||||
values[15][0] = 2676;
|
||||
values[15][1] = 1500;
|
||||
values[16][0] = 2899;
|
||||
values[16][1] = 1600;
|
||||
values[17][0] = 3081;
|
||||
values[17][1] = 1700;
|
||||
values[18][0] = 3186;
|
||||
values[18][1] = 1800;
|
||||
values[19][0] = 3422;
|
||||
values[19][1] = 1900;
|
||||
values[20][0] = 3622;
|
||||
values[20][1] = 2000;
|
||||
values[21][0] = 3830;
|
||||
values[21][1] = 2100;
|
||||
values[22][0] = 4044;
|
||||
values[22][1] = 2200;
|
||||
values[23][0] = 4400;
|
||||
values[23][1] = 2300;
|
||||
values[24][0] = 4691;
|
||||
values[24][1] = 2400;
|
||||
values[25][0] = 4989;
|
||||
values[25][1] = 2500;
|
||||
values[26][0] = 5289;
|
||||
values[26][1] = 2600;
|
||||
values[27][0] = 5583;
|
||||
values[27][1] = 2700;
|
||||
values[28][0] = 5879;
|
||||
values[28][1] = 2800;
|
||||
values[29][0] = 6075;
|
||||
values[29][1] = 2900;
|
||||
values[30][0] = 6332;
|
||||
values[30][1] = 3000;
|
||||
values[31][0] = 6521;
|
||||
values[31][1] = 3100;
|
||||
values[32][0] = 6724;
|
||||
values[32][1] = 3200;
|
||||
values[33][0] = 6929;
|
||||
values[33][1] = 3300;
|
||||
values[34][0] = 7132;
|
||||
values[34][1] = 3400;
|
||||
values[35][0] = 7356;
|
||||
values[35][1] = 3500;
|
||||
values[36][0] = 7561;
|
||||
values[36][1] = 3600;
|
||||
values[37][0] = 7774;
|
||||
values[37][1] = 3700;
|
||||
values[38][0] = 7992;
|
||||
values[38][1] = 3800;
|
||||
values[39][0] = 8200;
|
||||
values[39][1] = 3900;
|
||||
values[40][0] = 8410;
|
||||
values[40][1] = 4000;
|
||||
values[41][0] = 8626;
|
||||
values[41][1] = 4100;
|
||||
values[42][0] = 8849;
|
||||
values[42][1] = 4200;
|
||||
values[43][0] = 9060;
|
||||
values[43][1] = 4300;
|
||||
values[44][0] = 9271;
|
||||
values[44][1] = 4400;
|
||||
values[45][0] = 9531;
|
||||
values[45][1] = 4500;
|
||||
values[46][0] = 9748;
|
||||
values[46][1] = 4600;
|
||||
values[47][0] = 10210;
|
||||
values[47][1] = 4700;
|
||||
values[48][0] = 10219;
|
||||
values[48][1] = 4800;
|
||||
values[49][0] = 10429;
|
||||
values[49][1] = 4900;
|
||||
values[50][0] = 10649;
|
||||
values[50][1] = 5000;
|
||||
values[1][0] = 0;
|
||||
values[1][1] = 0;
|
||||
values[2][0] = 175;
|
||||
values[2][1] = 100;
|
||||
values[3][0] = 381;
|
||||
values[3][1] = 200;
|
||||
values[4][0] = 587;
|
||||
values[4][1] = 300;
|
||||
values[5][0] = 804;
|
||||
values[5][1] = 400;
|
||||
values[6][0] = 1005;
|
||||
values[6][1] = 500;
|
||||
values[7][0] = 1007;
|
||||
values[7][1] = 600;
|
||||
values[8][0] = 1107;
|
||||
values[8][1] = 700;
|
||||
values[9][0] = 1310;
|
||||
values[9][1] = 800;
|
||||
values[10][0] = 1522;
|
||||
values[10][1] = 900;
|
||||
values[11][0] = 1731;
|
||||
values[11][1] = 1000;
|
||||
values[12][0] = 1939;
|
||||
values[12][1] = 1100;
|
||||
values[13][0] = 2079;
|
||||
values[13][1] = 1200;
|
||||
values[14][0] = 2265;
|
||||
values[14][1] = 1300;
|
||||
values[15][0] = 2470;
|
||||
values[15][1] = 1400;
|
||||
values[16][0] = 2676;
|
||||
values[16][1] = 1500;
|
||||
values[17][0] = 2899;
|
||||
values[17][1] = 1600;
|
||||
values[18][0] = 3081;
|
||||
values[18][1] = 1700;
|
||||
values[19][0] = 3186;
|
||||
values[19][1] = 1800;
|
||||
values[20][0] = 3422;
|
||||
values[20][1] = 1900;
|
||||
values[21][0] = 3622;
|
||||
values[21][1] = 2000;
|
||||
values[22][0] = 3830;
|
||||
values[22][1] = 2100;
|
||||
values[23][0] = 4044;
|
||||
values[23][1] = 2200;
|
||||
values[24][0] = 4400;
|
||||
values[24][1] = 2300;
|
||||
values[25][0] = 4691;
|
||||
values[25][1] = 2400;
|
||||
values[26][0] = 4989;
|
||||
values[26][1] = 2500;
|
||||
values[27][0] = 5289;
|
||||
values[27][1] = 2600;
|
||||
values[28][0] = 5583;
|
||||
values[28][1] = 2700;
|
||||
values[29][0] = 5879;
|
||||
values[29][1] = 2800;
|
||||
values[30][0] = 6075;
|
||||
values[30][1] = 2900;
|
||||
values[31][0] = 6332;
|
||||
values[31][1] = 3000;
|
||||
values[32][0] = 6521;
|
||||
values[32][1] = 3100;
|
||||
values[33][0] = 6724;
|
||||
values[33][1] = 3200;
|
||||
values[34][0] = 6929;
|
||||
values[34][1] = 3300;
|
||||
values[35][0] = 7132;
|
||||
values[35][1] = 3400;
|
||||
values[36][0] = 7356;
|
||||
values[36][1] = 3500;
|
||||
values[37][0] = 7561;
|
||||
values[37][1] = 3600;
|
||||
values[38][0] = 7774;
|
||||
values[38][1] = 3700;
|
||||
values[39][0] = 7992;
|
||||
values[39][1] = 3800;
|
||||
values[40][0] = 8200;
|
||||
values[40][1] = 3900;
|
||||
values[41][0] = 8410;
|
||||
values[41][1] = 4000;
|
||||
values[42][0] = 8626;
|
||||
values[42][1] = 4100;
|
||||
values[43][0] = 8849;
|
||||
values[43][1] = 4200;
|
||||
values[44][0] = 9060;
|
||||
values[44][1] = 4300;
|
||||
values[45][0] = 9271;
|
||||
values[45][1] = 4400;
|
||||
values[46][0] = 9531;
|
||||
values[46][1] = 4500;
|
||||
values[47][0] = 9748;
|
||||
values[47][1] = 4600;
|
||||
values[48][0] = 10210;
|
||||
values[48][1] = 4700;
|
||||
values[49][0] = 10219;
|
||||
values[49][1] = 4800;
|
||||
values[50][0] = 10429;
|
||||
values[50][1] = 4900;
|
||||
values[51][0] = 10649;
|
||||
values[51][1] = 5000;
|
||||
|
||||
}
|
||||
uint32_t count = 51;
|
||||
uint32_t values[51][2];
|
||||
uint32_t count = 52;
|
||||
uint32_t values[52][2];
|
||||
|
||||
};
|
||||
constexpr auto ThermalTable = HakkoThermocoupleLookup();
|
||||
@@ -189,7 +199,7 @@ uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) {
|
||||
//This assumes results in the table are increasing order
|
||||
// TODO -> Should this be made into a binary search? Is it much faster??
|
||||
for (uint32_t i = 1; i < ThermalTable.count; i++) {
|
||||
if (((uint32_t) ThermalTable.values[i][0]) < tipuVDelta) {
|
||||
if (((uint32_t) ThermalTable.values[i][0]) > tipuVDelta) {
|
||||
//Then extrapolate
|
||||
//Where i= the lower raw sample, i-1 is the higher raw sample
|
||||
return LinearInterpolate( //
|
||||
@@ -197,9 +207,41 @@ uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) {
|
||||
ThermalTable.values[i][1], // y1
|
||||
ThermalTable.values[i - 1][0], // x2
|
||||
ThermalTable.values[i - 1][1], // y2
|
||||
tipuVDelta); // raw sample to be interpolated
|
||||
tipuVDelta) / 10; // raw sample to be interpolated
|
||||
|
||||
}
|
||||
}
|
||||
return 5000;
|
||||
return 500; // fail high -> will turn off heater
|
||||
}
|
||||
|
||||
uint32_t TipThermoModel::convertuVToDegF(uint32_t tipuVDelta) {
|
||||
//(Y °C × 9/5) + 32 =Y°F
|
||||
for (uint32_t i = 1; i < ThermalTable.count; i++) {
|
||||
if (((uint32_t) ThermalTable.values[i][0]) < tipuVDelta) {
|
||||
//Then extrapolate
|
||||
//Where i= the lower raw sample, i-1 is the higher raw sample
|
||||
return ((LinearInterpolate( //
|
||||
ThermalTable.values[i][0], // x1
|
||||
ThermalTable.values[i][1], // y1
|
||||
ThermalTable.values[i - 1][0], // x2
|
||||
ThermalTable.values[i - 1][1], // y2
|
||||
tipuVDelta) // raw sample to be interpolated
|
||||
* 9) / 50) + 32; // Convert C ->> F for 'mericans
|
||||
|
||||
}
|
||||
}
|
||||
return 932; // fail high -> will turn off heater
|
||||
}
|
||||
|
||||
uint32_t TipThermoModel::convertCtoF(uint32_t degC) {
|
||||
//(Y °C × 9/5) + 32 =Y°F
|
||||
return 32 + ((degC * 9) / 5);
|
||||
}
|
||||
|
||||
uint32_t TipThermoModel::convertFtoC(uint32_t degF) {
|
||||
//(Y°F − 32) × 5/9 = Y°C
|
||||
if (degF < 32)
|
||||
return 0;
|
||||
return ((degF - 32) * 5) / 9;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,10 +11,17 @@
|
||||
#include "hardware.h"
|
||||
class TipThermoModel {
|
||||
public:
|
||||
//These are the main two functions
|
||||
static uint32_t convertTipRawADCToDegC(uint16_t rawADC);
|
||||
static uint32_t convertTipRawADCToDegF(uint16_t rawADC);
|
||||
//Returns the uV of the tip reading before the op-amp compensating for pullups
|
||||
static uint32_t convertTipRawADCTouV(uint16_t rawADC);
|
||||
static uint32_t convertTipRawADCToDegC(uint16_t rawADC);
|
||||
static uint32_t convertCtoF(uint32_t degC);
|
||||
static uint32_t convertFtoC(uint32_t degF);
|
||||
|
||||
private:
|
||||
static uint32_t convertuVToDegC(uint32_t tipuVDelta);
|
||||
static uint32_t convertuVToDegF(uint32_t tipuVDelta);
|
||||
};
|
||||
|
||||
#endif /* SRC_TIPTHERMOMODEL_H_ */
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
#include "Translation.h"
|
||||
#include "cmsis_os.h"
|
||||
#include "main.hpp"
|
||||
|
||||
#include "TipThermoModel.h"
|
||||
#include "string.h"
|
||||
extern uint32_t lastButtonTime;
|
||||
void gui_Menu(const menuitem* menu);
|
||||
@@ -50,19 +50,11 @@ static void settings_setCoolingBlinkEnabled(void);
|
||||
static void settings_displayCoolingBlinkEnabled(void);
|
||||
static void settings_setResetSettings(void);
|
||||
static void settings_displayResetSettings(void);
|
||||
static void settings_setTipModel(void);
|
||||
static void settings_displayTipModel(void);
|
||||
static void settings_setCalibrate(void);
|
||||
static void settings_displayCalibrate(void);
|
||||
static void settings_setCalibrateVIN(void);
|
||||
static void settings_displayCalibrateVIN(void);
|
||||
|
||||
// Calibration Menu
|
||||
static void calibration_displaySimpleCal(void); // Hot water cal
|
||||
static void calibration_enterSimpleCal(void);
|
||||
static void calibration_displayAdvancedCal(void); // two point cal
|
||||
static void calibration_enterAdvancedCal(void);
|
||||
|
||||
// Menu functions
|
||||
static void settings_displaySolderingMenu(void);
|
||||
static void settings_enterSolderingMenu(void);
|
||||
@@ -197,8 +189,6 @@ const menuitem advancedMenu[] = {
|
||||
settings_displayAdvancedSolderingScreens } }, /* Advanced soldering screen*/
|
||||
{ (const char*) SettingsDescriptions[13], { settings_setResetSettings }, {
|
||||
settings_displayResetSettings } }, /*Resets settings*/
|
||||
{ (const char*) SettingsDescriptions[17], { settings_setTipModel }, {
|
||||
settings_displayTipModel } }, /*Select tip Model */
|
||||
{ (const char*) SettingsDescriptions[12], { settings_setCalibrate }, {
|
||||
settings_displayCalibrate } }, /*Calibrate tip*/
|
||||
{ (const char*) SettingsDescriptions[14], { settings_setCalibrateVIN }, {
|
||||
@@ -206,13 +196,6 @@ const menuitem advancedMenu[] = {
|
||||
{ NULL, { NULL }, { NULL } } // end of menu marker. DO NOT REMOVE
|
||||
};
|
||||
|
||||
const menuitem calibrationMenu[] { { (const char*) SettingsDescriptions[6], {
|
||||
calibration_enterSimpleCal }, { calibration_displaySimpleCal } },
|
||||
/* Simple Cal*/
|
||||
{ (const char*) SettingsDescriptions[6], { calibration_enterAdvancedCal }, {
|
||||
calibration_displayAdvancedCal } }, /* Advanced Cal */
|
||||
{ NULL, { NULL }, { NULL } } };
|
||||
|
||||
static void printShortDescriptionSingleLine(uint32_t shortDescIndex) {
|
||||
OLED::setFont(0);
|
||||
OLED::setCharCursor(0, 0);
|
||||
@@ -305,7 +288,7 @@ static void settings_displayInputVRange(void) {
|
||||
printShortDescription(0, 6);
|
||||
|
||||
if (systemSettings.cutoutSetting) {
|
||||
OLED::printNumber(2 + systemSettings.cutoutSetting,1);
|
||||
OLED::printNumber(2 + systemSettings.cutoutSetting, 1);
|
||||
OLED::print(SymbolCellCount);
|
||||
} else {
|
||||
OLED::print(SymbolDC);
|
||||
@@ -574,47 +557,11 @@ static void settings_displayResetSettings(void) {
|
||||
printShortDescription(13, 7);
|
||||
}
|
||||
|
||||
static void settings_setTipModel(void) {
|
||||
systemSettings.tipType++;
|
||||
if(systemSettings.tipType==Tip_MiniWare)
|
||||
systemSettings.tipType++;
|
||||
#ifdef MODEL_TS100
|
||||
if(systemSettings.tipType==Tip_Hakko)
|
||||
systemSettings.tipType++;
|
||||
#endif
|
||||
systemSettings.tipType %= (Tip_Custom + 1); // Wrap after custom
|
||||
}
|
||||
static void settings_displayTipModel(void) {
|
||||
printShortDescription(17, 4);
|
||||
// Print in small text the tip model
|
||||
OLED::setFont(1);
|
||||
// set the cursor
|
||||
// Print the mfg
|
||||
OLED::setCursor(55, 0);
|
||||
if (systemSettings.tipType == Tip_Custom) {
|
||||
OLED::print(TipModelStrings[Tip_Custom]);
|
||||
} else if (systemSettings.tipType < Tip_MiniWare) {
|
||||
OLED::print(TipModelStrings[Tip_MiniWare]);
|
||||
}
|
||||
#ifdef MODEL_TS100
|
||||
else if (systemSettings.tipType < Tip_Hakko) {
|
||||
OLED::print(TipModelStrings[Tip_Hakko]);
|
||||
}
|
||||
#endif
|
||||
|
||||
OLED::setCursor(55, 8);
|
||||
if (systemSettings.tipType != Tip_Custom)
|
||||
OLED::print(TipModelStrings[systemSettings.tipType]);
|
||||
|
||||
}
|
||||
static void calibration_displaySimpleCal(void) {
|
||||
printShortDescription(18, 5);
|
||||
}
|
||||
static void setTipOffset() {
|
||||
setCalibrationOffset(0); // turn off the current offset
|
||||
systemSettings.CalibrationOffset = 0;
|
||||
|
||||
// If the thermocouple at the end of the tip, and the handle are at
|
||||
// equalibrium, then the output should be zero, as there is no temperature
|
||||
// If the thermo-couple at the end of the tip, and the handle are at
|
||||
// equilibrium, then the output should be zero, as there is no temperature
|
||||
// differential.
|
||||
|
||||
uint32_t offset = 0;
|
||||
@@ -629,147 +576,20 @@ static void setTipOffset() {
|
||||
OLED::refresh();
|
||||
osDelay(100);
|
||||
}
|
||||
systemSettings.CalibrationOffset = offset / 15;
|
||||
// Need to remove from this the ambient temperature offset
|
||||
uint32_t ambientoffset = getHandleTemperature(); // Handle temp in C x10
|
||||
ambientoffset *= 100;
|
||||
ambientoffset /= tipGainCalValue;
|
||||
systemSettings.CalibrationOffset -= ambientoffset;
|
||||
setCalibrationOffset(systemSettings.CalibrationOffset); // store the error
|
||||
systemSettings.CalibrationOffset = TipThermoModel::convertTipRawADCTouV(
|
||||
offset / 15);
|
||||
OLED::clearScreen();
|
||||
OLED::setCursor(0, 0);
|
||||
OLED::drawCheckbox(true);
|
||||
OLED::refresh();
|
||||
osDelay(1000);
|
||||
}
|
||||
static void calibration_enterSimpleCal(void) {
|
||||
// User has entered into the simple cal routine
|
||||
if (userConfirmation(SettingsCalibrationWarning)) {
|
||||
// User has confirmed their handle is at ambient
|
||||
// So take the offset measurement
|
||||
setTipOffset();
|
||||
// Next we want the user to put the tip into 100C water so we can calculate
|
||||
// their tip's gain Gain is the m term from rise/run plot of raw readings vs
|
||||
// (tip-handle) Thus we want to calculate
|
||||
// ([TipRawHot-TipRawCold])/(ActualHot-HandleHot)-(ActualCold-HandleCold)
|
||||
// Thus we first need to store ->
|
||||
// TiprawCold,HandleCold,ActualCold==HandleCold -> RawTipCold
|
||||
uint32_t RawTipCold = getTipRawTemp(0) * 10;
|
||||
OLED::clearScreen();
|
||||
OLED::setCursor(0, 0);
|
||||
OLED::setFont(1);
|
||||
OLED::print("Please Insert Tip\nInto Boiling Water");
|
||||
OLED::refresh();
|
||||
osDelay(200);
|
||||
waitForButtonPress();
|
||||
|
||||
// Now take the three hot measurements
|
||||
// Assume water is boiling at 100C
|
||||
uint32_t RawTipHot = getTipRawTemp(0) * 10;
|
||||
uint32_t HandleTempHot = getHandleTemperature() / 10;
|
||||
|
||||
uint32_t gain = (RawTipHot - RawTipCold) / (100 - HandleTempHot);
|
||||
|
||||
// Show this to the user
|
||||
OLED::clearScreen();
|
||||
OLED::setCursor(0, 0);
|
||||
OLED::print(YourGainMessage);
|
||||
OLED::printNumber(gain, 6);
|
||||
OLED::refresh();
|
||||
osDelay(2000);
|
||||
waitForButtonPress();
|
||||
OLED::clearScreen();
|
||||
OLED::setCursor(0, 0);
|
||||
OLED::print(SymbolPlus);
|
||||
OLED::printNumber(RawTipHot, 8);
|
||||
OLED::setCursor(0, 8);
|
||||
OLED::print(SymbolMinus);
|
||||
OLED::printNumber(RawTipCold, 8);
|
||||
OLED::refresh();
|
||||
osDelay(2000);
|
||||
waitForButtonPress();
|
||||
}
|
||||
}
|
||||
static void calibration_displayAdvancedCal(void) {
|
||||
printShortDescription(19, 5);
|
||||
}
|
||||
static void calibration_enterAdvancedCal(void) {
|
||||
//Advanced cal
|
||||
if (userConfirmation(SettingsCalibrationWarning)) {
|
||||
//User has confirmed their handle is at ambient
|
||||
//So take the offset measurement
|
||||
setTipOffset();
|
||||
//The tip now has a known ADC offset
|
||||
//Head up until it is at 350C
|
||||
//Then let the user adjust the gain value until it converges
|
||||
systemSettings.customTipGain = 160; // start safe and high
|
||||
bool exit = false;
|
||||
|
||||
while (exit == false) {
|
||||
//Set tip to 350C
|
||||
setTipType(Tip_Custom, systemSettings.customTipGain);
|
||||
currentlyActiveTemperatureTarget = ctoTipMeasurement(350);
|
||||
//Check if user has pressed button to change the gain
|
||||
ButtonState buttons = getButtonState();
|
||||
switch (buttons) {
|
||||
case BUTTON_NONE:
|
||||
break;
|
||||
case BUTTON_BOTH:
|
||||
case BUTTON_B_LONG:
|
||||
case BUTTON_F_LONG:
|
||||
exit = true;
|
||||
break;
|
||||
case BUTTON_F_SHORT:
|
||||
systemSettings.customTipGain++;
|
||||
break;
|
||||
case BUTTON_B_SHORT: {
|
||||
systemSettings.customTipGain--;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
if (systemSettings.customTipGain > 200)
|
||||
systemSettings.customTipGain = 200;
|
||||
else if (systemSettings.customTipGain <= 100)
|
||||
systemSettings.customTipGain = 100;
|
||||
OLED::setCursor(0, 0);
|
||||
OLED::clearScreen();
|
||||
OLED::setFont(0);
|
||||
if (OLED::getRotation())
|
||||
OLED::print(SymbolMinus);
|
||||
else
|
||||
OLED::print(SymbolPlus);
|
||||
|
||||
OLED::print(SymbolSpace);
|
||||
OLED::printNumber(systemSettings.customTipGain, 4);
|
||||
OLED::print(SymbolSpace);
|
||||
if (OLED::getRotation())
|
||||
OLED::print(SymbolPlus);
|
||||
else
|
||||
OLED::print(SymbolMinus);
|
||||
OLED::refresh();
|
||||
GUIDelay();
|
||||
}
|
||||
// Wait for the user to confirm the exit message that the calibration is done
|
||||
userConfirmation(SettingsCalibrationDone);
|
||||
}
|
||||
}
|
||||
//Provide the user the option to tune their own tip if custom is selected
|
||||
//If not only do single point tuning as per usual
|
||||
static void settings_setCalibrate(void) {
|
||||
if (systemSettings.tipType == Tip_Custom) {
|
||||
// Two types of calibration
|
||||
// 1. Basic, idle temp + hot water (100C)
|
||||
// 2. Advanced, 100C + 350C, we keep PID tracking to a temperature target
|
||||
return gui_Menu(calibrationMenu);
|
||||
}
|
||||
// Else
|
||||
// Ask user if handle is at the tip temperature
|
||||
// Any error between handle and the tip will be a direct offset in the control
|
||||
// loop
|
||||
|
||||
else if (userConfirmation(SettingsCalibrationWarning)) {
|
||||
if (userConfirmation(SettingsCalibrationWarning)) {
|
||||
// User confirmed
|
||||
// So we now perform the actual calculation
|
||||
setTipOffset();
|
||||
|
||||
@@ -9,17 +9,7 @@
|
||||
#include "hardware.h"
|
||||
#include "history.hpp"
|
||||
volatile uint16_t PWMSafetyTimer = 0;
|
||||
volatile int16_t CalibrationTempOffset = 0;
|
||||
uint16_t tipGainCalValue = 0;
|
||||
void setTipType(enum TipType tipType, uint8_t manualCalGain) {
|
||||
if (manualCalGain)
|
||||
tipGainCalValue = manualCalGain;
|
||||
else
|
||||
tipGainCalValue = lookupTipDefaultCalValue(tipType);
|
||||
}
|
||||
void setCalibrationOffset(int16_t offSet) {
|
||||
CalibrationTempOffset = offSet;
|
||||
}
|
||||
|
||||
uint16_t getHandleTemperature() {
|
||||
// We return the current handle temperature in X10 C
|
||||
// TMP36 in handle, 0.5V offset and then 10mV per deg C (0.75V @ 25C for
|
||||
@@ -36,34 +26,7 @@ uint16_t getHandleTemperature() {
|
||||
result /= 993;
|
||||
return result;
|
||||
}
|
||||
uint16_t tipMeasurementToC(uint16_t raw) {
|
||||
//((Raw Tip-RawOffset) * calibrationgain) / 1000 = tip delta in CX10
|
||||
// tip delta in CX10 + handleTemp in CX10 = tip absolute temp in CX10
|
||||
// Div answer by 10 to get final result
|
||||
|
||||
uint32_t tipDelta = ((raw - CalibrationTempOffset) * tipGainCalValue)
|
||||
/ 1000;
|
||||
tipDelta += getHandleTemperature();
|
||||
|
||||
return tipDelta / 10;
|
||||
}
|
||||
uint16_t ctoTipMeasurement(uint16_t temp) {
|
||||
//[ (temp-handle/10) * 10000 ]/calibrationgain = tip raw delta
|
||||
// tip raw delta + tip offset = tip ADC reading
|
||||
int32_t TipRaw = ((temp - (getHandleTemperature() / 10)) * 10000)
|
||||
/ tipGainCalValue;
|
||||
TipRaw += CalibrationTempOffset;
|
||||
return TipRaw;
|
||||
}
|
||||
|
||||
uint16_t tipMeasurementToF(uint16_t raw) {
|
||||
// Convert result from C to F
|
||||
return (tipMeasurementToC(raw) * 9) / 5 + 32;
|
||||
}
|
||||
uint16_t ftoTipMeasurement(uint16_t temp) {
|
||||
// Convert the temp back to C from F
|
||||
return ctoTipMeasurement(((temp - 32) * 5) / 9);
|
||||
}
|
||||
|
||||
uint16_t getTipInstantTemperature() {
|
||||
uint16_t sum = 0; // 12 bit readings * 8 -> 15 bits
|
||||
@@ -93,44 +56,7 @@ uint16_t getTipInstantTemperature() {
|
||||
sum += readings[minID]; //Duplicate the min to make up for the missing max value
|
||||
return sum; // 8x over sample
|
||||
}
|
||||
/*
|
||||
* Loopup table for the tip calibration values for
|
||||
* the gain of the tip's
|
||||
* This can be found by line of best fit of TipRaw on X, and TipTemp-handle on
|
||||
* Y. Then take the m term * 10000
|
||||
* */
|
||||
uint16_t lookupTipDefaultCalValue(enum TipType tipID) {
|
||||
#ifdef MODEL_TS100
|
||||
switch (tipID) {
|
||||
case TS_D24:
|
||||
return 141;
|
||||
break;
|
||||
case TS_BC2:
|
||||
return (133 + 129) / 2;
|
||||
break;
|
||||
case TS_C1:
|
||||
return 133;
|
||||
break;
|
||||
case TS_B2:
|
||||
return 133;
|
||||
default:
|
||||
return 132; // make this the average of all
|
||||
break;
|
||||
}
|
||||
#else
|
||||
switch (tipID) {
|
||||
case TS_D25:
|
||||
return 154;
|
||||
break;
|
||||
case TS_B02:
|
||||
return 154;
|
||||
break;
|
||||
default:
|
||||
return 154; // make this the average of all
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
//2 second filter (ADC is PID_TIM_HZ Hz)
|
||||
history<uint16_t, PID_TIM_HZ*4> rawTempFilter = { { 0 }, 0, 0 };
|
||||
|
||||
@@ -333,54 +259,7 @@ void startQC(uint16_t divisor) {
|
||||
if (QCTries > 10)
|
||||
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)
|
||||
// current PA0->Diode -> 6K8 -> Tip -> GND So the op-amp will amplify the
|
||||
// small signal across the tip and convert this into an easily read voltage
|
||||
GPIO_InitTypeDef GPIO_InitStruct;
|
||||
GPIO_InitStruct.Pin = GPIO_PIN_0;
|
||||
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
|
||||
setTipPWM(0);
|
||||
vTaskDelay(1);
|
||||
uint32_t offReading = getTipRawTemp(1);
|
||||
for (uint8_t i = 0; i < 49; i++) {
|
||||
vTaskDelay(1); // delay to allow it to stabilize
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
offReading += getTipRawTemp(1);
|
||||
}
|
||||
|
||||
// Turn on
|
||||
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 < 49; i++) {
|
||||
vTaskDelay(1); // delay to allow it to stabilize
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
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
|
||||
// resistance This was determined emperically This tip is 4.688444162 ohms,
|
||||
// 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
|
||||
lastRes = (difference / 21) + 1; // ceil
|
||||
return lastRes;
|
||||
}
|
||||
static unsigned int sqrt32(unsigned long n) {
|
||||
unsigned int c = 0x8000;
|
||||
unsigned int g = 0x8000;
|
||||
@@ -398,7 +277,7 @@ int16_t calculateMaxVoltage(uint8_t useHP) {
|
||||
// This measures the tip resistance, then it calculates the appropriate
|
||||
// voltage To stay under ~18W. Mosfet is "9A", so no issues there
|
||||
// QC3.0 supports up to 18W, which is 2A @9V and 1.5A @12V
|
||||
uint32_t milliOhms = calculateTipR();
|
||||
uint32_t milliOhms = 4500;
|
||||
// Check no tip
|
||||
if (milliOhms > 10000)
|
||||
return -1;
|
||||
|
||||
@@ -11,10 +11,10 @@
|
||||
#include "stdlib.h"
|
||||
#include "stm32f1xx_hal.h"
|
||||
#include "string.h"
|
||||
|
||||
#include "TipThermoModel.h"
|
||||
uint8_t PCBVersion = 0;
|
||||
// File local variables
|
||||
uint32_t currentlyActiveTemperatureTarget = 0;
|
||||
uint32_t currentTempTargetDegC = 0; // Current temperature target in C
|
||||
uint32_t lastMovementTime = 0;
|
||||
int16_t idealQCVoltage = 0;
|
||||
// FreeRTOS variables
|
||||
@@ -71,9 +71,7 @@ int main(void) {
|
||||
}
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
restoreSettings(); // load the settings from flash
|
||||
setCalibrationOffset(systemSettings.CalibrationOffset);
|
||||
setTipType((enum TipType) systemSettings.tipType,
|
||||
systemSettings.customTipGain); // apply tip type selection
|
||||
|
||||
HAL_IWDG_Refresh(&hiwdg);
|
||||
|
||||
/* Create the thread(s) */
|
||||
@@ -112,7 +110,6 @@ void startPIDTask(void const *argument __unused) {
|
||||
#ifdef MODEL_TS80
|
||||
idealQCVoltage = calculateMaxVoltage(systemSettings.cutoutSetting);
|
||||
#endif
|
||||
uint8_t rawC = ctoTipMeasurement(101) - ctoTipMeasurement(100); // 1*C change in raw.
|
||||
|
||||
#ifdef MODEL_TS80
|
||||
//Set power management code to the tip resistance in ohms * 10
|
||||
@@ -122,30 +119,30 @@ void startPIDTask(void const *argument __unused) {
|
||||
|
||||
#endif
|
||||
history<int32_t, 16> tempError = { { 0 }, 0, 0 };
|
||||
currentlyActiveTemperatureTarget = 0; // Force start with no output (off). If in sleep / soldering this will
|
||||
// be over-ridden rapidly
|
||||
currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will
|
||||
// be over-ridden rapidly
|
||||
pidTaskNotification = xTaskGetCurrentTaskHandle();
|
||||
for (;;) {
|
||||
|
||||
if (ulTaskNotifyTake(pdTRUE, 2000)) {
|
||||
// This is a call to block this thread until the ADC does its samples
|
||||
uint16_t rawTemp = getTipRawTemp(1); // get instantaneous reading
|
||||
if (currentlyActiveTemperatureTarget) {
|
||||
if (currentTempTargetDegC) {
|
||||
// Cap the max set point to 450C
|
||||
if (currentlyActiveTemperatureTarget > ctoTipMeasurement(450)) {
|
||||
if (currentTempTargetDegC > (450)) {
|
||||
//Maximum allowed output
|
||||
currentlyActiveTemperatureTarget = ctoTipMeasurement(450);
|
||||
} else if (currentlyActiveTemperatureTarget > 32400) {
|
||||
//Cap to max adc reading
|
||||
currentlyActiveTemperatureTarget = 32400;
|
||||
currentTempTargetDegC = (450);
|
||||
}
|
||||
// Convert the current tip to degree's C
|
||||
uint32_t currentTipTempInC =
|
||||
TipThermoModel::convertTipRawADCToDegC(rawTemp);
|
||||
currentTipTempInC += getHandleTemperature() / 10; //Add handle offset
|
||||
|
||||
// As we get close to our target, temp noise causes the system
|
||||
// to be unstable. Use a rolling average to dampen it.
|
||||
// We overshoot by roughly 1/2 of 1 degree Fahrenheit.
|
||||
// We overshoot by roughly 1 degree C.
|
||||
// This helps stabilize the display.
|
||||
int32_t tError = currentlyActiveTemperatureTarget - rawTemp
|
||||
+ (rawC / 4);
|
||||
int32_t tError = currentTempTargetDegC - currentTipTempInC + 1;
|
||||
tError = tError > INT16_MAX ? INT16_MAX : tError;
|
||||
tError = tError < INT16_MIN ? INT16_MIN : tError;
|
||||
tempError.update(tError);
|
||||
@@ -160,15 +157,8 @@ void startPIDTask(void const *argument __unused) {
|
||||
// This is necessary because of the temp noise and thermal lag in the system.
|
||||
// Once we have feed-forward temp estimation we should be able to better tune this.
|
||||
|
||||
#ifdef MODEL_TS100
|
||||
const uint16_t mass = 2020 / 20; // divide here so division is compile-time.
|
||||
#endif
|
||||
#ifdef MODEL_TS80
|
||||
const uint16_t mass = 2020 / 50;
|
||||
#endif
|
||||
|
||||
int32_t milliWattsNeeded = tempToMilliWatts(tempError.average(),
|
||||
mass);
|
||||
int32_t milliWattsNeeded = tempToMilliWatts(
|
||||
tempError.average());
|
||||
// note that milliWattsNeeded is sometimes negative, this counters overshoot
|
||||
// from I term's inertia.
|
||||
milliWattsOut += milliWattsNeeded;
|
||||
@@ -193,7 +183,7 @@ void startPIDTask(void const *argument __unused) {
|
||||
// This is purely guesswork :'( as everyone implements stuff differently
|
||||
if (xTaskGetTickCount() - lastPowerPulse < 10) {
|
||||
// for the first 100mS turn on for a bit
|
||||
setTipMilliWatts(5000); // typically its around 5W to hold the current temp, so this wont raise temp much
|
||||
setTipMilliWatts(2500); // typically its around 5W to hold the current temp, so this wont raise temp much
|
||||
} else
|
||||
setTipMilliWatts(0);
|
||||
//Then wait until the next 0.5 seconds
|
||||
|
||||
@@ -14,11 +14,11 @@ const uint16_t totalPWM = 255 + 17; //htim2.Init.Period, the full PWM cycle
|
||||
|
||||
history<uint32_t, oscillationPeriod> milliWattHistory = { { 0 }, 0, 0 };
|
||||
|
||||
int32_t tempToMilliWatts(int32_t rawTemp, uint8_t rawC) {
|
||||
int32_t tempToMilliWatts(int32_t rawTemp) {
|
||||
// mass is in milliJ/*C, rawC is raw per degree C
|
||||
// returns milliWatts needed to raise/lower a mass by rawTemp
|
||||
// degrees in one cycle.
|
||||
int32_t milliJoules = tipMass*10 * (rawTemp / rawC);
|
||||
int32_t milliJoules = tipMass*10 * rawTemp;
|
||||
return milliJoules;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user