diff --git a/workspace/TS100/.settings/language.settings.xml b/workspace/TS100/.settings/language.settings.xml index f18f24e1..2b2f4904 100644 --- a/workspace/TS100/.settings/language.settings.xml +++ b/workspace/TS100/.settings/language.settings.xml @@ -6,7 +6,7 @@ - + diff --git a/workspace/TS100/Core/Inc/expMovingAverage.h b/workspace/TS100/Core/Inc/expMovingAverage.h new file mode 100644 index 00000000..374befb7 --- /dev/null +++ b/workspace/TS100/Core/Inc/expMovingAverage.h @@ -0,0 +1,24 @@ +/* + * expMovingAverage.h + * + * Created on: 8 Oct 2019 + * Author: ralim + */ + +#ifndef INC_EXPMOVINGAVERAGE_H_ +#define INC_EXPMOVINGAVERAGE_H_ + +// max size = 127 +template +struct expMovingAverage { + int32_t sum; + void update(T const val) { + sum = ((val * weighting) + (sum * (256 - weighting))) / 256; + } + + T average() const { + return sum; + } +}; + +#endif /* INC_EXPMOVINGAVERAGE_H_ */ diff --git a/workspace/TS100/Core/Inc/history.hpp b/workspace/TS100/Core/Inc/history.hpp index 01f2a93d..c6dd8778 100644 --- a/workspace/TS100/Core/Inc/history.hpp +++ b/workspace/TS100/Core/Inc/history.hpp @@ -11,25 +11,25 @@ #include // max size = 127 -template +template struct history { - static const uint8_t size = SIZE; + static const uint8_t size = SIZE; T buf[size]; int32_t sum; uint8_t loc; void update(T const val) { // step backwards so i+1 is the previous value. - loc = (size+loc-1) % size; sum -= buf[loc]; sum += val; buf[loc] = val; + loc = (loc + 1) % size; } - T operator[] (uint8_t i) const { + T operator[](uint8_t i) const { // 0 = newest, size-1 = oldest. - i = (i+loc) % size; + i = (i + loc) % size; return buf[i]; } diff --git a/workspace/TS100/Core/Inc/power.hpp b/workspace/TS100/Core/Inc/power.hpp index 94d329a4..9e86752b 100644 --- a/workspace/TS100/Core/Inc/power.hpp +++ b/workspace/TS100/Core/Inc/power.hpp @@ -8,6 +8,7 @@ #include "stdint.h" #include #include "hardware.h" +#include "expMovingAverage.h" #ifndef POWER_HPP_ #define POWER_HPP_ @@ -18,17 +19,17 @@ // Once we have feed-forward temp estimation we should be able to better tune this. #ifdef MODEL_TS100 -const int32_t tipMass = 3500; // divide here so division is compile-time. +const int32_t tipMass = 45; // X10 watts to raise 1 deg C in 1 second const uint8_t tipResistance = 85; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80 #endif #ifdef MODEL_TS80 -const uint32_t tipMass = 4500; +const uint32_t tipMass = 40; const uint8_t tipResistance = 45; //x10 ohms, 8.5 typical for ts100, 4.5 typical for ts80 #endif -const uint8_t oscillationPeriod = 8*PID_TIM_HZ; // I term look back value -extern history x10WattHistory; +const uint8_t wattHistoryFilter = 24; // I term look back weighting +extern expMovingAverage x10WattHistory; int32_t tempToX10Watts(int32_t rawTemp); void setTipX10Watts(int32_t mw); diff --git a/workspace/TS100/Core/Src/GUIThread.cpp b/workspace/TS100/Core/Src/GUIThread.cpp index 41b78814..2bdaaa54 100644 --- a/workspace/TS100/Core/Src/GUIThread.cpp +++ b/workspace/TS100/Core/Src/GUIThread.cpp @@ -502,9 +502,9 @@ static void gui_solderingMode(uint8_t jumpToSleep) { if (systemSettings.detailedSoldering) { OLED::setFont(1); OLED::print(SolderingAdvancedPowerPrompt); // Power: - OLED::printNumber(x10WattHistory[0] / 10, 2); + OLED::printNumber(x10WattHistory.average() / 10, 2); OLED::print(SymbolDot); - OLED::printNumber(x10WattHistory[0] % 10, 1); + OLED::printNumber(x10WattHistory.average()% 10, 1); OLED::print(SymbolWatts); if (systemSettings.sensitivity && systemSettings.SleepTime) { @@ -538,10 +538,10 @@ static void gui_solderingMode(uint8_t jumpToSleep) { OLED::print(SymbolSpace); // Draw heating/cooling symbols - OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory[0])); + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); } else { // Draw heating/cooling symbols - OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory[0])); + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); // We draw boost arrow if boosting, or else gap temp <-> heat // indicator if (boostModeOn) diff --git a/workspace/TS100/Core/Src/Settings.cpp b/workspace/TS100/Core/Src/Settings.cpp index e8011e6e..02140333 100644 --- a/workspace/TS100/Core/Src/Settings.cpp +++ b/workspace/TS100/Core/Src/Settings.cpp @@ -106,7 +106,7 @@ void resetSettings() { systemSettings.descriptionScrollSpeed = 0; // default to slow #ifdef MODEL_TS100 - systemSettings.CalibrationOffset = 300; // the adc offset in uV + systemSettings.CalibrationOffset = 850; // the adc offset in uV systemSettings.pidPowerLimit=70; // Sets the max pwm power limit #endif diff --git a/workspace/TS100/Core/Src/TipThermoModel.cpp b/workspace/TS100/Core/Src/TipThermoModel.cpp index 168216e2..23d26a2b 100644 --- a/workspace/TS100/Core/Src/TipThermoModel.cpp +++ b/workspace/TS100/Core/Src/TipThermoModel.cpp @@ -50,7 +50,7 @@ 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) + if (valueuV >= systemSettings.CalibrationOffset) valueuV -= systemSettings.CalibrationOffset; else valueuV = 0; diff --git a/workspace/TS100/Core/Src/gui.cpp b/workspace/TS100/Core/Src/gui.cpp index f9f484e7..c82a1726 100644 --- a/workspace/TS100/Core/Src/gui.cpp +++ b/workspace/TS100/Core/Src/gui.cpp @@ -563,25 +563,26 @@ static void setTipOffset() { // 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; - for (uint8_t i = 0; i < 15; i++) { - offset += getTipRawTemp(0); - // cycle through the filter a fair bit to ensure we're stable. - OLED::clearScreen(); - OLED::setCursor(0, 0); - OLED::print(SymbolDot); - for (uint8_t x = 0; x < i / 4; x++) + while (systemSettings.CalibrationOffset == 0) { + uint32_t offset = 0; + for (uint8_t i = 0; i < 16; i++) { + offset += getTipRawTemp(1); + // cycle through the filter a fair bit to ensure we're stable. + OLED::clearScreen(); + OLED::setCursor(0, 0); OLED::print(SymbolDot); - OLED::refresh(); - osDelay(100); + for (uint8_t x = 0; x < (i / 4); x++) + OLED::print(SymbolDot); + OLED::refresh(); + osDelay(100); + } + systemSettings.CalibrationOffset = TipThermoModel::convertTipRawADCTouV( + offset / 16); } - systemSettings.CalibrationOffset = TipThermoModel::convertTipRawADCTouV( - offset / 15); OLED::clearScreen(); OLED::setCursor(0, 0); OLED::drawCheckbox(true); - OLED::printNumber(systemSettings.CalibrationOffset,4); + OLED::printNumber(systemSettings.CalibrationOffset, 4); OLED::refresh(); osDelay(1200); } diff --git a/workspace/TS100/Core/Src/main.cpp b/workspace/TS100/Core/Src/main.cpp index 9568b97a..f50ab87f 100644 --- a/workspace/TS100/Core/Src/main.cpp +++ b/workspace/TS100/Core/Src/main.cpp @@ -118,7 +118,7 @@ void startPIDTask(void const *argument __unused) { #else #endif - history tempError = { { 0 }, 0, 0 }; + history tempError = { { 0 }, 0, 0 }; currentTempTargetDegC = 0; // Force start with no output (off). If in sleep / soldering this will // be over-ridden rapidly pidTaskNotification = xTaskGetCurrentTaskHandle(); @@ -126,6 +126,9 @@ void startPIDTask(void const *argument __unused) { if (ulTaskNotifyTake(pdTRUE, 2000)) { // This is a call to block this thread until the ADC does its samples + // Do the reading here to keep the temp calculations churning along + uint32_t currentTipTempInC = TipThermoModel::getTipInC(true); + if (currentTempTargetDegC) { // Cap the max set point to 450C if (currentTempTargetDegC > (450)) { @@ -133,7 +136,6 @@ void startPIDTask(void const *argument __unused) { currentTempTargetDegC = (450); } // Convert the current tip to degree's C - uint32_t currentTipTempInC = TipThermoModel::getTipInC(true); // As we get close to our target, temp noise causes the system // to be unstable. Use a rolling average to dampen it. diff --git a/workspace/TS100/Core/Src/power.cpp b/workspace/TS100/Core/Src/power.cpp index a762a8cc..7fc8f956 100644 --- a/workspace/TS100/Core/Src/power.cpp +++ b/workspace/TS100/Core/Src/power.cpp @@ -12,7 +12,7 @@ const uint16_t powerPWM = 255; const uint16_t totalPWM = 255 + 17; //htim2.Init.Period, the full PWM cycle -history x10WattHistory = { { 0 }, 0, 0 }; +expMovingAverage x10WattHistory = { 0 }; int32_t tempToX10Watts(int32_t rawTemp) { // mass is in milliJ/*C, rawC is raw per degree C