From e351527dd2f2ca4d29452309fe52f5d5a51fa36a Mon Sep 17 00:00:00 2001 From: "Ben V. Brown" Date: Wed, 27 Sep 2017 09:42:39 +1000 Subject: [PATCH] Add tip compensation support --- workspace/TS100/inc/Settings.h | 33 ++++++-------- workspace/TS100/inc/Translation.h | 5 ++- workspace/TS100/inc/hardware.h | 2 +- workspace/TS100/inc/main.hpp | 15 +++++++ workspace/TS100/src/Settings.cpp | 24 ++++++++--- workspace/TS100/src/Translation.c | 8 +++- workspace/TS100/src/gui.cpp | 72 +++++++++++++++++++++++++++---- workspace/TS100/src/hardware.c | 11 +++-- workspace/TS100/src/main.cpp | 21 +++------ 9 files changed, 133 insertions(+), 58 deletions(-) diff --git a/workspace/TS100/inc/Settings.h b/workspace/TS100/inc/Settings.h index 7c1316f8..d3d4581d 100644 --- a/workspace/TS100/inc/Settings.h +++ b/workspace/TS100/inc/Settings.h @@ -11,35 +11,28 @@ #define SETTINGS_H_ #include #include "stm32f1xx_hal.h" -#define SETTINGSVERSION 2 /*Change this if you change the struct below to prevent people getting out of sync*/ -//Display Speeds -#define DISPLAYMODE_FAST (0x00) -#define DISPLAYMODE_MEDIUM (0x01) -#define DISPLAYMODE_SLOW (0x02) -//Rounding Modes -#define ROUNDING_NONE (0x00) -#define ROUNDING_FIVE (0x01) -#define ROUNDING_TEN (0x02) +#define SETTINGSVERSION 0x10 /*Change this if you change the struct below to prevent people getting out of sync*/ /* * This struct must be a multiple of 2 bytes as it is saved / restored from flash in uint16_t chunks */ typedef struct { uint16_t SolderingTemp; //current set point for the iron - uint32_t SleepTemp; //temp to drop to in sleep - uint8_t version; //Used to track if a reset is needed on firmware upgrade + uint16_t SleepTemp; //temp to drop to in sleep uint8_t SleepTime; //minutes timeout to sleep - uint8_t cutoutSetting :3; //(3 bits) The voltage we cut out at for under voltage - uint8_t powerDisplay :1; //Toggle to swap the arrows with a power readout instead - uint8_t OrientationMode :2; //If true we want to invert the display for lefties - uint8_t sensitivity :5; //Sensitivity of accelerometer (5 bits) - uint8_t autoStartMode :2; //Should the unit automatically jump straight into soldering mode when power is applied - uint8_t ShutdownTime :6; //Time until unit shuts down if left alone - uint8_t boostModeEnabled :1; //Boost mode swaps BUT_A in soldering mode to temporary soldering temp over-ride - uint8_t coolingTempBlink :1; //Should the temperature blink on the cool down screen until its <50C - uint8_t advancedScreens :1; //If enabled we draw more detailed screens with smaller fonts + uint8_t cutoutSetting; // The voltage we cut out at for under voltage + uint8_t powerDisplay; //Toggle to swap the arrows with a power readout instead + uint8_t OrientationMode; //If true we want to invert the display for lefties + uint8_t sensitivity; //Sensitivity of accelerometer (5 bits) + uint8_t autoStartMode; //Should the unit automatically jump straight into soldering mode when power is applied + uint8_t ShutdownTime; //Time until unit shuts down if left alone + uint8_t boostModeEnabled; //Boost mode swaps BUT_A in soldering mode to temporary soldering temp over-ride + uint8_t coolingTempBlink; //Should the temperature blink on the cool down screen until its <50C + uint8_t advancedScreens; //If enabled we draw more detailed screens with smaller fonts 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 in the iron. + uint8_t version; //Used to track if a reset is needed on firmware upgrade uint32_t padding; //This is here for in case we are not an even divisor so that nothing gets cut off } systemSettingsType; diff --git a/workspace/TS100/inc/Translation.h b/workspace/TS100/inc/Translation.h index 3d065e58..44647778 100644 --- a/workspace/TS100/inc/Translation.h +++ b/workspace/TS100/inc/Translation.h @@ -10,6 +10,7 @@ -extern const char* SettingsLongNames[12]; -extern const char* SettingsShortNames[12]; +extern const char* SettingsLongNames[13]; +extern const char* SettingsShortNames[13]; +extern const char* SettingsCalibrationWarning; #endif /* TRANSLATION_H_ */ diff --git a/workspace/TS100/inc/hardware.h b/workspace/TS100/inc/hardware.h index 783c3ce5..3ee860f3 100644 --- a/workspace/TS100/inc/hardware.h +++ b/workspace/TS100/inc/hardware.h @@ -45,7 +45,7 @@ uint16_t getTipInstantTemperature(); void setTipPWM(uint8_t pulse); uint16_t ctoTipMeasurement(uint16_t temp); uint16_t tipMeasurementToC(uint16_t raw); - +void setCalibrationOffset(int16_t offSet); #ifdef __cplusplus } #endif diff --git a/workspace/TS100/inc/main.hpp b/workspace/TS100/inc/main.hpp index f4761e25..1684285a 100644 --- a/workspace/TS100/inc/main.hpp +++ b/workspace/TS100/inc/main.hpp @@ -6,5 +6,20 @@ extern OLED lcd; extern MMA8652FC accel; +enum ButtonState { + BUTTON_NONE = 0, /* No buttons pressed / < filter time*/ + BUTTON_F_SHORT = 1, /* User has pressed the front button*/ + BUTTON_B_SHORT = 2, /* User has pressed the back button*/ + BUTTON_F_LONG = 4, /* User is holding the front button*/ + BUTTON_B_LONG = 8, /* User is holding the back button*/ + BUTTON_BOTH = 16, /* User has pressed both buttons*/ + +/* + * Note: + * Pressed means press + release, we trigger on a full \__/ pulse + * holding means it has gone low, and been low for longer than filter time + */ +}; +ButtonState getButtonState(); #endif /* __MAIN_H */ diff --git a/workspace/TS100/src/Settings.cpp b/workspace/TS100/src/Settings.cpp index df60b9f6..004b2a2b 100644 --- a/workspace/TS100/src/Settings.cpp +++ b/workspace/TS100/src/Settings.cpp @@ -8,8 +8,9 @@ */ #include "Settings.h" +#include "Setup.h" #define FLASH_ADDR (0x8000000|0xBC00)/*Flash start OR'ed with the maximum amount of flash - 1024 bytes*/ - +#include "string.h" systemSettingsType systemSettings; void saveSettings() { @@ -20,23 +21,33 @@ void saveSettings() { pEraseInit.NbPages = 1; pEraseInit.PageAddress = FLASH_ADDR; uint32_t failingAddress = 0; + HAL_IWDG_Refresh(&hiwdg); + __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_WRPERR | FLASH_FLAG_PGERR | FLASH_FLAG_BSY); HAL_FLASH_Unlock(); + HAL_Delay(10); + HAL_IWDG_Refresh(&hiwdg); HAL_FLASHEx_Erase(&pEraseInit, &failingAddress); - //^ Erase the page of flash (1024 bytes on this platform) + //^ Erase the page of flash (1024 bytes on this stm32) //erased the chunk //now we program it uint16_t *data = (uint16_t*) &systemSettings; - for (uint8_t i = 0; i < (sizeof(systemSettings) / 2); i++) { + HAL_FLASH_Unlock(); + + for (uint8_t i = 0; i < (sizeof(systemSettingsType) / 2); i++) { + HAL_IWDG_Refresh(&hiwdg); HAL_FLASH_Program(FLASH_TYPEPROGRAM_HALFWORD, FLASH_ADDR + (i * 2), data[i]); } + HAL_FLASH_Lock(); + } void restoreSettings() { //We read the flash uint16_t *data = (uint16_t*) &systemSettings; - for (uint8_t i = 0; i < (sizeof(systemSettings) / 2); i++) { - data[i] = *(uint16_t *) (FLASH_ADDR + (i * 2)); + for (uint8_t i = 0; i < (sizeof(systemSettingsType) / 2); i++) { + data[i] = *((uint16_t*) (FLASH_ADDR + (i * 2))); } + //if the version is correct were done //if not we reset and save if (systemSettings.version != SETTINGSVERSION) { @@ -66,7 +77,7 @@ void resetSettings() { systemSettings.SolderingTemp = 320; //Default soldering temp is 320.0 C systemSettings.cutoutSetting = 0; //default to no cut-off voltage systemSettings.version = SETTINGSVERSION; //Store the version number to allow for easier upgrades - systemSettings.advancedScreens = 1; //Do we show detailed screens? + systemSettings.advancedScreens = 0; //Do we show detailed screens? systemSettings.OrientationMode = 2; //Default to automatic systemSettings.sensitivity = 8; //Default high sensitivity systemSettings.voltageDiv = 144; //Default divider from schematic @@ -76,6 +87,7 @@ void resetSettings() { systemSettings.powerDisplay = 0; //default to power display being off systemSettings.autoStartMode = 0; //Auto start off for safety systemSettings.coolingTempBlink = 0; //Blink the temperature on the cooling screen when its > 50C + systemSettings.CalibrationOffset = 10; saveSettings(); } diff --git a/workspace/TS100/src/Translation.c b/workspace/TS100/src/Translation.c index 3295bdee..269f7b19 100644 --- a/workspace/TS100/src/Translation.c +++ b/workspace/TS100/src/Translation.c @@ -11,7 +11,7 @@ #endif #ifdef LANG_EN -const char* SettingsLongNames[12] = +const char* SettingsLongNames[13] = { /*These are all the help text for all the settings.*/ /*No requirements on spacing or length*/ @@ -26,10 +26,11 @@ const char* SettingsLongNames[12] = "Temperature when in \"boost\" mode", "Automatically starts the iron into soldering on power up. T=Soldering, S= Sleep mode,F=Off", "Blink the temperature on the cooling screen while the tip is still hot.", + "Calibrate tip offset.", "Reset all settings", }; -const char* SettingsShortNames[12] = { +const char* SettingsShortNames[13] = { "PWRSC ", "STMP ", "STME ", @@ -41,6 +42,9 @@ const char* SettingsShortNames[12] = { "BTMP ", "ASTART ", "CLBLNK ", + "TMP CAL?", "RESET? " }; +const char* SettingsCalibrationWarning = "Please ensure the tip is at room temperature before continuing!"; + #endif diff --git a/workspace/TS100/src/gui.cpp b/workspace/TS100/src/gui.cpp index 23135df8..5b1d3f4e 100644 --- a/workspace/TS100/src/gui.cpp +++ b/workspace/TS100/src/gui.cpp @@ -6,7 +6,9 @@ */ #include "gui.h" - +#include "string.h" +#include "hardware.h" +#include "cmsis_os.h" static void settings_setInputVRange(void); static void settings_displayInputVRange(void); static void settings_setSleepTemp(void); @@ -31,10 +33,10 @@ static void settings_setCoolingBlinkEnabled(void); static void settings_displayCoolingBlinkEnabled(void); static void settings_setResetSettings(void); static void settings_displayResetSettings(void); +static void settings_setCalibrate(void); +static void settings_displayCalibrate(void); - - -bool settingsResetRequest=false; +bool settingsResetRequest = false; const menuitem settingsMenu[] = { /*Struct used for all settings options in the settings menu*/ { (const char*) SettingsLongNames[0], { settings_setInputVRange }, { settings_displayInputVRange } },/*Voltage input*/ { (const char*) SettingsLongNames[1], { settings_setSleepTemp }, { settings_displaySleepTemp } }, /*Sleep Temp*/ @@ -47,12 +49,11 @@ const menuitem settingsMenu[] = { /*Struct used for all settings options in the { (const char*) SettingsLongNames[8], { settings_setBoostTemp }, { settings_displayBoostTemp } }, /**/ { (const char*) SettingsLongNames[9], { settings_setAutomaticStartMode }, { settings_displayAutomaticStartMode } },/**/ { (const char*) SettingsLongNames[10], { settings_setCoolingBlinkEnabled }, { settings_displayCoolingBlinkEnabled } }, /**/ -{ (const char*) SettingsLongNames[11], { settings_setResetSettings }, { settings_displayResetSettings } }, /**/ +{ (const char*) SettingsLongNames[11], { settings_setCalibrate }, { settings_displayCalibrate } }, /**/ +{ (const char*) SettingsLongNames[12], { settings_setResetSettings }, { settings_displayResetSettings } }, /**/ { NULL, { NULL }, { NULL } } //end of menu marker. DO NOT REMOVE }; - - static void settings_setInputVRange(void) { systemSettings.cutoutSetting = (systemSettings.cutoutSetting + 1) % 5; } @@ -188,9 +189,64 @@ static void settings_setResetSettings(void) { settingsResetRequest = !settingsResetRequest; } static void settings_displayResetSettings(void) { - lcd.print(SettingsShortNames[11]); + lcd.print(SettingsShortNames[12]); if (settingsResetRequest) lcd.drawChar('T'); else lcd.drawChar('F'); } + +static void settings_setCalibrate(void) { + //Calibrate the offset + //We split off here to confirm with the user + uint8_t maxOffset = strlen(SettingsCalibrationWarning); + uint32_t descriptionStart = HAL_GetTick(); + lcd.setFont(0); + for (;;) { + + int16_t descriptionOffset = ((HAL_GetTick() - descriptionStart) / 150) % maxOffset; + lcd.setCursor(12 * (7 - descriptionOffset), 0); + lcd.print(SettingsCalibrationWarning); + ButtonState buttons = getButtonState(); + + switch (buttons) { + case BUTTON_F_SHORT: { + //User confirmed + //So we now perform the actual calculation + lcd.clearScreen(); + lcd.print("....."); + lcd.refresh(); + setCalibrationOffset(0); //turn off the current offset + for (uint8_t i = 0; i < 20; i++) { + getTipRawTemp(1); //cycle through the filter a fair bit to ensure were stable. + osDelay(20); + } + osDelay(100); + uint16_t rawTempC = tipMeasurementToC(getTipRawTemp(0)); + //We now measure the current reported tip temperature + uint16_t handleTempC = getHandleTemperature() / 10; + //We now have an error between these that we want to store as the offset + rawTempC = rawTempC - handleTempC; + systemSettings.CalibrationOffset = rawTempC; + setCalibrationOffset(rawTempC); //store the error + osDelay(100); + return; + } + break; + case BUTTON_BOTH: + case BUTTON_B_SHORT: + case BUTTON_F_LONG: + case BUTTON_B_LONG: + return; + break; + case BUTTON_NONE: + break; + } + lcd.refresh(); + osDelay(50); + } + +} +static void settings_displayCalibrate(void) { + lcd.print(SettingsShortNames[11]); +} diff --git a/workspace/TS100/src/hardware.c b/workspace/TS100/src/hardware.c index c237d22d..e504eac0 100644 --- a/workspace/TS100/src/hardware.c +++ b/workspace/TS100/src/hardware.c @@ -9,7 +9,11 @@ #include "hardware.h" volatile uint16_t PWMSafetyTimer = 0; - +volatile int16_t CalibrationTempOffset = 0; +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 example) @@ -27,11 +31,12 @@ uint16_t getHandleTemperature() { } uint16_t tipMeasurementToC(uint16_t raw) { - return (raw / 33) - 16; + return ((raw-532) / 33) + (getHandleTemperature()/10) - CalibrationTempOffset; //Surprisingly that appears to be a fairly good linear best fit } uint16_t ctoTipMeasurement(uint16_t temp) { - return (temp + 16) * 33; + //We need to compensate for cold junction temp + return ((temp-(getHandleTemperature()/10) + CalibrationTempOffset) * 33)+532; } uint16_t getTipInstantTemperature() { uint16_t sum = 0; diff --git a/workspace/TS100/src/main.cpp b/workspace/TS100/src/main.cpp index ed7ab0a9..60f0f51f 100644 --- a/workspace/TS100/src/main.cpp +++ b/workspace/TS100/src/main.cpp @@ -51,8 +51,9 @@ int main(void) { HAL_IWDG_Refresh(&hiwdg); HAL_Delay(500); restoreSettings(); //load the settings from flash - showBootLogoIfavailable(); + showBootLogoIfavailable(); + setCalibrationOffset(systemSettings.CalibrationOffset); HAL_IWDG_Refresh(&hiwdg); /* Create the thread(s) */ /* definition and creation of GUITask */ @@ -80,20 +81,7 @@ int main(void) { while (1) { } } -enum ButtonState { - BUTTON_NONE = 0, /* No buttons pressed / < filter time*/ - BUTTON_F_SHORT = 1, /* User has pressed the front button*/ - BUTTON_B_SHORT = 2, /* User has pressed the back button*/ - BUTTON_F_LONG = 4, /* User is holding the front button*/ - BUTTON_B_LONG = 8, /* User is holding the back button*/ - BUTTON_BOTH = 16, /* User has pressed both buttons*/ -/* - * Note: - * Pressed means press + release, we trigger on a full \__/ pulse - * holding means it has gone low, and been low for longer than filter time - */ -}; ButtonState getButtonState() { /* * Read in the buttons and then determine if a state change needs to occur @@ -316,8 +304,7 @@ static void gui_settingsMenu() { } if (settingsResetRequest) resetSettings(); - else - saveSettings(); + saveSettings(); } static void gui_showTipTempWarning() { for (;;) { @@ -582,6 +569,8 @@ void startGUITask(void const * argument) { lcd.setFont(0); lcd.displayOnOff(true); //turn lcd on gui_settingsMenu(); //enter the settings menu + saveSettings(); + setCalibrationOffset(systemSettings.CalibrationOffset); HAL_IWDG_Refresh(&hiwdg); osDelay(500); //tempWarningState=0;//make sure warning can show