diff --git a/.gitignore b/.gitignore index 6c8904c1..3130b067 100644 --- a/.gitignore +++ b/.gitignore @@ -58,3 +58,6 @@ workspace/TS100/src/Translation.cpp *.list workspace/TS100/Release/ workspace/TS100/Hexfile/ +workspace/RemoteSystemsTempFiles/ +workspace/TS100/.settings/ +workspace/TS100/TS80/ diff --git a/Translation Editor/make_translation.py b/Translation Editor/make_translation.py index 803dfb1f..21d2a7e9 100755 --- a/Translation Editor/make_translation.py +++ b/Translation Editor/make_translation.py @@ -121,7 +121,7 @@ def getDebugMenu(): constants.append(datetime.today().strftime('%d-%m-%y')) constants.append("HW G ") constants.append("HW M ") - constants.append("HW P ") + constants.append("HW P ") constants.append("Time ") constants.append("Move ") constants.append("RTip ") @@ -176,7 +176,6 @@ def getLetterCounts(defs, lang): constants = getConstants() for x in constants: textList.append(x[1]) - textList.extend(getDebugMenuHeaders()) textList.extend(getTipModelEnumTS100()) textList.extend(getTipModelEnumTS80()) textList.extend(getDebugMenu()) diff --git a/workspace/TS100/.cproject b/workspace/TS100/.cproject index cf57f62e..a9d9f96a 100644 --- a/workspace/TS100/.cproject +++ b/workspace/TS100/.cproject @@ -1,152 +1,280 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 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/Settings.h b/workspace/TS100/Core/Inc/Settings.h index 5e883651..dd918168 100644 --- a/workspace/TS100/Core/Inc/Settings.h +++ b/workspace/TS100/Core/Inc/Settings.h @@ -11,7 +11,7 @@ #define SETTINGS_H_ #include #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,18 +39,13 @@ 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 - // in the iron. - uint8_t PID_P; // PID P Term - uint8_t PID_I; // PID I Term - uint8_t PID_D; // PID D Term - uint8_t version; // Used to track if a reset is needed on firmware upgrade + uint16_t CalibrationOffset; // This stores the temperature offset for this tip + // in the iron. + 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 + 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/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/main.hpp b/workspace/TS100/Core/Inc/main.hpp index 2474fe60..78b6cc70 100644 --- a/workspace/TS100/Core/Inc/main.hpp +++ b/workspace/TS100/Core/Inc/main.hpp @@ -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*/ diff --git a/workspace/TS100/Core/Inc/power.hpp b/workspace/TS100/Core/Inc/power.hpp index 1850cd14..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,22 +19,21 @@ // Once we have feed-forward temp estimation we should be able to better tune this. #ifdef MODEL_TS100 -const uint16_t tipMass = 450; // 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 uint16_t tipMass = 450; +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 = 6 * PID_TIM_HZ; // I term look back value -extern history milliWattHistory; - -int32_t tempToMilliWatts(int32_t rawTemp, uint8_t rawC); -void setTipMilliWatts(int32_t mw); -uint8_t milliWattsToPWM(int32_t milliWatts, uint8_t divisor, - uint8_t sample = 0); -int32_t PWMToMilliWatts(uint8_t pwm, uint8_t divisor, uint8_t sample = 0); +const uint8_t wattHistoryFilter = 24; // I term look back weighting +extern expMovingAverage x10WattHistory; +int32_t tempToX10Watts(int32_t rawTemp); +void setTipX10Watts(int32_t mw); +uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample = 0); +int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample = 0); +uint32_t availableW10(uint8_t sample) ; #endif /* POWER_HPP_ */ diff --git a/workspace/TS100/Core/Src/GUIThread.cpp b/workspace/TS100/Core/Src/GUIThread.cpp index 8d93716f..7e7a4f1e 100644 --- a/workspace/TS100/Core/Src/GUIThread.cpp +++ b/workspace/TS100/Core/Src/GUIThread.cpp @@ -16,9 +16,10 @@ #include "stdlib.h" #include "stm32f1xx_hal.h" #include "string.h" +#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; @@ -53,12 +54,12 @@ void GUIDelay() { } void gui_drawTipTemp(bool symbol) { // Draw tip temp handling unit conversion & tolerance near setpoint - uint16_t Temp = getTipRawTemp(0); + uint16_t Temp = 0; if (systemSettings.temperatureInF) - Temp = tipMeasurementToF(Temp); + Temp = TipThermoModel::getTipInF(); else - Temp = tipMeasurementToC(Temp); + Temp = TipThermoModel::getTipInC(); OLED::printNumber(Temp, 3); // Draw the tip temp out finally if (symbol) { @@ -200,7 +201,7 @@ static bool checkVoltageForExit() { } OLED::refresh(); - currentlyActiveTemperatureTarget = 0; + currentTempTargetDegC = 0; waitForButtonPress(); return true; } @@ -215,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 @@ -249,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 (;;) { @@ -316,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 @@ -332,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 @@ -353,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::getTipInF(); else - tipTemp = tipMeasurementToC(getTipRawTemp(0)); + tipTemp = TipThermoModel::getTipInC(); OLED::clearScreen(); OLED::setCursor(0, 0); @@ -402,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(); @@ -494,7 +494,7 @@ static void gui_solderingMode(uint8_t jumpToSleep) { OLED::setFont(0); uint16_t tipTemp = getTipRawTemp(0); if (tipTemp > 32700) { - badTipCounter++; // Use a counter so that error has to persist for > 1 second continious so that peak errors dont trip it + badTipCounter++; // Use a counter so that error has to persist for > 1 second continuous so that peak errors dont trip it } else { badTipCounter = 0; } @@ -502,9 +502,9 @@ static void gui_solderingMode(uint8_t jumpToSleep) { if (systemSettings.detailedSoldering) { OLED::setFont(1); OLED::print(SolderingAdvancedPowerPrompt); // Power: - OLED::printNumber(milliWattHistory[0] / 1000, 2); + OLED::printNumber(x10WattHistory.average() / 10, 2); OLED::print(SymbolDot); - OLED::printNumber(milliWattHistory[0] / 100 % 10, 1); + OLED::printNumber(x10WattHistory.average()% 10, 1); OLED::print(SymbolWatts); if (systemSettings.sensitivity && systemSettings.SleepTime) { @@ -514,6 +514,9 @@ static void gui_solderingMode(uint8_t jumpToSleep) { OLED::setCursor(0, 8); OLED::print(SleepingTipAdvancedString); + //OLED::printNumber( + // TipThermoModel::convertTipRawADCTouV(getTipRawTemp(0)), 5); // Draw the tip temp out finally + gui_drawTipTemp(true); OLED::print(SymbolSpace); printVoltage(); @@ -535,14 +538,10 @@ static void gui_solderingMode(uint8_t jumpToSleep) { OLED::print(SymbolSpace); // Draw heating/cooling symbols - OLED::drawHeatSymbol( - milliWattsToPWM(milliWattHistory[0], - systemSettings.voltageDiv)); + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); } else { // Draw heating/cooling symbols - OLED::drawHeatSymbol( - milliWattsToPWM(milliWattHistory[0], - systemSettings.voltageDiv)); + OLED::drawHeatSymbol(X10WattsToPWM(x10WattHistory.average())); // We draw boost arrow if boosting, or else gap temp <-> heat // indicator if (boostModeOn) @@ -560,9 +559,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(); @@ -570,19 +569,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 @@ -647,11 +644,17 @@ void showDebugMenu(void) { break; case 6: //Raw Tip - OLED::printNumber(getTipRawTemp(0), 6); + { + uint32_t temp = systemSettings.CalibrationOffset; + systemSettings.CalibrationOffset = 0; + OLED::printNumber( + TipThermoModel::convertTipRawADCTouV(getTipRawTemp(1)), 6); + systemSettings.CalibrationOffset = temp; + } break; case 7: //Temp in C - OLED::printNumber(tipMeasurementToC(getTipRawTemp(0)), 5); + OLED::printNumber(TipThermoModel::getTipInC(1), 5); break; case 8: //Handle Temp @@ -707,7 +710,7 @@ void startGUITask(void const *argument __unused) { gui_solderingMode(1); } -#if ACCELDEBUG +#ifdef ACCELDEBUG for (;;) { HAL_IWDG_Refresh(&hiwdg); @@ -755,15 +758,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::getTipInC(); // Preemptively turn the display on. Turn it off if and only if // the tip temperature is below 50 degrees C *and* motion sleep @@ -771,9 +773,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); } @@ -800,7 +804,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); @@ -821,7 +825,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 diff --git a/workspace/TS100/Core/Src/Settings.cpp b/workspace/TS100/Core/Src/Settings.cpp index bd355b47..02140333 100644 --- a/workspace/TS100/Core/Src/Settings.cpp +++ b/workspace/TS100/Core/Src/Settings.cpp @@ -97,25 +97,23 @@ 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 = 0; // Blink the temperature on the cooling screen when its > 50C systemSettings.temperatureInF = 0; // default to 0 systemSettings.descriptionScrollSpeed = 0; // default to slow - 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 = 850; // the adc offset in uV + systemSettings.pidPowerLimit=70; // Sets the max pwm power limit + #endif #ifdef MODEL_TS80 systemSettings.pidPowerLimit=24; // Sets the max pwm power limit - systemSettings.tipType = TS_B02; // Default to the B2 Tip + + systemSettings.CalibrationOffset = 300; // the adc offset in uV #endif saveSettings(); // Save defaults } diff --git a/workspace/TS100/Core/Src/Setup.c b/workspace/TS100/Core/Src/Setup.c index 12858395..88aa1a3c 100644 --- a/workspace/TS100/Core/Src/Setup.c +++ b/workspace/TS100/Core/Src/Setup.c @@ -136,7 +136,7 @@ static void MX_ADC1_Init(void) { */ sConfig.Channel = TMP36_ADC1_CHANNEL; sConfig.Rank = 1; - sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; + sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; HAL_ADC_ConfigChannel(&hadc1, &sConfig); /**Configure Regular Channel @@ -197,11 +197,10 @@ static void MX_ADC2_Init(void) { */ sConfig.Channel = TIP_TEMP_ADC2_CHANNEL; sConfig.Rank = ADC_REGULAR_RANK_1; - sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; + sConfig.SamplingTime = ADC_SAMPLETIME_71CYCLES_5; HAL_ADC_ConfigChannel(&hadc2, &sConfig); sConfig.Channel = VIN_ADC2_CHANNEL; sConfig.Rank = ADC_REGULAR_RANK_2; - sConfig.SamplingTime = ADC_SAMPLETIME_239CYCLES_5; HAL_ADC_ConfigChannel(&hadc2, &sConfig); /**Configure Injected Channel diff --git a/workspace/TS100/Core/Src/TipThermoModel.cpp b/workspace/TS100/Core/Src/TipThermoModel.cpp new file mode 100644 index 00000000..3c6b0d64 --- /dev/null +++ b/workspace/TS100/Core/Src/TipThermoModel.cpp @@ -0,0 +1,121 @@ +/* + * TipThermoModel.cpp + * + * Created on: 7 Oct 2019 + * Author: ralim + */ + +#include "TipThermoModel.h" +#include "Settings.h" +#include "hardware.h" + +/* + * The hardware is laid out as a non-inverting op-amp + * There is a pullup of 39k(TS100) from the +ve input to 3.9V (1M pulup on TS100) + * + * The simplest case to model this, is to ignore the pullup resistors influence, and assume that its influence is mostly constant + * -> Tip resistance *does* change with temp, but this should be much less than the rest of the system. + * + * When a thermocouple is equal temperature at both sides (hot and cold junction), then the output should be 0uV + * Therefore, by measuring the uV when both are equal, the measured reading is the offset value. + * This is a mix of the pull-up resistor, combined with tip manufacturing differences. + * + * All of the thermocouple readings are based on this expired patent + * - > https://patents.google.com/patent/US6087631A/en + * + * This was bought to my attention by + */ + +// TIP_GAIN = TIP_GAIN/1000 == uV per deg C constant of the tip +#ifdef MODEL_TS100 +#define OP_AMP_Rf 750*1000 /*750 Kilo-ohms -> From schematic, R1*/ +#define OP_AMP_Rin 2370 /*2.37 Kilo-ohms -> From schematic, R2*/ +#define TIP_GAIN 405 +#else +#define OP_AMP_Rf 180*1000 /*180 Kilo-ohms -> From schematic, R6*/ +#define OP_AMP_Rin 2000 /*2.0 Kilo-ohms -> From schematic, R3*/ +#define TIP_GAIN 115 + +#endif + +#define op_amp_gain_stage (1+(OP_AMP_Rf/OP_AMP_Rin)) +uint32_t TipThermoModel::convertTipRawADCTouV(uint16_t rawADC) { + // This takes the raw ADC samples, converts these to uV + // Then divides this down by the gain to convert to the uV on the input to the op-amp (A+B terminals) + // Then remove the calibration value that is stored as a tip offset + uint32_t vddRailmVX10 = 33000; //TODO use ADC Vref to calculate this + // 4096 * 8 readings for full scale + // Convert the input ADC reading back into mV times 10 format. + uint32_t rawInputmVX10 = (rawADC * vddRailmVX10) / (4096 * 8); + + uint32_t valueuV = rawInputmVX10 * 100; // shift into uV + //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; + + return valueuV; +} + +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 + +//Extrapolate between two points +// [x1, y1] = point 1 +// [x2, y2] = point 2 +// x = input value +// output is x's extrapolated y value +int32_t LinearInterpolate(int32_t x1, int32_t y1, int32_t x2, int32_t y2, + int32_t x) { + return y1 + (((((x - x1) * 1000) / (x2 - x1)) * (y2 - y1))) / 1000; +} + +uint32_t TipThermoModel::convertuVToDegC(uint32_t tipuVDelta) { + //based on new measurements, tip is quite linear at 24.9uV per deg C = 2.49 per 0.1C + // + tipuVDelta *= TIP_GAIN; + tipuVDelta /= 10000; + return tipuVDelta; +} + +uint32_t TipThermoModel::convertuVToDegF(uint32_t tipuVDelta) { + tipuVDelta *= TIP_GAIN; + tipuVDelta /= 1000; + return ((tipuVDelta * 9) / 50) + 32; + //(Y °C × 9/5) + 32 =Y°F +} + +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; +} + +uint32_t TipThermoModel::getTipInC(bool sampleNow) { + uint32_t currentTipTempInC = TipThermoModel::convertTipRawADCToDegC( + getTipRawTemp(sampleNow)); + currentTipTempInC += getHandleTemperature() / 10; //Add handle offset + return currentTipTempInC; +} + +uint32_t TipThermoModel::getTipInF(bool sampleNow) { + uint32_t currentTipTempInF = TipThermoModel::convertTipRawADCToDegF( + getTipRawTemp(sampleNow)); + currentTipTempInF += convertCtoF(getHandleTemperature() / 10); //Add handle offset + return currentTipTempInF; +} diff --git a/workspace/TS100/Core/Src/TipThermoModel.h b/workspace/TS100/Core/Src/TipThermoModel.h new file mode 100644 index 00000000..88b0782d --- /dev/null +++ b/workspace/TS100/Core/Src/TipThermoModel.h @@ -0,0 +1,31 @@ +/* + * TipThermoModel.h + * + * Created on: 7 Oct 2019 + * Author: ralim + */ + +#ifndef SRC_TIPTHERMOMODEL_H_ +#define SRC_TIPTHERMOMODEL_H_ +#include "stdint.h" +#include "hardware.h" +class TipThermoModel { +public: + //These are the main two functions + static uint32_t getTipInC(bool sampleNow=false); + static uint32_t getTipInF(bool sampleNow=false); + + + 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 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_ */ diff --git a/workspace/TS100/Core/Src/Translation.cpp b/workspace/TS100/Core/Src/Translation.cpp index f566e5af..9adb6dcc 100644 --- a/workspace/TS100/Core/Src/Translation.cpp +++ b/workspace/TS100/Core/Src/Translation.cpp @@ -238,7 +238,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x3B\x02\x0A\x3B\x03\x0B",//19-08-19 + "\x04\x05\x3B\x03\x04\x3B\x03\x0B",//23-12-19 "\x2A\x31\x0D\x40\x0D",//HW G "\x2A\x31\x0D\x2C\x0D",//HW M "\x2A\x31\x0D\x26\x0D",//HW P @@ -617,7 +617,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x5E\x02\x0A\x5E\x03\x0B",//19-08-19 + "\x04\x05\x5E\x03\x04\x5E\x03\x0B",//23-12-19 "\x43\x42\x0C\x68\x0C",//HW G "\x43\x42\x0C\x4A\x0C",//HW M "\x43\x42\x0C\x52\x0C",//HW P @@ -936,7 +936,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x47\x02\x0A\x47\x03\x0B",//19-08-19 + "\x04\x05\x47\x03\x04\x47\x03\x0B",//23-12-19 "\x2A\x36\x0C\x4E\x0C",//HW G "\x2A\x36\x0C\x31\x0C",//HW M "\x2A\x36\x0C\x21\x0C",//HW P @@ -1227,7 +1227,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x3E\x02\x0A\x3E\x03\x0B",//19-08-19 + "\x04\x05\x3E\x03\x04\x3E\x03\x0B",//23-12-19 "\x28\x2F\x0C\x43\x0C",//HW G "\x28\x2F\x0C\x23\x0C",//HW M "\x28\x2F\x0C\x25\x0C",//HW P @@ -1526,7 +1526,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x25\x02\x0A\x25\x03\x0B",//19-08-19 + "\x04\x05\x25\x03\x04\x25\x03\x0B",//23-12-19 "\x37\x3A\x0E\x46\x0E",//HW G "\x37\x3A\x0E\x34\x0E",//HW M "\x37\x3A\x0E\x45\x0E",//HW P @@ -1831,7 +1831,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x3E\x02\x0A\x3E\x03\x0B",//19-08-19 + "\x04\x05\x3E\x03\x04\x3E\x03\x0B",//23-12-19 "\x37\x36\x0C\x43\x0C",//HW G "\x37\x36\x0C\x23\x0C",//HW M "\x37\x36\x0C\x24\x0C",//HW P @@ -2126,7 +2126,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x2E\x02\x0A\x2E\x03\x0B",//19-08-19 + "\x04\x05\x2E\x03\x04\x2E\x03\x0B",//23-12-19 "\x2A\x2F\x10\x43\x10",//HW G "\x2A\x2F\x10\x36\x10",//HW M "\x2A\x2F\x10\x31\x10",//HW P @@ -2419,7 +2419,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x36\x02\x0A\x36\x03\x0B",//19-08-19 + "\x04\x05\x36\x03\x04\x36\x03\x0B",//23-12-19 "\x2C\x3D\x0D\x3A\x0D",//HW G "\x2C\x3D\x0D\x32\x0D",//HW M "\x2C\x3D\x0D\x23\x0D",//HW P @@ -2718,7 +2718,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x3F\x02\x0A\x3F\x03\x0B",//19-08-19 + "\x04\x05\x3F\x03\x04\x3F\x03\x0B",//23-12-19 "\x37\x3D\x0D\x46\x0D",//HW G "\x37\x3D\x0D\x39\x0D",//HW M "\x37\x3D\x0D\x23\x0D",//HW P @@ -3035,7 +3035,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x4A\x02\x0A\x4A\x03\x0B",//19-08-19 + "\x04\x05\x4A\x03\x04\x4A\x03\x0B",//23-12-19 "\x1D\x44\x0C\x32\x0C",//HW G "\x1D\x44\x0C\x36\x0C",//HW M "\x1D\x44\x0C\x4C\x0C",//HW P @@ -3330,7 +3330,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x3D\x02\x0A\x3D\x03\x0B",//19-08-19 + "\x04\x05\x3D\x03\x04\x3D\x03\x0B",//23-12-19 "\x35\x38\x0C\x44\x0C",//HW G "\x35\x38\x0C\x27\x0C",//HW M "\x35\x38\x0C\x30\x0C",//HW P @@ -3637,7 +3637,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x26\x02\x0A\x26\x03\x0B",//19-08-19 + "\x04\x05\x26\x03\x04\x26\x03\x0B",//23-12-19 "\x3A\x3C\x0E\x2C\x0E",//HW G "\x3A\x3C\x0E\x24\x0E",//HW M "\x3A\x3C\x0E\x3B\x0E",//HW P @@ -3922,7 +3922,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x25\x02\x0A\x25\x03\x0B",//19-08-19 + "\x04\x05\x25\x03\x04\x25\x03\x0B",//23-12-19 "\x2E\x35\x0D\x2A\x0D",//HW G "\x2E\x35\x0D\x2F\x0D",//HW M "\x2E\x35\x0D\x2D\x0D",//HW P @@ -4209,7 +4209,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x26\x02\x0A\x26\x03\x0B",//19-08-19 + "\x04\x05\x26\x03\x04\x26\x03\x0B",//23-12-19 "\x2F\x35\x0E\x24\x0E",//HW G "\x2F\x35\x0E\x33\x0E",//HW M "\x2F\x35\x0E\x28\x0E",//HW P @@ -4494,7 +4494,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x2F\x02\x0A\x2F\x03\x0B",//19-08-19 + "\x04\x05\x2F\x03\x04\x2F\x03\x0B",//23-12-19 "\x26\x33\x0C\x42\x0C",//HW G "\x26\x33\x0C\x2A\x0C",//HW M "\x26\x33\x0C\x2D\x0C",//HW P @@ -4809,7 +4809,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x49\x02\x0A\x49\x03\x0B",//19-08-19 + "\x04\x05\x49\x03\x04\x49\x03\x0B",//23-12-19 "\x3C\x27\x0C\x3D\x0C",//HW G "\x3C\x27\x0C\x2A\x0C",//HW M "\x3C\x27\x0C\x23\x0C",//HW P @@ -5114,7 +5114,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x3E\x02\x0A\x3E\x03\x0B",//19-08-19 + "\x04\x05\x3E\x03\x04\x3E\x03\x0B",//23-12-19 "\x35\x36\x0D\x41\x0D",//HW G "\x35\x36\x0D\x21\x0D",//HW M "\x35\x36\x0D\x24\x0D",//HW P @@ -5485,7 +5485,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x25\x02\x0A\x25\x03\x0B",//19-08-19 + "\x04\x05\x25\x03\x04\x25\x03\x0B",//23-12-19 "\x3A\x36\x0C\x5C\x0C",//HW G "\x3A\x36\x0C\x4D\x0C",//HW M "\x3A\x36\x0C\x47\x0C",//HW P @@ -5778,7 +5778,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x42\x02\x0A\x42\x03\x0B",//19-08-19 + "\x04\x05\x42\x03\x04\x42\x03\x0B",//23-12-19 "\x32\x35\x0C\x45\x0C",//HW G "\x32\x35\x0C\x25\x0C",//HW M "\x32\x35\x0C\x21\x0C",//HW P @@ -6067,7 +6067,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x40\x02\x0A\x40\x03\x0B",//19-08-19 + "\x04\x05\x40\x03\x04\x40\x03\x0B",//23-12-19 "\x2B\x39\x0D\x46\x0D",//HW G "\x2B\x39\x0D\x32\x0D",//HW M "\x2B\x39\x0D\x2C\x0D",//HW P @@ -6424,7 +6424,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x4B\x02\x0A\x4B\x03\x0B",//19-08-19 + "\x04\x05\x4B\x03\x04\x4B\x03\x0B",//23-12-19 "\x3B\x46\x0D\x57\x0D",//HW G "\x3B\x46\x0D\x43\x0D",//HW M "\x3B\x46\x0D\x54\x0D",//HW P @@ -6725,7 +6725,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x44\x02\x0A\x44\x03\x0B",//19-08-19 + "\x04\x05\x44\x03\x04\x44\x03\x0B",//23-12-19 "\x35\x3F\x0D\x45\x0D",//HW G "\x35\x3F\x0D\x38\x0D",//HW M "\x35\x3F\x0D\x23\x0D",//HW P @@ -7024,7 +7024,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x22\x02\x0A\x22\x03\x0B",//19-08-19 + "\x04\x05\x22\x03\x04\x22\x03\x0B",//23-12-19 "\x29\x34\x0C\x3E\x0C",//HW G "\x29\x34\x0C\x2B\x0C",//HW M "\x29\x34\x0C\x2C\x0C",//HW P @@ -7331,7 +7331,7 @@ const char* TipModelStrings[] = { }; const char* DebugMenu[] = { - "\x03\x0B\x46\x02\x0A\x46\x03\x0B",//19-08-19 + "\x04\x05\x46\x03\x04\x46\x03\x0B",//23-12-19 "\x38\x37\x0C\x34\x0C",//HW G "\x38\x37\x0C\x25\x0C",//HW M "\x38\x37\x0C\x2C\x0C",//HW P @@ -7401,112 +7401,103 @@ const uint8_t USER_FONT_12[] = { 0x00,0x00,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1E,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//\x0D -> а 0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,//\x0E -> н 0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//\x0F -> о -0x00,0xF0,0xF0,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,//\x10 -> и -0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,//\x11 -> е -0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,//\x12 -> р +0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x70,0xE0,0xC0,0x00,0x00,0xFF,0xFF,0x0C,0x0C,0x0C,0x0C,0x0C,0x0E,0x07,0x03,0x00,//\x10 -> р +0x00,0xF0,0xF0,0x00,0x00,0x00,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,//\x11 -> и +0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x33,0x00,//\x12 -> е 0x00,0x30,0x30,0x30,0x30,0xF0,0xF0,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//\x13 -> т 0x00,0x30,0xF0,0xC0,0x00,0x00,0x00,0x00,0xC0,0xF0,0x30,0x00,0x00,0x60,0xE0,0xC3,0xE7,0x7C,0x3C,0x0F,0x03,0x00,0x00,0x00,//\x14 -> у 0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x00,0x3F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,//\x15 -> в 0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x16 -> л -0x00,0xF0,0xF0,0x80,0x80,0xC0,0xE0,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,//\x17 -> к -0x00,0x00,0x00,0x00,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x18 -> і -0x00,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x03,0x01,0x00,0x3F,0x3F,0x00,//\x19 -> м +0x00,0x00,0x00,0x00,0x30,0xF6,0xF6,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x17 -> і +0x00,0xF0,0xF0,0xE0,0xC0,0x80,0x80,0xC0,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x03,0x01,0x00,0x3F,0x3F,0x00,//\x18 -> м +0x00,0xF0,0xF0,0x80,0x80,0xC0,0xE0,0x70,0x30,0x10,0x00,0x00,0x00,0x3F,0x3F,0x03,0x03,0x07,0x0E,0x1C,0x38,0x30,0x20,0x00,//\x19 -> к 0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x1A -> п 0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x18,0x08,0x00,//\x1B -> с -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,//\x1C -> . -0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x21,0x33,0x3B,0x1E,0x0E,0x06,0x06,0x06,0x3F,0x3F,0x00,//\x1D -> я -0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x60,0x7F,0x3F,0x30,0x30,0x30,0x30,0x3F,0x7F,0x60,0x00,//\x1E -> д -0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,//\x1F -> e +0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x21,0x33,0x3B,0x1E,0x0E,0x06,0x06,0x06,0x3F,0x3F,0x00,//\x1C -> я +0x00,0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0xF0,0xF0,0x00,0x00,0x00,0x60,0x7F,0x3F,0x30,0x30,0x30,0x30,0x3F,0x7F,0x60,0x00,//\x1D -> д +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x38,0x38,0x38,0x00,0x00,0x00,0x00,0x00,//\x1E -> . +0x00,0x30,0xF0,0xC0,0x00,0xF0,0xF0,0x00,0xC0,0xF0,0x30,0x00,0x00,0x30,0x3C,0x0F,0x03,0x3F,0x3F,0x03,0x0F,0x3C,0x30,0x00,//\x1F -> ж 0x00,0x00,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,//\x20 -> - -0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x21 -> i -0x00,0x00,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//\x22 -> a -0x00,0x30,0xF0,0xC0,0x00,0xF0,0xF0,0x00,0xC0,0xF0,0x30,0x00,0x00,0x30,0x3C,0x0F,0x03,0x3F,0x3F,0x03,0x0F,0x3C,0x30,0x00,//\x23 -> ж -0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,//\x24 -> ч -0x00,0x60,0x60,0xFE,0xFE,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,//\x25 -> t -0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//\x26 -> o -0x00,0xF0,0xF0,0x00,0x04,0x08,0x88,0xC4,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,//\x27 -> й -0x00,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,//\x28 -> ь -0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,//\x29 -> C -0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x2A -> n -0x00,0x00,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x2B -> r -0x00,0xF0,0xF0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,//\x2C -> ш -0x00,0x60,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x18,0x38,0x30,0x33,0x33,0x33,0x33,0x33,0x3F,0x1D,0x00,//\x2D -> з -0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,//\x2E -> б -0x00,0x30,0x70,0xC0,0x80,0x00,0x00,0x80,0xC0,0x70,0x30,0x00,0x00,0x30,0x38,0x0C,0x07,0x03,0x03,0x07,0x0C,0x38,0x30,0x00,//\x2F -> х -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0xF8,0x78,0x00,0x00,0x00,0x00,0x00,//\x30 -> , -0x00,0x00,0x00,0x00,0x03,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x31 -> l -0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x0C,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,//\x32 -> p -0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,//\x33 -> А -0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//\x34 -> S -0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0xE0,0xC0,0xFF,0xFF,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,//\x35 -> d -0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//\x36 -> Т -0x00,0x00,0x03,0x07,0x0E,0x1C,0x38,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,//\x37 -> > -0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,//\x38 -> К -0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x39 -> П -0x00,0x07,0x3F,0xF8,0xC0,0x00,0x00,0xC0,0xF8,0x3F,0x07,0x00,0x00,0x00,0x00,0x01,0x0F,0x3E,0x3E,0x0F,0x01,0x00,0x00,0x00,//\x3A -> V -0x00,0x00,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,0x00,//\x3B -> < -0x00,0xF0,0xF0,0x00,0xE0,0xF0,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x3F,0x3F,0x03,0x1F,0x3F,0x30,0x30,0x30,0x3F,0x1F,0x00,//\x3C -> ю -0x00,0x03,0x0F,0xFC,0xE0,0xFF,0xFF,0xE0,0xFC,0x0F,0x03,0x00,0x00,0x38,0x3F,0x07,0x00,0x3F,0x3F,0x00,0x07,0x3F,0x38,0x00,//\x3D -> Ж -0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,//\x3E -> s -0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//\x3F -> T -0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x3F,0xFF,0xF0,0x00,//\x40 -> ц -0x00,0x00,0xF8,0xFE,0x0F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x70,0x7F,0x1F,0x18,0x18,0x18,0x18,0x1F,0x7F,0x70,0x00,//\x41 -> Д -0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x42 -> г -0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//\x43 -> B -0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x06,0x03,0x03,0x06,0x1C,0x3F,0x3F,0x00,//\x44 -> W -0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x45 -> H -0x00,0x00,0x00,0x1E,0x3F,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x46 -> ° -0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,//\x47 -> : -0x00,0x00,0x00,0x00,0x7C,0xFF,0xFF,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00,0x00,0x00,0x00,//\x48 -> ! -0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,//\x49 -> u -0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//\x4A -> b -0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x30,0x18,0x08,0x00,//\x4B -> c -0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,//\x4C -> M -0x00,0x7F,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x4D -> Ч -0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,//\x4E -> P -0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xE0,0xE0,0x00,0x00,0x07,0x1F,0x38,0x1C,0x0F,0x0F,0x1C,0x38,0x1F,0x07,0x00,//\x4F -> w -0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xE0,0x00,0x00,0x03,0xC7,0xCE,0xCC,0xCC,0xCC,0xCC,0xE6,0x7F,0x3F,0x00,//\x50 -> g -0x00,0xE0,0xC0,0xE0,0xE0,0xC0,0xC0,0xE0,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,//\x51 -> m -0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,//\x52 -> С -0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,//\x53 -> R -0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,//\x54 -> A -0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//\x55 -> В -0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x56 -> F -0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//\x57 -> D -0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,//\x58 -> Р -0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x59 -> Г -0x00,0xFF,0xFF,0xC0,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,//\x5A -> h -0x00,0x60,0xE0,0x80,0x00,0x00,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x01,0x07,0x1E,0x38,0x38,0x1E,0x07,0x01,0x00,0x00,//\x5B -> v -0x00,0x80,0xC0,0x60,0x60,0xF0,0xF0,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x30,0x30,0xFF,0xFF,0x30,0x30,0x1F,0x0F,0x00,//\x5C -> ф -0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0xFF,0xE0,//\x5D -> щ -0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x5E -> Н -0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x30,0x38,0x18,0x08,0x00,//\x5F -> є -0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//\x60 -> О -0x00,0x07,0x1F,0x7C,0xF0,0xC0,0xC0,0xF0,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,//\x61 -> У -0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,//\x62 -> U -0x00,0x00,0xFF,0xFF,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x07,0x0F,0x1C,0x38,0x30,0x00,0x00,//\x63 -> k -0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x64 -> І -0x00,0x00,0x80,0x80,0x80,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x0F,0x01,0x01,0x01,0x00,0x00,//\x65 -> + -0x00,0xF0,0xFC,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC7,0xC6,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,//\x66 -> G -0x00,0x00,0x00,0x01,0x01,0x07,0xFE,0xFC,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x38,0x1F,0x0F,0x03,0x00,0x00,0x00,//\x67 -> ) -0x00,0x00,0x00,0xF0,0xFC,0xFE,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x38,0x20,0x20,0x00,0x00,0x00,//\x68 -> ( -0x00,0x1C,0x1E,0x07,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x37,0x00,0x00,0x00,0x00,0x00,//\x69 -> ? -0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,//\x6A -> Ш -0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,//\x6B -> L -0x00,0xF8,0xFC,0x0E,0x06,0xFF,0xFF,0x06,0x0E,0xFC,0xF8,0x00,0x00,0x03,0x07,0x0E,0x0C,0x3F,0x3F,0x0C,0x0E,0x07,0x03,0x00,//\x6C -> Ф -0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x00,0x18,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,//\x6D -> / -0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//\x6E -> Y -0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,//\x6F -> K -0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//\x70 -> O -0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,//\x71 -> Е -0x00,0x7C,0xFE,0xC7,0x83,0x83,0x83,0x83,0x83,0xFF,0xFF,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x03,0x01,0x01,0x3F,0x3F,0x00,//\x72 -> Я -0x00,0xFF,0xFF,0x00,0x02,0xC3,0xF1,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x73 -> Й -0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,//\x74 -> М -0x00,0x00,0x00,0x04,0x34,0xF0,0xF4,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x75 -> ї -0x00,0xC0,0xC0,0xFC,0xFE,0xC7,0xC3,0xC3,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x76 -> f -0x00,0x00,0xF0,0xFC,0x1E,0x07,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x77 -> Л -0x00,0x60,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x18,0x38,0x30,0x33,0x33,0x33,0x33,0x33,0x3F,0x1D,0x00,//\x78 -> З -0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x1F,0x7F,0x78,0x00,//\x79 -> Ц +0x00,0xF0,0xF0,0x80,0x80,0x80,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x3F,0x3F,0x31,0x31,0x31,0x31,0x31,0x3B,0x1F,0x0E,0x00,//\x21 -> ь +0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x01,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x3F,0x3F,0x00,//\x22 -> ч +0x00,0xE0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x00,0x1F,0x3F,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,//\x23 -> б +0x00,0xF0,0xF0,0x00,0x04,0x08,0x88,0xC4,0xE0,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x1C,0x0E,0x07,0x03,0x01,0x00,0x3F,0x3F,0x00,//\x24 -> й +0x00,0x60,0x70,0x30,0x30,0x30,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x18,0x38,0x30,0x33,0x33,0x33,0x33,0x33,0x3F,0x1D,0x00,//\x25 -> з +0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x26 -> П +0x00,0xF0,0xF0,0x00,0x00,0xE0,0xE0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,//\x27 -> ш +0x00,0x30,0x70,0xC0,0x80,0x00,0x00,0x80,0xC0,0x70,0x30,0x00,0x00,0x30,0x38,0x0C,0x07,0x03,0x03,0x07,0x0C,0x38,0x30,0x00,//\x28 -> х +0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xB8,0xF8,0x78,0x00,0x00,0x00,0x00,0x00,//\x29 -> , +0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,//\x2A -> C +0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,//\x2B -> К +0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,//\x2C -> А +0x00,0xF0,0xF0,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x2D -> г +0x00,0x03,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//\x2E -> Т +0x00,0x03,0x0F,0xFC,0xE0,0xFF,0xFF,0xE0,0xFC,0x0F,0x03,0x00,0x00,0x38,0x3F,0x07,0x00,0x3F,0x3F,0x00,0x07,0x3F,0x38,0x00,//\x2F -> Ж +0x00,0xF0,0xF0,0x00,0x00,0x00,0x00,0x00,0xF0,0xF0,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x3F,0xFF,0xF0,0x00,//\x30 -> ц +0x00,0x00,0x03,0x07,0x0E,0x1C,0x38,0xF0,0xE0,0xC0,0x00,0x00,0x00,0x00,0x30,0x38,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,//\x31 -> > +0x00,0x3C,0x7E,0xE7,0xC3,0xC3,0xC3,0xC3,0xC7,0x8E,0x0C,0x00,0x00,0x0C,0x1C,0x38,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//\x32 -> S +0x00,0x07,0x3F,0xF8,0xC0,0x00,0x00,0xC0,0xF8,0x3F,0x07,0x00,0x00,0x00,0x00,0x01,0x0F,0x3E,0x3E,0x0F,0x01,0x00,0x00,0x00,//\x33 -> V +0x00,0x00,0xF8,0xFE,0x0F,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x00,0x70,0x7F,0x1F,0x18,0x18,0x18,0x18,0x1F,0x7F,0x70,0x00,//\x34 -> Д +0x00,0x00,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x00,0x00,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,0x00,//\x35 -> < +0x00,0xF0,0xF0,0x00,0xE0,0xF0,0x30,0x30,0x30,0xF0,0xE0,0x00,0x00,0x3F,0x3F,0x03,0x1F,0x3F,0x30,0x30,0x30,0x3F,0x1F,0x00,//\x36 -> ю +0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//\x37 -> В +0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x33,0x33,0x13,0x01,0x00,//\x38 -> e +0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xE7,0xFE,0xBC,0x00,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x39,0x1F,0x0F,0x00,//\x39 -> B +0x00,0x00,0x00,0x1E,0x3F,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x3A -> ° +0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x3B -> H +0x00,0x00,0x03,0x03,0x03,0xFF,0xFF,0x03,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//\x3C -> T +0x00,0x00,0x00,0x00,0x60,0xEC,0xEC,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x3D -> i +0x00,0x00,0x00,0x00,0x70,0x70,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x1C,0x1C,0x00,0x00,0x00,0x00,0x00,//\x3E -> : +0x00,0x00,0x00,0x00,0x7C,0xFF,0xFF,0x7C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x33,0x33,0x00,0x00,0x00,0x00,0x00,//\x3F -> ! +0x00,0x80,0xC0,0x60,0x60,0xF0,0xF0,0x60,0x60,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x30,0x30,0xFF,0xFF,0x30,0x30,0x1F,0x0F,0x00,//\x40 -> ф +0x00,0x7F,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x41 -> Ч +0x00,0xFF,0xFF,0x00,0x00,0x80,0x80,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x06,0x03,0x03,0x06,0x1C,0x3F,0x3F,0x00,//\x42 -> W +0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,//\x43 -> Р +0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x44 -> F +0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//\x45 -> D +0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,//\x46 -> M +0x00,0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x47 -> n +0x00,0x00,0x40,0x60,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x1C,0x3E,0x33,0x33,0x33,0x33,0x33,0x33,0x3F,0x3F,0x00,//\x48 -> a +0x00,0x00,0xE0,0xE0,0xC0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x49 -> r +0x00,0x80,0xC0,0xE0,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x0F,0x00,//\x4A -> o +0x00,0xC0,0xE0,0x60,0x60,0x60,0x60,0x60,0x40,0x00,0x00,0x00,0x00,0x11,0x33,0x33,0x33,0x33,0x33,0x3F,0x1E,0x00,0x00,0x00,//\x4B -> s +0x00,0xFF,0xFF,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x03,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,//\x4C -> Г +0x00,0x60,0x60,0xFE,0xFE,0x60,0x60,0x60,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1F,0x3F,0x30,0x30,0x30,0x30,0x00,0x00,0x00,//\x4D -> t +0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0xF0,0xF0,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0xFF,0xE0,//\x4E -> щ +0x00,0xFF,0xFF,0xC0,0xC0,0xC0,0xC0,0xC0,0xC0,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x4F -> Н +0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x03,0x07,0x0E,0x0C,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x38,0x1C,0x0C,0x00,//\x50 -> С +0x00,0x00,0xF0,0xFC,0x1E,0x07,0x03,0x03,0x03,0xFF,0xFF,0x00,0x00,0x30,0x3F,0x1F,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x51 -> Л +0x00,0xC0,0xE0,0x70,0x30,0x30,0x30,0x30,0x70,0x60,0x40,0x00,0x00,0x0F,0x1F,0x3B,0x33,0x33,0x33,0x30,0x38,0x18,0x08,0x00,//\x52 -> є +0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//\x53 -> О +0x00,0xE0,0xE0,0x60,0x60,0x60,0x60,0x60,0xE0,0xC0,0x80,0x00,0x00,0xFF,0xFF,0x0C,0x18,0x18,0x18,0x18,0x1C,0x0F,0x07,0x00,//\x54 -> p +0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x01,0x01,0x01,0x01,0x00,0x00,0x00,//\x55 -> P +0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x07,0x1F,0x38,0x30,0x30,0x30,0x30,0x38,0x1F,0x07,0x00,//\x56 -> U +0x00,0x00,0xFF,0xFF,0x00,0x80,0xC0,0xE0,0x60,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x03,0x07,0x0F,0x1C,0x38,0x30,0x00,0x00,//\x57 -> k +0x00,0x00,0x80,0x80,0x80,0xF0,0xF0,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x01,0x01,0x01,0x0F,0x0F,0x01,0x01,0x01,0x00,0x00,//\x58 -> + +0x00,0xF0,0xFC,0x0E,0x07,0x03,0xC3,0xC3,0xC3,0xC7,0xC6,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x30,0x30,0x3F,0x3F,0x00,//\x59 -> G +0x00,0xFF,0xFF,0x83,0x83,0x83,0x83,0x83,0xC7,0xFE,0x7C,0x00,0x00,0x3F,0x3F,0x01,0x01,0x03,0x07,0x0F,0x1D,0x38,0x30,0x00,//\x5A -> R +0x00,0x00,0x00,0x01,0x01,0x07,0xFE,0xFC,0xF0,0x00,0x00,0x00,0x00,0x00,0x00,0x20,0x20,0x38,0x1F,0x0F,0x03,0x00,0x00,0x00,//\x5B -> ) +0x00,0x00,0x00,0xF0,0xFC,0xFE,0x07,0x01,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x0F,0x1F,0x38,0x20,0x20,0x00,0x00,0x00,//\x5C -> ( +0x00,0xFF,0xFF,0x1E,0x78,0xE0,0xE0,0x78,0x1E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x00,0x00,0x01,0x01,0x00,0x00,0x3F,0x3F,0x00,//\x5D -> М +0x00,0x07,0x1F,0x7C,0xF0,0xC0,0xC0,0xF0,0x7C,0x1F,0x07,0x00,0x00,0x00,0x30,0x30,0x3C,0x0F,0x07,0x01,0x00,0x00,0x00,0x00,//\x5E -> У +0x00,0x1C,0x1E,0x07,0x03,0x83,0xC3,0xE3,0x77,0x3E,0x1C,0x00,0x00,0x00,0x00,0x00,0x00,0x37,0x37,0x00,0x00,0x00,0x00,0x00,//\x5F -> ? +0x00,0x00,0x00,0x04,0x34,0xF0,0xF4,0x04,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x60 -> ї +0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x30,0x30,0x3F,0x3F,0x00,//\x61 -> Ш +0x00,0x00,0x00,0xE0,0xFC,0x1F,0x1F,0xFC,0xE0,0x00,0x00,0x00,0x00,0x38,0x3F,0x07,0x06,0x06,0x06,0x06,0x07,0x3F,0x38,0x00,//\x62 -> A +0x00,0xF8,0xFC,0x0E,0x06,0xFF,0xFF,0x06,0x0E,0xFC,0xF8,0x00,0x00,0x03,0x07,0x0E,0x0C,0x3F,0x3F,0x0C,0x0E,0x07,0x03,0x00,//\x63 -> Ф +0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x30,0x3C,0x0F,0x03,0x00,0x00,0x03,0x0F,0x3C,0x30,0x00,//\x64 -> Х +0x00,0x00,0x00,0x00,0x00,0x80,0xC0,0xE0,0x70,0x38,0x1C,0x0E,0x00,0x18,0x1C,0x0E,0x07,0x03,0x01,0x00,0x00,0x00,0x00,0x00,//\x65 -> / +0x00,0x60,0xE0,0x80,0x00,0x00,0x00,0x00,0x80,0xE0,0x60,0x00,0x00,0x00,0x01,0x07,0x1E,0x38,0x38,0x1E,0x07,0x01,0x00,0x00,//\x66 -> v +0x00,0xE0,0xC0,0xE0,0xE0,0xC0,0xC0,0xE0,0xE0,0xC0,0x80,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,0x00,0x3F,0x3F,0x00,//\x67 -> m +0x00,0x00,0x00,0x03,0x03,0xFF,0xFF,0x03,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x30,0x3F,0x3F,0x30,0x30,0x00,0x00,0x00,//\x68 -> І +0x00,0xE0,0xE0,0x00,0x00,0x00,0x00,0x00,0x00,0xE0,0xE0,0x00,0x00,0x0F,0x1F,0x38,0x30,0x30,0x30,0x30,0x18,0x3F,0x3F,0x00,//\x69 -> u +0x00,0x03,0x0F,0x3C,0xF0,0xC0,0xC0,0xF0,0x3C,0x0F,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x3F,0x3F,0x00,0x00,0x00,0x00,0x00,//\x6A -> Y +0x00,0xFF,0xFF,0xC0,0xE0,0xF0,0x38,0x1C,0x0E,0x07,0x03,0x00,0x00,0x3F,0x3F,0x00,0x01,0x03,0x07,0x0E,0x1C,0x38,0x30,0x00,//\x6B -> K +0x00,0xF0,0xFC,0x0E,0x07,0x03,0x03,0x07,0x0E,0xFC,0xF0,0x00,0x00,0x03,0x0F,0x1C,0x38,0x30,0x30,0x38,0x1C,0x0F,0x03,0x00,//\x6C -> O +0x00,0xFF,0xFF,0xC3,0xC3,0xC3,0xC3,0xC3,0xC3,0x03,0x03,0x00,0x00,0x3F,0x3F,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x30,0x00,//\x6D -> Е +0x00,0x7C,0xFE,0xC7,0x83,0x83,0x83,0x83,0x83,0xFF,0xFF,0x00,0x00,0x30,0x38,0x1D,0x0F,0x07,0x03,0x01,0x01,0x3F,0x3F,0x00,//\x6E -> Я +0x00,0xFF,0xFF,0x00,0x02,0xC3,0xF1,0x38,0x0E,0xFF,0xFF,0x00,0x00,0x3F,0x3F,0x1C,0x07,0x03,0x00,0x00,0x00,0x3F,0x3F,0x00,//\x6F -> Й +0x00,0xFF,0xFF,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0x00,0x00,0x00,0x1F,0x1F,0x18,0x18,0x18,0x18,0x18,0x1F,0x7F,0x78,0x00,//\x70 -> Ц }; const uint8_t USER_FONT_6x8[] = { 0x3e, 0x51, 0x49, 0x45, 0x3e, 0x00,//\x02 -> 0 @@ -7523,249 +7514,240 @@ const uint8_t USER_FONT_6x8[] = { 0x20, 0x54, 0x54, 0x54, 0x78, 0x00,//\x0D -> а 0x7c, 0x10, 0x10, 0x10, 0x7c, 0x00,//\x0E -> н 0x38, 0x44, 0x44, 0x44, 0x38, 0x00,//\x0F -> о -0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00,//\x10 -> и -0x38, 0x54, 0x54, 0x54, 0x18, 0x00,//\x11 -> е -0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,//\x12 -> р +0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,//\x10 -> р +0x7c, 0x20, 0x10, 0x08, 0x7c, 0x00,//\x11 -> и +0x38, 0x54, 0x54, 0x54, 0x18, 0x00,//\x12 -> е 0x04, 0x04, 0x7c, 0x04, 0x04, 0x00,//\x13 -> т 0x4c, 0x50, 0x20, 0x10, 0x0c, 0x00,//\x14 -> у 0x7c, 0x54, 0x54, 0x54, 0x28, 0x00,//\x15 -> в 0x40, 0x3c, 0x04, 0x04, 0x7c, 0x00,//\x16 -> л -0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,//\x17 -> к -0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,//\x18 -> і -0x7c, 0x08, 0x10, 0x08, 0x7c, 0x00,//\x19 -> м +0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,//\x17 -> і +0x7c, 0x08, 0x10, 0x08, 0x7c, 0x00,//\x18 -> м +0x7c, 0x10, 0x28, 0x44, 0x00, 0x00,//\x19 -> к 0x7c, 0x04, 0x04, 0x04, 0x7c, 0x00,//\x1A -> п 0x38, 0x44, 0x44, 0x44, 0x20, 0x00,//\x1B -> с -0x00, 0x60, 0x60, 0x00, 0x00, 0x00,//\x1C -> . -0x48, 0x34, 0x14, 0x14, 0x7c, 0x00,//\x1D -> я -0x40, 0x3c, 0x24, 0x3c, 0x60, 0x00,//\x1E -> д -0x38, 0x54, 0x54, 0x54, 0x18, 0x00,//\x1F -> e +0x48, 0x34, 0x14, 0x14, 0x7c, 0x00,//\x1C -> я +0x40, 0x3c, 0x24, 0x3c, 0x60, 0x00,//\x1D -> д +0x00, 0x60, 0x60, 0x00, 0x00, 0x00,//\x1E -> . +0x6c, 0x10, 0x7c, 0x10, 0x6c, 0x00,//\x1F -> ж 0x08, 0x08, 0x08, 0x08, 0x08, 0x00,//\x20 -> - -0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,//\x21 -> i -0x20, 0x54, 0x54, 0x54, 0x78, 0x00,//\x22 -> a -0x6c, 0x10, 0x7c, 0x10, 0x6c, 0x00,//\x23 -> ж -0x0c, 0x10, 0x10, 0x10, 0x7c, 0x00,//\x24 -> ч -0x04, 0x3e, 0x44, 0x40, 0x20, 0x00,//\x25 -> t -0x38, 0x44, 0x44, 0x44, 0x38, 0x00,//\x26 -> o -0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,//\x27 -> й -0x00, 0x7c, 0x50, 0x20, 0x00, 0x00,//\x28 -> ь -0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,//\x29 -> C -0x7c, 0x08, 0x04, 0x04, 0x78, 0x00,//\x2A -> n -0x7c, 0x08, 0x04, 0x04, 0x08, 0x00,//\x2B -> r -0x3c, 0x20, 0x3c, 0x20, 0x3c, 0x00,//\x2C -> ш -0x28, 0x44, 0x54, 0x54, 0x28, 0x00,//\x2D -> з -0x3c, 0x4a, 0x4a, 0x4a, 0x30, 0x00,//\x2E -> б -0x44, 0x28, 0x10, 0x28, 0x44, 0x00,//\x2F -> х -0x00, 0x50, 0x30, 0x00, 0x00, 0x00,//\x30 -> , -0x00, 0x41, 0x7f, 0x40, 0x00, 0x00,//\x31 -> l -0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,//\x32 -> p -0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,//\x33 -> А -0x26, 0x49, 0x49, 0x49, 0x32, 0x00,//\x34 -> S -0x38, 0x44, 0x44, 0x48, 0x7f, 0x00,//\x35 -> d -0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,//\x36 -> Т -0x00, 0x41, 0x22, 0x14, 0x08, 0x00,//\x37 -> > -0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,//\x38 -> К -0x7f, 0x01, 0x01, 0x01, 0x7f, 0x00,//\x39 -> П -0x1f, 0x20, 0x40, 0x20, 0x1f, 0x00,//\x3A -> V -0x08, 0x14, 0x22, 0x41, 0x00, 0x00,//\x3B -> < -0x7c, 0x10, 0x38, 0x44, 0x38, 0x00,//\x3C -> ю -0x77, 0x08, 0x7f, 0x08, 0x77, 0x00,//\x3D -> Ж -0x48, 0x54, 0x54, 0x54, 0x24, 0x00,//\x3E -> s -0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,//\x3F -> T -0x3c, 0x20, 0x20, 0x3c, 0x60, 0x00,//\x40 -> ц -0x60, 0x3f, 0x21, 0x3f, 0x60, 0x00,//\x41 -> Д -0x7c, 0x04, 0x04, 0x04, 0x04, 0x00,//\x42 -> г -0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,//\x43 -> B -0x3f, 0x40, 0x38, 0x40, 0x3f, 0x00,//\x44 -> W -0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,//\x45 -> H -0x00, 0x00, 0x07, 0x05, 0x07, 0x00,//\x46 -> ° -0x00, 0x36, 0x36, 0x00, 0x00, 0x00,//\x47 -> : -0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,//\x48 -> ! -0x3c, 0x40, 0x40, 0x20, 0x7c, 0x00,//\x49 -> u -0x7f, 0x48, 0x44, 0x44, 0x38, 0x00,//\x4A -> b -0x38, 0x44, 0x44, 0x44, 0x20, 0x00,//\x4B -> c -0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00,//\x4C -> M -0x07, 0x08, 0x08, 0x08, 0x7f, 0x00,//\x4D -> Ч -0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,//\x4E -> P -0x3c, 0x40, 0x30, 0x40, 0x3c, 0x00,//\x4F -> w -0x08, 0x54, 0x54, 0x54, 0x3c, 0x00,//\x50 -> g -0x7c, 0x04, 0x78, 0x04, 0x78, 0x00,//\x51 -> m -0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,//\x52 -> С -0x7f, 0x09, 0x19, 0x29, 0x46, 0x00,//\x53 -> R -0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,//\x54 -> A -0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,//\x55 -> В -0x7f, 0x09, 0x09, 0x09, 0x01, 0x00,//\x56 -> F -0x7f, 0x41, 0x41, 0x22, 0x1c, 0x00,//\x57 -> D -0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,//\x58 -> Р -0x7f, 0x01, 0x01, 0x01, 0x01, 0x00,//\x59 -> Г -0x7f, 0x08, 0x04, 0x04, 0x78, 0x00,//\x5A -> h -0x0c, 0x30, 0x40, 0x30, 0x0c, 0x00,//\x5B -> v -0x18, 0x24, 0x7e, 0x24, 0x18, 0x00,//\x5C -> ф -0x3c, 0x20, 0x3c, 0x20, 0x7c, 0x00,//\x5D -> щ -0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,//\x5E -> Н -0x38, 0x54, 0x54, 0x44, 0x28, 0x00,//\x5F -> є -0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,//\x60 -> О -0x47, 0x48, 0x30, 0x08, 0x07, 0x00,//\x61 -> У -0x3f, 0x40, 0x40, 0x40, 0x3f, 0x00,//\x62 -> U -0x00, 0x7f, 0x10, 0x28, 0x44, 0x00,//\x63 -> k -0x41, 0x41, 0x7f, 0x41, 0x41, 0x00,//\x64 -> І -0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,//\x65 -> + -0x3e, 0x41, 0x41, 0x49, 0x7a, 0x00,//\x66 -> G -0x00, 0x41, 0x22, 0x1c, 0x00, 0x00,//\x67 -> ) -0x00, 0x1c, 0x22, 0x41, 0x00, 0x00,//\x68 -> ( -0x02, 0x01, 0x51, 0x09, 0x06, 0x00,//\x69 -> ? -0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x00,//\x6A -> Ш -0x7f, 0x40, 0x40, 0x40, 0x40, 0x00,//\x6B -> L -0x0c, 0x12, 0x7f, 0x12, 0x0c, 0x00,//\x6C -> Ф -0x20, 0x10, 0x08, 0x04, 0x02, 0x00,//\x6D -> / -0x07, 0x08, 0x70, 0x08, 0x07, 0x00,//\x6E -> Y -0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,//\x6F -> K -0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,//\x70 -> O -0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,//\x71 -> Е -0x46, 0x29, 0x19, 0x09, 0x7f, 0x00,//\x72 -> Я -0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,//\x73 -> Й -0x7f, 0x02, 0x04, 0x02, 0x7f, 0x00,//\x74 -> М -0x00, 0x45, 0x7c, 0x41, 0x00, 0x00,//\x75 -> ї -0x00, 0x04, 0x7e, 0x05, 0x01, 0x00,//\x76 -> f -0x40, 0x3f, 0x01, 0x01, 0x7f, 0x00,//\x77 -> Л -0x00, 0x41, 0x49, 0x49, 0x36, 0x00,//\x78 -> З -0x3f, 0x20, 0x20, 0x3f, 0x60, 0x00,//\x79 -> Ц +0x00, 0x7c, 0x50, 0x20, 0x00, 0x00,//\x21 -> ь +0x0c, 0x10, 0x10, 0x10, 0x7c, 0x00,//\x22 -> ч +0x3c, 0x4a, 0x4a, 0x4a, 0x30, 0x00,//\x23 -> б +0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,//\x24 -> й +0x28, 0x44, 0x54, 0x54, 0x28, 0x00,//\x25 -> з +0x7f, 0x01, 0x01, 0x01, 0x7f, 0x00,//\x26 -> П +0x3c, 0x20, 0x3c, 0x20, 0x3c, 0x00,//\x27 -> ш +0x44, 0x28, 0x10, 0x28, 0x44, 0x00,//\x28 -> х +0x00, 0x50, 0x30, 0x00, 0x00, 0x00,//\x29 -> , +0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,//\x2A -> C +0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,//\x2B -> К +0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,//\x2C -> А +0x7c, 0x04, 0x04, 0x04, 0x04, 0x00,//\x2D -> г +0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,//\x2E -> Т +0x77, 0x08, 0x7f, 0x08, 0x77, 0x00,//\x2F -> Ж +0x3c, 0x20, 0x20, 0x3c, 0x60, 0x00,//\x30 -> ц +0x00, 0x41, 0x22, 0x14, 0x08, 0x00,//\x31 -> > +0x26, 0x49, 0x49, 0x49, 0x32, 0x00,//\x32 -> S +0x1f, 0x20, 0x40, 0x20, 0x1f, 0x00,//\x33 -> V +0x60, 0x3f, 0x21, 0x3f, 0x60, 0x00,//\x34 -> Д +0x08, 0x14, 0x22, 0x41, 0x00, 0x00,//\x35 -> < +0x7c, 0x10, 0x38, 0x44, 0x38, 0x00,//\x36 -> ю +0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,//\x37 -> В +0x38, 0x54, 0x54, 0x54, 0x18, 0x00,//\x38 -> e +0x7f, 0x49, 0x49, 0x49, 0x36, 0x00,//\x39 -> B +0x00, 0x00, 0x07, 0x05, 0x07, 0x00,//\x3A -> ° +0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,//\x3B -> H +0x01, 0x01, 0x7f, 0x01, 0x01, 0x00,//\x3C -> T +0x00, 0x44, 0x7d, 0x40, 0x00, 0x00,//\x3D -> i +0x00, 0x36, 0x36, 0x00, 0x00, 0x00,//\x3E -> : +0x00, 0x00, 0x4f, 0x00, 0x00, 0x00,//\x3F -> ! +0x18, 0x24, 0x7e, 0x24, 0x18, 0x00,//\x40 -> ф +0x07, 0x08, 0x08, 0x08, 0x7f, 0x00,//\x41 -> Ч +0x3f, 0x40, 0x38, 0x40, 0x3f, 0x00,//\x42 -> W +0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,//\x43 -> Р +0x7f, 0x09, 0x09, 0x09, 0x01, 0x00,//\x44 -> F +0x7f, 0x41, 0x41, 0x22, 0x1c, 0x00,//\x45 -> D +0x7f, 0x02, 0x0c, 0x02, 0x7f, 0x00,//\x46 -> M +0x7c, 0x08, 0x04, 0x04, 0x78, 0x00,//\x47 -> n +0x20, 0x54, 0x54, 0x54, 0x78, 0x00,//\x48 -> a +0x7c, 0x08, 0x04, 0x04, 0x08, 0x00,//\x49 -> r +0x38, 0x44, 0x44, 0x44, 0x38, 0x00,//\x4A -> o +0x48, 0x54, 0x54, 0x54, 0x24, 0x00,//\x4B -> s +0x7f, 0x01, 0x01, 0x01, 0x01, 0x00,//\x4C -> Г +0x04, 0x3e, 0x44, 0x40, 0x20, 0x00,//\x4D -> t +0x3c, 0x20, 0x3c, 0x20, 0x7c, 0x00,//\x4E -> щ +0x7f, 0x08, 0x08, 0x08, 0x7f, 0x00,//\x4F -> Н +0x3e, 0x41, 0x41, 0x41, 0x22, 0x00,//\x50 -> С +0x40, 0x3f, 0x01, 0x01, 0x7f, 0x00,//\x51 -> Л +0x38, 0x54, 0x54, 0x44, 0x28, 0x00,//\x52 -> є +0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,//\x53 -> О +0x7c, 0x14, 0x14, 0x14, 0x08, 0x00,//\x54 -> p +0x7f, 0x09, 0x09, 0x09, 0x06, 0x00,//\x55 -> P +0x3f, 0x40, 0x40, 0x40, 0x3f, 0x00,//\x56 -> U +0x00, 0x7f, 0x10, 0x28, 0x44, 0x00,//\x57 -> k +0x08, 0x08, 0x3e, 0x08, 0x08, 0x00,//\x58 -> + +0x3e, 0x41, 0x41, 0x49, 0x7a, 0x00,//\x59 -> G +0x7f, 0x09, 0x19, 0x29, 0x46, 0x00,//\x5A -> R +0x00, 0x41, 0x22, 0x1c, 0x00, 0x00,//\x5B -> ) +0x00, 0x1c, 0x22, 0x41, 0x00, 0x00,//\x5C -> ( +0x7f, 0x02, 0x04, 0x02, 0x7f, 0x00,//\x5D -> М +0x47, 0x48, 0x30, 0x08, 0x07, 0x00,//\x5E -> У +0x02, 0x01, 0x51, 0x09, 0x06, 0x00,//\x5F -> ? +0x00, 0x45, 0x7c, 0x41, 0x00, 0x00,//\x60 -> ї +0x3f, 0x20, 0x3f, 0x20, 0x3f, 0x00,//\x61 -> Ш +0x7e, 0x09, 0x09, 0x09, 0x7e, 0x00,//\x62 -> A +0x0c, 0x12, 0x7f, 0x12, 0x0c, 0x00,//\x63 -> Ф +0x63, 0x14, 0x08, 0x14, 0x63, 0x00,//\x64 -> Х +0x20, 0x10, 0x08, 0x04, 0x02, 0x00,//\x65 -> / +0x0c, 0x30, 0x40, 0x30, 0x0c, 0x00,//\x66 -> v +0x7c, 0x04, 0x78, 0x04, 0x78, 0x00,//\x67 -> m +0x41, 0x41, 0x7f, 0x41, 0x41, 0x00,//\x68 -> І +0x3c, 0x40, 0x40, 0x20, 0x7c, 0x00,//\x69 -> u +0x07, 0x08, 0x70, 0x08, 0x07, 0x00,//\x6A -> Y +0x7f, 0x08, 0x14, 0x22, 0x41, 0x00,//\x6B -> K +0x3e, 0x41, 0x41, 0x41, 0x3e, 0x00,//\x6C -> O +0x7f, 0x49, 0x49, 0x49, 0x41, 0x00,//\x6D -> Е +0x46, 0x29, 0x19, 0x09, 0x7f, 0x00,//\x6E -> Я +0x7c, 0x21, 0x12, 0x09, 0x7c, 0x00,//\x6F -> Й +0x3f, 0x20, 0x20, 0x3f, 0x60, 0x00,//\x70 -> Ц }; // ---- Українська ---- const char* SettingsDescriptions[] = { - /* PowerSource */ "\x61\x1B\x13\x0D\x0E\x0F\x15\x17\x0D\x0C\x0E\x0D\x1A\x12\x14\x42\x10\x0C\x15\x18\x1E\x17\x16\x3C\x24\x11\x0E\x0E\x1D\x1C\x0C\x3B\x57\x29\x0C\x20\x0C\x03\x02\x3A\x30\x0C\x05\x34\x0C\x20\x0C\x0B\x1C\x0B\x3A\x30\x0C\x06\x34\x0C\x20\x0C\x03\x05\x1C\x04\x3A\x30\x0C\x07\x34\x0C\x20\x0C\x03\x08\x1C\x07\x3A\x30\x0C\x08\x34\x0C\x20\x0C\x03\x0B\x1C\x0A\x3A\x37",//Установка напруги відключення. - /* SleepTemperature */ "\x36\x11\x19\x1A\x11\x12\x0D\x13\x14\x12\x0D\x0C\x12\x11\x23\x10\x19\x14\x0C\x0F\x24\x18\x17\x14\x15\x0D\x0E\x0E\x1D\x0C\x3B\x29\x46\x6D\x56\x46\x37",//Температура режиму очікування - /* SleepTimeout */ "\x4D\x0D\x1B\x0C\x1E\x0F\x0C\x1A\x11\x12\x11\x2F\x0F\x1E\x14\x0C\x15\x0C\x12\x11\x23\x10\x19\x0C\x0F\x24\x18\x17\x14\x15\x0D\x0E\x0E\x1D\x0C\x3B\x41\x0F\x1B\x13\x14\x1A\x0E\x0F\x0C\x0F\x13\x17\x16\x3C\x24\x11\x0E\x10\x11\x37",//Час до переходу в режим очікування <Доступно отключение> - /* ShutdownTimeout */ "\x4D\x0D\x1B\x0C\x1E\x0F\x0C\x15\x18\x1E\x17\x16\x3C\x24\x11\x0E\x0E\x1D\x0C\x3B\x41\x0F\x1B\x13\x14\x1A\x0E\x0F\x0C\x15\x18\x1E\x17\x16\x3C\x24\x11\x0E\x0E\x1D\x37",//Час до відключення <Доступно відключення> - /* MotionSensitivity */ "\x33\x17\x1B\x11\x16\x11\x12\x0F\x19\x11\x13\x12\x0C\x3B\x02\x0C\x20\x0C\x55\x10\x17\x16\x1C\x0C\x03\x0C\x2F\x15\x1C\x0C\x24\x14\x13\x16\x10\x15\x0F\x1B\x13\x18\x0C\x0B\x0C\x20\x0C\x19\x0D\x17\x1B\x1C\x0C\x24\x14\x13\x16\x10\x15\x0F\x1B\x13\x18\x37",//Акселерометр <0 - Викл. 1 хв. чутливості 9 - макс. чутливості> - /* TemperatureUnit */ "\x60\x1E\x10\x0E\x10\x40\x1D\x0C\x15\x10\x19\x18\x12\x14\x0C\x13\x11\x19\x1A\x11\x12\x0D\x13\x14\x12\x10\x0C\x3B\x29\x0C\x20\x0C\x79\x11\x16\x28\x1B\x18\x27\x30\x0C\x56\x0C\x20\x0C\x6C\x0D\x12\x11\x0E\x42\x11\x27\x13\x37",//Одиниця виміру температури - /* AdvancedIdle */ "\x39\x0F\x17\x0D\x2D\x14\x15\x0D\x13\x10\x0C\x1E\x11\x13\x0D\x16\x28\x0E\x14\x0C\x15\x0C\x12\x11\x23\x10\x19\x18\x0C\x0E\x0D\x16\x0D\x2C\x13\x14\x15\x0D\x0E\x28\x0C\x3B\x78\x0D\x19\x18\x1B\x13\x28\x0C\x17\x0D\x12\x13\x10\x0E\x17\x10\x37",//Показувати детальну в режимі налаштувань <Замість картинки> - /* DisplayRotation */ "\x60\x12\x18\x5F\x0E\x13\x0D\x40\x18\x1D\x0C\x1E\x10\x1B\x1A\x16\x11\x1D\x0C\x3B\x54\x0C\x20\x0C\x33\x15\x13\x0F\x1A\x0F\x15\x0F\x12\x0F\x13\x30\x0C\x6B\x0C\x20\x0C\x77\x18\x15\x2C\x0D\x30\x0C\x53\x0C\x20\x0C\x39\x12\x0D\x15\x2C\x0D\x37",//Орієнтація дисплея - /* BoostEnabled */ "\x36\x14\x12\x2E\x0F\x20\x12\x11\x23\x10\x19\x0C\x1A\x12\x10\x0C\x14\x13\x12\x10\x19\x0D\x0E\x0E\x18\x0C\x17\x0E\x0F\x1A\x17\x10\x0C\x33\x0C\x1A\x12\x10\x0C\x1A\x0D\x27\x40\x18",//Турбо-режим при утриманні кнопки А при пайці - /* BoostTemperature */ "\x36\x11\x19\x1A\x11\x12\x0D\x13\x14\x12\x0D\x0C\x15\x0C\x36\x14\x12\x2E\x0F\x20\x12\x11\x23\x10\x19\x18",//Температура в Турбо-режимі - /* AutoStart */ "\x33\x15\x13\x0F\x19\x0D\x13\x10\x24\x0E\x10\x27\x0C\x1A\x11\x12\x11\x2F\x18\x1E\x0C\x15\x0C\x12\x11\x23\x10\x19\x0C\x1A\x0D\x27\x17\x10\x0C\x1A\x12\x10\x0C\x15\x17\x16\x3C\x24\x11\x0E\x0E\x18\x0C\x23\x10\x15\x16\x11\x0E\x0E\x1D\x1C",//Автоматичний перехід в режим пайки при включенні живлення. - /* CooldownBlink */ "\x39\x0F\x17\x0D\x2D\x14\x15\x0D\x13\x10\x0C\x13\x11\x19\x1A\x11\x12\x0D\x13\x14\x12\x14\x0C\x0E\x0D\x0C\x11\x17\x12\x0D\x0E\x18\x0C\x0F\x2F\x0F\x16\x0F\x1E\x23\x11\x0E\x0E\x1D\x30\x0C\x1A\x0F\x17\x10\x0C\x23\x0D\x16\x0F\x0C\x2D\x0D\x16\x10\x2C\x0D\x5F\x13\x28\x1B\x1D\x0C\x42\x0D\x12\x1D\x24\x10\x19\x30\x0C\x1A\x12\x10\x0C\x40\x28\x0F\x19\x14\x0C\x11\x17\x12\x0D\x0E\x0C\x19\x0F\x12\x42\x0D\x5F",//Показувати температуру на екрані охолодження, поки жало залишається гарячим, при цьому екран моргає - /* TemperatureCalibration */ "\x38\x0D\x16\x18\x2E\x12\x14\x15\x0D\x0E\x0E\x1D\x0C\x13\x11\x19\x1A\x11\x12\x0D\x13\x14\x12\x0E\x0F\x42\x0F\x0C\x1E\x0D\x13\x24\x10\x17\x0D\x1C",//Калібрування температурного датчика. - /* SettingsReset */ "\x52\x17\x10\x1E\x0D\x0E\x0E\x1D\x0C\x15\x1B\x18\x2F\x0C\x1A\x0D\x12\x0D\x19\x11\x13\x12\x18\x15\x0C\x1E\x0F\x0C\x15\x10\x2F\x18\x1E\x0E\x10\x2F\x0C\x2D\x0E\x0D\x24\x11\x0E\x28\x1C",//Скидання всіх параметрів до вихідних значень. - /* VoltageCalibration */ "\x38\x0D\x16\x18\x2E\x12\x14\x15\x0D\x0E\x0E\x1D\x0C\x0E\x0D\x1A\x12\x14\x42\x10\x0C\x15\x2F\x0F\x1E\x14\x1C\x0C\x5E\x0D\x16\x0D\x2C\x13\x14\x15\x0D\x13\x10\x0C\x17\x0E\x0F\x1A\x17\x0D\x19\x10\x30\x0C\x0E\x0D\x13\x10\x1B\x0E\x14\x13\x10\x0C\x18\x0C\x14\x13\x12\x10\x19\x0D\x13\x10\x0C\x5D\x0F\x2E\x0C\x2D\x0D\x15\x11\x12\x2C\x10\x13\x10\x1C",//Калібрування напруги входу. Налаштувати кнопками, натиснути і утримати щоб завершити. - /* AdvancedSoldering */ "\x39\x0F\x17\x0D\x2D\x14\x15\x0D\x13\x10\x0C\x1E\x11\x13\x0D\x16\x28\x0E\x14\x0C\x18\x0E\x5C\x0F\x12\x19\x0D\x40\x18\x3C\x0C\x1A\x12\x10\x0C\x1A\x0D\x27\x40\x18\x1C",//Показувати детальну інформацію при пайці. - /* ScrollingSpeed */ "\x6A\x15\x10\x1E\x17\x18\x1B\x13\x28\x0C\x1A\x12\x0F\x17\x12\x14\x13\x17\x10\x0C\x13\x11\x17\x1B\x13\x14",//Швидкість прокрутки тексту - /* TipModel */ "\x3F\x21\x32\x0C\x4C\x26\x35\x1F\x31\x0C\x3E\x1F\x31\x1F\x4B\x25\x21\x26\x2A",//Tip Model selection - /* SimpleCalibrationMode */ "\x34\x21\x51\x32\x31\x1F\x0C\x29\x22\x31\x21\x4A\x2B\x22\x25\x21\x26\x2A\x0C\x49\x3E\x21\x2A\x50\x0C\x45\x26\x25\x0C\x4F\x22\x25\x1F\x2B",//Simple Calibration using Hot water - /* AdvancedCalibrationMode */ "\x54\x35\x5B\x22\x2A\x4B\x1F\x35\x0C\x4B\x22\x31\x21\x4A\x2B\x22\x25\x21\x26\x2A\x0C\x49\x3E\x21\x2A\x50\x0C\x25\x5A\x1F\x2B\x51\x26\x4B\x26\x49\x32\x31\x1F\x0C\x26\x2A\x0C\x25\x5A\x1F\x0C\x25\x21\x32",//Advanced calibration using thermocouple on the tip - /* PowerInput */ "\x4E\x26\x4F\x1F\x2B\x0C\x44\x22\x25\x25\x22\x50\x1F\x0C\x26\x76\x0C\x25\x5A\x1F\x0C\x32\x26\x4F\x1F\x2B\x0C\x22\x35\x22\x32\x25\x1F\x2B\x0C\x49\x3E\x1F\x35",//Power Wattage of the power adapter used + /* PowerSource */ "\x37\x1B\x13\x0D\x0E\x0F\x15\x16\x12\x0E\x0E\x1C\x0C\x0E\x0D\x1A\x10\x14\x2D\x11\x0C\x15\x17\x1D\x19\x16\x36\x22\x12\x0E\x0E\x1C\x1E\x0C\x35\x45\x2A\x0C\x20\x0C\x03\x02\x33\x29\x0C\x05\x32\x0C\x20\x0C\x0B\x1E\x0B\x33\x29\x0C\x06\x32\x0C\x20\x0C\x03\x05\x1E\x04\x33\x29\x0C\x07\x32\x0C\x20\x0C\x03\x08\x1E\x07\x33\x29\x0C\x08\x32\x0C\x20\x0C\x03\x0B\x1E\x0A\x33\x31",//Встановлення напруги відключення. + /* SleepTemperature */ "\x2E\x12\x18\x1A\x12\x10\x0D\x13\x14\x10\x0D\x0C\x10\x12\x1F\x11\x18\x14\x0C\x0F\x22\x17\x19\x14\x15\x0D\x0E\x0E\x1C\x0C\x35\x2A\x3A\x65\x44\x3A\x31",//Температура режиму очікування + /* SleepTimeout */ "\x41\x0D\x1B\x0C\x1D\x0F\x0C\x1A\x12\x10\x12\x28\x0F\x1D\x14\x0C\x15\x0C\x10\x12\x1F\x11\x18\x0C\x0F\x22\x17\x19\x14\x15\x0D\x0E\x0E\x1C\x0C\x35\x64\x15\x11\x16\x11\x0E\x11\x31",//Час до переходу в режим очікування <Хвилини> + /* ShutdownTimeout */ "\x41\x0D\x1B\x0C\x1D\x0F\x0C\x15\x17\x1D\x19\x16\x36\x22\x12\x0E\x0E\x1C\x0C\x35\x64\x15\x11\x16\x11\x0E\x11\x31",//Час до відключення <Хвилини> + /* MotionSensitivity */ "\x2C\x19\x1B\x12\x16\x12\x10\x0F\x18\x12\x13\x10\x0C\x35\x02\x0C\x20\x0C\x37\x11\x18\x19\x1E\x0C\x03\x0C\x28\x15\x1E\x0C\x22\x14\x13\x16\x11\x15\x0F\x1B\x13\x17\x0C\x0B\x0C\x20\x0C\x18\x0D\x19\x1B\x1E\x0C\x22\x14\x13\x16\x11\x15\x0F\x1B\x13\x17\x31",//Акселерометр <0 - Вимк. 1 хв. чутливості 9 - макс. чутливості> + /* TemperatureUnit */ "\x53\x1D\x11\x0E\x11\x30\x1C\x0C\x15\x11\x18\x17\x10\x14\x0C\x13\x12\x18\x1A\x12\x10\x0D\x13\x14\x10\x11\x0C\x35\x2A\x0C\x20\x0C\x70\x12\x16\x21\x1B\x17\x24\x29\x0C\x44\x0C\x20\x0C\x63\x0D\x10\x12\x0E\x2D\x12\x24\x13\x31",//Одиниця виміру температури + /* AdvancedIdle */ "\x26\x0F\x19\x0D\x25\x14\x15\x0D\x13\x11\x0C\x1D\x12\x13\x0D\x16\x21\x0E\x14\x0C\x17\x0E\x40\x0F\x10\x18\x0D\x30\x17\x36\x0C\x18\x0D\x16\x12\x0E\x21\x19\x11\x18\x0C\x27\x10\x11\x40\x13\x0F\x18\x0C\x0E\x0D\x0C\x1D\x0F\x18\x0D\x27\x0E\x21\x0F\x18\x14\x0C\x12\x19\x10\x0D\x0E\x17",//Показувати детальну інформацію маленьким шрифтом на домашньому екрані + /* DisplayRotation */ "\x53\x10\x17\x52\x0E\x13\x0D\x30\x17\x1C\x0C\x1D\x11\x1B\x1A\x16\x12\x1C\x0C\x35\x62\x0C\x20\x0C\x2C\x15\x13\x0F\x1A\x0F\x15\x0F\x10\x0F\x13\x29\x0C\x51\x0C\x20\x0C\x51\x17\x15\x27\x0D\x29\x0C\x26\x0C\x20\x0C\x26\x10\x0D\x15\x27\x0D\x31",//Орієнтація дисплея + /* BoostEnabled */ "\x2E\x14\x10\x23\x0F\x20\x10\x12\x1F\x11\x18\x0C\x1A\x10\x11\x0C\x14\x13\x10\x11\x18\x0D\x0E\x0E\x17\x0C\x19\x0E\x0F\x1A\x19\x11\x0C\x2C\x0C\x1A\x10\x11\x0C\x1A\x0D\x24\x30\x17",//Турбо-режим при утриманні кнопки А при пайці + /* BoostTemperature */ "\x2E\x12\x18\x1A\x12\x10\x0D\x13\x14\x10\x0D\x0C\x15\x0C\x2E\x14\x10\x23\x0F\x20\x10\x12\x1F\x11\x18\x17",//Температура в Турбо-режимі + /* AutoStart */ "\x2C\x15\x13\x0F\x18\x0D\x13\x11\x22\x0E\x11\x24\x0C\x1A\x12\x10\x12\x28\x17\x1D\x0C\x15\x0C\x10\x12\x1F\x11\x18\x0C\x1A\x0D\x24\x19\x11\x0C\x1A\x10\x11\x0C\x15\x15\x17\x18\x19\x0E\x12\x0E\x17\x0C\x1F\x11\x15\x16\x12\x0E\x0E\x1C\x1E",//Автоматичний перехід в режим пайки при ввімкнені живлення. + /* CooldownBlink */ "\x26\x0F\x19\x0D\x25\x14\x15\x0D\x13\x11\x0C\x13\x12\x18\x1A\x12\x10\x0D\x13\x14\x10\x14\x0C\x0E\x0D\x0C\x12\x19\x10\x0D\x0E\x17\x0C\x0F\x28\x0F\x16\x0F\x1D\x1F\x12\x0E\x0E\x1C\x29\x0C\x1A\x0F\x19\x11\x0C\x1F\x0D\x16\x0F\x0C\x25\x0D\x16\x11\x27\x0D\x52\x13\x21\x1B\x1C\x0C\x2D\x0D\x10\x1C\x22\x11\x18\x29\x0C\x1A\x10\x11\x0C\x30\x21\x0F\x18\x14\x0C\x12\x19\x10\x0D\x0E\x0C\x18\x0F\x10\x2D\x0D\x52",//Показувати температуру на екрані охолодження, поки жало залишається гарячим, при цьому екран моргає + /* TemperatureCalibration */ "\x2B\x0D\x16\x17\x23\x10\x14\x15\x0D\x0E\x0E\x1C\x0C\x13\x12\x18\x1A\x12\x10\x0D\x13\x14\x10\x0E\x0F\x2D\x0F\x0C\x1D\x0D\x13\x22\x11\x19\x0D\x1E",//Калібрування температурного датчика. + /* SettingsReset */ "\x50\x19\x11\x1D\x0D\x0E\x0E\x1C\x0C\x15\x1B\x17\x28\x0C\x1A\x0D\x10\x0D\x18\x12\x13\x10\x17\x15\x0C\x1D\x0F\x0C\x1B\x13\x0D\x0E\x1D\x0D\x10\x13\x0E\x11\x28\x0C\x25\x0E\x0D\x22\x12\x0E\x21\x1E",//Скидання всіх параметрів до стандартних значень. + /* VoltageCalibration */ "\x2B\x0D\x16\x17\x23\x10\x14\x15\x0D\x0E\x0E\x1C\x0C\x0E\x0D\x1A\x10\x14\x2D\x11\x0C\x15\x28\x0F\x1D\x14\x1E\x0C\x4F\x0D\x16\x0D\x27\x13\x14\x15\x0D\x13\x11\x0C\x19\x0E\x0F\x1A\x19\x0D\x18\x11\x29\x0C\x0E\x0D\x13\x11\x1B\x0E\x14\x13\x11\x0C\x17\x0C\x14\x13\x10\x11\x18\x0D\x13\x11\x0C\x4E\x0F\x23\x0C\x25\x0D\x15\x12\x10\x27\x11\x13\x11\x1E",//Калібрування напруги входу. Налаштувати кнопками, натиснути і утримати щоб завершити. + /* AdvancedSoldering */ "\x26\x0F\x19\x0D\x25\x14\x15\x0D\x13\x11\x0C\x1D\x12\x13\x0D\x16\x21\x0E\x14\x0C\x17\x0E\x40\x0F\x10\x18\x0D\x30\x17\x36\x0C\x1A\x10\x11\x0C\x1A\x0D\x24\x30\x17\x1E",//Показувати детальну інформацію при пайці. + /* ScrollingSpeed */ "\x61\x15\x11\x1D\x19\x17\x1B\x13\x21\x0C\x1A\x10\x0F\x19\x10\x14\x13\x19\x11\x0C\x13\x12\x19\x1B\x13\x14",//Швидкість прокрутки тексту + /* TipModel */ "\x37\x11\x23\x17\x10\x0C\x18\x0F\x1D\x12\x16\x17\x0C\x1F\x0D\x16\x0D",//Вибір моделі жала + /* SimpleCalibrationMode */ "\x26\x10\x0F\x1B\x13\x12\x0C\x19\x0D\x16\x17\x23\x10\x14\x15\x0D\x0E\x0E\x1C\x0C\x25\x0C\x15\x11\x19\x0F\x10\x11\x1B\x13\x0D\x0E\x0E\x1C\x18\x0C\x2D\x0D\x10\x1C\x22\x0F\x60\x0C\x15\x0F\x1D\x11",//Просте калібрування з використанням гарячої води + /* AdvancedCalibrationMode */ "\x2B\x0D\x16\x17\x23\x10\x14\x15\x0D\x0E\x0E\x1C\x0C\x25\x0D\x0C\x1D\x0F\x1A\x0F\x18\x0F\x2D\x0F\x36\x0C\x13\x12\x10\x18\x0F\x1A\x0D\x10\x11",//Калібрування за допомогою термопари + /* PowerInput */ "\x26\x0F\x13\x14\x1F\x0E\x17\x1B\x13\x21\x0C\x1D\x1F\x12\x10\x12\x16\x0D\x0C\x1F\x11\x15\x16\x12\x0E\x0E\x1C\x0C\x15\x0C\x37\x0D\x13\x0D\x28",//Потужність джерела живлення в Ватах }; -const char* SettingsCalibrationDone = "\x29\x22\x31\x21\x4A\x2B\x22\x25\x21\x26\x2A\x0C\x35\x26\x2A\x1F\x48";//Calibration done! -const char* SettingsCalibrationWarning = "\x39\x11\x12\x11\x17\x0F\x0E\x0D\x27\x13\x11\x1B\x1D\x30\x0C\x5D\x0F\x0C\x23\x0D\x16\x0F\x0C\x0F\x2F\x0F\x16\x0F\x16\x0F\x0C\x1E\x0F\x0C\x17\x18\x19\x0E\x0D\x13\x0E\x0F\x75\x0C\x13\x11\x19\x1A\x11\x12\x0D\x13\x14\x12\x10\x30\x0C\x1A\x11\x12\x2C\x0C\x0E\x18\x23\x0C\x1A\x12\x0F\x1E\x0F\x15\x23\x14\x15\x0D\x13\x10\x48";//Переконайтеся, що жало охололо до кімнатної температури, перш ніж продовжувати! -const char* SettingsResetWarning = "\x55\x10\x0C\x1E\x18\x27\x1B\x0E\x0F\x0C\x2F\x0F\x24\x11\x13\x11\x0C\x1B\x17\x10\x0E\x14\x13\x10\x0C\x0E\x0D\x16\x0D\x2C\x13\x14\x15\x0D\x0E\x0E\x1D\x0C\x1E\x0F\x0C\x2D\x0E\x0D\x24\x11\x0E\x28\x0C\x2D\x0D\x0C\x2D\x0D\x19\x0F\x15\x24\x14\x15\x0D\x0E\x0E\x1D\x19\x69";//Ви дійсно хочете скинути налаштування до значень за замовчуванням? -const char* UVLOWarningString = "\x33\x38\x38\x61\x74\x20\x20";//АККУМ-- -const char* UndervoltageString = "\x39\x18\x1E\x0C\x23\x10\x15\x16\x11\x0E\x0E\x1D\x19";//Під живленням -const char* InputVoltageString = "\x3D\x10\x15\x1C\x68\x43\x67\x47\x0C";//Жив.(B): -const char* WarningTipTempString = "\x3D\x0D\x16\x0F\x0C\x25\x46\x47\x0C";//Жало t°: -const char* BadTipString = "\x3D\x0D\x16\x0F\x20\x20";//Жало-- -const char* SleepingSimpleString = "\x52\x0F\x0E\x0C";//Сон -const char* SleepingAdvancedString = "\x60\x24\x18\x17\x14\x15\x0D\x0E\x0E\x1D\x1C\x1C\x1C";//Очікування... -const char* WarningSimpleString = "\x33\x73\x48";//АЙ! -const char* WarningAdvancedString = "\x61\x55\x33\x59\x33\x0C\x59\x33\x58\x72\x4D\x71\x48";//УВАГА ГАРЯЧЕ! -const char* SleepingTipAdvancedString = "\x3D\x0D\x16\x0F\x47";//Жало: -const char* IdleTipString = "\x3D\x0D\x16\x0F\x47";//Жало: -const char* IdleSetString = "\x0C\x20\x37";// -> -const char* TipDisconnectedString = "\x3D\x0D\x16\x0F\x0C\x15\x10\x19\x17\x0E\x11\x0E\x0F\x48";//Жало вимкнено! -const char* SolderingAdvancedPowerPrompt = "\x3D\x10\x15\x16\x11\x0E\x0E\x1D\x47\x0C";//Живлення: -const char* OffString = "\x55\x10\x19";//Вим -const char* ResetOKMessage = "\x53\x1F\x3E\x1F\x25\x0C\x70\x6F";//Reset OK -const char* YourGainMessage = "\x6E\x26\x49\x2B\x0C\x66\x22\x21\x2A";//Your Gain +const char* SettingsCalibrationDone = "\x2B\x0D\x16\x17\x23\x10\x14\x15\x0D\x0E\x0E\x1C\x0C\x15\x11\x19\x0F\x0E\x0D\x0E\x12\x3F";//Калібрування виконане! +const char* SettingsCalibrationWarning = "\x26\x12\x10\x12\x19\x0F\x0E\x0D\x24\x13\x12\x1B\x1C\x29\x0C\x4E\x0F\x0C\x1F\x0D\x16\x0F\x0C\x0F\x28\x0F\x16\x0F\x16\x0F\x0C\x1D\x0F\x0C\x19\x17\x18\x0E\x0D\x13\x0E\x0F\x60\x0C\x13\x12\x18\x1A\x12\x10\x0D\x13\x14\x10\x11\x29\x0C\x1A\x12\x10\x27\x0C\x0E\x17\x1F\x0C\x1A\x10\x0F\x1D\x0F\x15\x1F\x14\x15\x0D\x13\x11\x3F";//Переконайтеся, що жало охололо до кімнатної температури, перш ніж продовжувати! +const char* SettingsResetWarning = "\x37\x11\x0C\x1D\x17\x24\x1B\x0E\x0F\x0C\x28\x0F\x22\x12\x13\x12\x0C\x1B\x19\x11\x0E\x14\x13\x11\x0C\x0E\x0D\x16\x0D\x27\x13\x14\x15\x0D\x0E\x0E\x1C\x0C\x1D\x0F\x0C\x25\x0E\x0D\x22\x12\x0E\x21\x0C\x25\x0D\x0C\x25\x0D\x18\x0F\x15\x22\x14\x15\x0D\x0E\x0E\x1C\x18\x5F";//Ви дійсно хочете скинути налаштування до значень за замовчуванням? +const char* UVLOWarningString = "\x2C\x2B\x2B\x5E\x5D\x20\x20";//АККУМ-- +const char* UndervoltageString = "\x26\x17\x1D\x0C\x1F\x11\x15\x16\x12\x0E\x0E\x1C\x18";//Під живленням +const char* InputVoltageString = "\x2F\x11\x15\x1E\x5C\x39\x5B\x3E\x0C";//Жив.(B): +const char* WarningTipTempString = "\x2F\x0D\x16\x0F\x0C\x4D\x3A\x3E\x0C";//Жало t°: +const char* BadTipString = "\x2F\x0D\x16\x0F\x20\x20";//Жало-- +const char* SleepingSimpleString = "\x50\x0F\x0E\x0C";//Сон +const char* SleepingAdvancedString = "\x53\x22\x17\x19\x14\x15\x0D\x0E\x0E\x1C\x1E\x1E\x1E";//Очікування... +const char* WarningSimpleString = "\x2C\x6F\x3F";//АЙ! +const char* WarningAdvancedString = "\x5E\x37\x2C\x4C\x2C\x0C\x4C\x2C\x43\x6E\x41\x6D\x3F";//УВАГА ГАРЯЧЕ! +const char* SleepingTipAdvancedString = "\x2F\x0D\x16\x0F\x3E";//Жало: +const char* IdleTipString = "\x2F\x0D\x16\x0F\x3E";//Жало: +const char* IdleSetString = "\x0C\x20\x31";// -> +const char* TipDisconnectedString = "\x2F\x0D\x16\x0F\x0C\x15\x11\x18\x19\x0E\x12\x0E\x0F\x3F";//Жало вимкнено! +const char* SolderingAdvancedPowerPrompt = "\x2F\x11\x15\x16\x12\x0E\x0E\x1C\x3E\x0C";//Живлення: +const char* OffString = "\x37\x11\x18\x19";//Вимк +const char* ResetOKMessage = "\x5A\x38\x4B\x38\x4D\x0C\x6C\x6B";//Reset OK +const char* YourGainMessage = "\x6A\x4A\x69\x49\x0C\x59\x48\x3D\x47";//Your Gain -const char* SettingRightChar = "\x53";//R -const char* SettingLeftChar = "\x6B";//L -const char* SettingAutoChar = "\x54";//A -const char* SettingFastChar = "\x65";//+ +const char* SettingRightChar = "\x26";//П +const char* SettingLeftChar = "\x51";//Л +const char* SettingAutoChar = "\x62";//A +const char* SettingFastChar = "\x58";//+ const char* SettingSlowChar = "\x20";//- -const char* SymbolPlus = "\x65";//+ +const char* SymbolPlus = "\x58";//+ const char* SymbolMinus = "\x20";//- const char* SymbolSpace = "\x0C";// -const char* SymbolDot = "\x1C";//. -const char* SymbolDegC = "\x29";//C -const char* SymbolDegF = "\x56";//F -const char* SymbolMinutes = "\x4C";//M -const char* SymbolSeconds = "\x34";//S -const char* SymbolWatts = "\x44";//W -const char* SymbolVolts = "\x3A";//V -const char* SymbolDC = "\x57\x29";//DC -const char* SymbolCellCount = "\x34";//S -const char* SymbolVersionNumber = "\x3A\x04\x1C\x02\x08";//V2.06 +const char* SymbolDot = "\x1E";//. +const char* SymbolDegC = "\x2A";//C +const char* SymbolDegF = "\x44";//F +const char* SymbolMinutes = "\x46";//M +const char* SymbolSeconds = "\x32";//S +const char* SymbolWatts = "\x42";//W +const char* SymbolVolts = "\x33";//V +const char* SymbolDC = "\x45\x2A";//DC +const char* SymbolCellCount = "\x32";//S +const char* SymbolVersionNumber = "\x33\x04\x1E\x02\x08";//V2.06 const char* TipModelStrings[] = { #ifdef MODEL_TS100 - "\x43\x02\x04",//B02 - "\x57\x04\x06",//D24 - "\x43\x29\x04",//BC2 - "\x0C\x29\x03",// C1 - "\x3F\x34\x03\x02\x02",//TS100 - "\x43\x29\x04",//BC2 - "\x45\x22\x63\x63\x26",//Hakko - "\x62\x3E\x1F\x2B",//User + "\x39\x02\x04",//B02 + "\x45\x04\x06",//D24 + "\x39\x2A\x04",//BC2 + "\x0C\x2A\x03",// C1 + "\x3C\x32\x03\x02\x02",//TS100 + "\x39\x2A\x04",//BC2 + "\x3B\x48\x57\x57\x4A",//Hakko + "\x56\x4B\x38\x49",//User #else - "\x43\x02\x04",//B02 - "\x57\x04\x07",//D25 - "\x3F\x34\x0A\x02",//TS80 - "\x62\x3E\x1F\x2B",//User + "\x39\x02\x04",//B02 + "\x45\x04\x07",//D25 + "\x3C\x32\x0A\x02",//TS80 + "\x56\x4B\x38\x49",//User #endif }; const char* DebugMenu[] = { - "\x03\x0B\x20\x02\x0A\x20\x03\x0B",//19-08-19 - "\x45\x44\x0C\x66\x0C",//HW G - "\x45\x44\x0C\x4C\x0C",//HW M - "\x45\x44\x0C\x4E\x0C",//HW P - "\x3F\x21\x51\x1F\x0C",//Time - "\x4C\x26\x5B\x1F\x0C",//Move - "\x53\x3F\x21\x32\x0C",//RTip - "\x29\x3F\x21\x32\x0C",//CTip - "\x29\x45\x22\x2A\x0C",//CHan - "\x3A\x21\x2A\x0C\x0C",//Vin - "\x4E\x29\x43\x0C\x0C",//PCB + "\x04\x05\x20\x03\x04\x20\x03\x0B",//23-12-19 + "\x3B\x42\x0C\x59\x0C",//HW G + "\x3B\x42\x0C\x46\x0C",//HW M + "\x3B\x42\x0C\x55\x0C",//HW P + "\x3C\x3D\x67\x38\x0C",//Time + "\x46\x4A\x66\x38\x0C",//Move + "\x5A\x3C\x3D\x54\x0C",//RTip + "\x2A\x3C\x3D\x54\x0C",//CTip + "\x2A\x3B\x48\x47\x0C",//CHan + "\x33\x3D\x47\x0C\x0C",//Vin + "\x55\x2A\x39\x0C\x0C",//PCB }; const enum ShortNameType SettingsShortNameType = SHORT_NAME_DOUBLE_LINE; const char* SettingsShortNames[][2] = { - /* PowerSource */ { "\x41\x23\x11\x12\x11\x16\x0F", "\x23\x10\x15\x16\x11\x0E\x0E\x1D" },//['Джерело', 'живлення'] - /* SleepTemperature */ { "\x36\x11\x19\x1A\x11\x12\x1C", "\x1B\x0E\x14" },//['Темпер.', 'сну'] - /* SleepTimeout */ { "\x36\x0D\x27\x19\x0D\x14\x13", "\x1B\x0E\x14" },//['Таймаут', 'сну'] - /* ShutdownTimeout */ { "\x4D\x0D\x1B\x14\x0C\x1E\x0F", "\x15\x10\x19\x17\x0E\x11\x0E\x0E\x1D" },//['Часу до', 'вимкнення'] - /* MotionSensitivity */ { "\x4D\x14\x13\x16\x1C\x0C\x1B\x11\x0E\x1B\x0F\x20", "\x12\x14\x0C\x12\x14\x2F\x14" },//['Чутл. сенсо-', 'ру руху'] - /* TemperatureUnit */ { "\x6C\x0F\x12\x19\x0D\x13\x0C\x13\x11\x19\x1A\x11\x20", "\x12\x0D\x13\x14\x12\x10\x68\x29\x46\x6D\x56\x46\x67" },//['Формат темпе-', 'ратури(C°/F°)'] - /* AdvancedIdle */ { "\x41\x11\x13\x0D\x16\x28\x0E\x10\x27\x0C\x12\x11\x20", "\x23\x10\x19\x0C\x0F\x24\x18\x17\x14\x15\x0D\x0E\x1C" },//['Детальний ре-', 'жим очікуван.'] - /* DisplayRotation */ { "\x33\x15\x13\x0F\x1A\x0F\x15\x0F\x12\x0F\x13", "\x11\x17\x12\x0D\x0E\x14" },//['Автоповорот', 'екрану'] - /* BoostEnabled */ { "\x58\x11\x23\x10\x19", "\x36\x14\x12\x2E\x0F" },//['Режим', 'Турбо'] - /* BoostTemperature */ { "\x36\x11\x19\x1A\x11\x12\x1C", "\x36\x14\x12\x2E\x0F" },//['Темпер.', 'Турбо'] - /* AutoStart */ { "\x59\x0D\x12\x1D\x24\x10\x27", "\x1B\x13\x0D\x12\x13" },//['Гарячий', 'старт'] - /* CooldownBlink */ { "\x39\x0F\x17\x0D\x2D\x0C\x25\x46\x0C\x1A\x12\x10", "\x0F\x2F\x0F\x16\x0F\x1E\x23\x1C" },//['Показ t° при', 'охолодж.'] - /* TemperatureCalibration */ { "\x38\x0D\x16\x18\x2E\x12\x0F\x15\x17\x0D", "\x13\x11\x19\x1A\x11\x12\x0D\x13\x14\x12\x10" },//['Калібровка', 'температури'] - /* SettingsReset */ { "\x52\x17\x10\x0E\x14\x13\x10\x0C\x15\x1B\x18", "\x0E\x0D\x16\x0D\x2C\x13\x14\x15\x0D\x0E\x0E\x1D\x69" },//['Скинути всі', 'налаштування?'] - /* VoltageCalibration */ { "\x38\x0D\x16\x18\x2E\x12\x0F\x15\x17\x0D", "\x0E\x0D\x1A\x12\x14\x42\x0D" },//['Калібровка', 'напруга'] - /* AdvancedSoldering */ { "\x41\x11\x13\x0D\x16\x28\x0E\x10\x27\x0C\x12\x11\x20", "\x23\x10\x19\x0C\x1A\x0D\x27\x17\x10" },//['Детальний ре-', 'жим пайки'] - /* ScrollingSpeed */ { "\x6A\x15\x10\x1E\x17\x18\x1B\x13\x28", "\x13\x11\x17\x1B\x13\x14" },//['Швидкість', 'тексту'] - /* TipModel */ { "\x3F\x21\x32", "\x4C\x26\x35\x1F\x31" },//['Tip', 'Model'] - /* SimpleCalibrationMode */ { "\x34\x21\x51\x32\x31\x1F", "\x29\x22\x31\x21\x4A\x2B\x22\x25\x21\x26\x2A" },//['Simple', 'Calibration'] - /* AdvancedCalibrationMode */ { "\x54\x35\x5B\x22\x2A\x4B\x1F\x35", "\x29\x22\x31\x21\x4A\x2B\x22\x25\x21\x26\x2A" },//['Advanced', 'Calibration'] - /* PowerInput */ { "\x4E\x26\x4F\x1F\x2B", "\x44\x22\x25\x25\x22\x50\x1F" },//['Power', 'Wattage'] + /* PowerSource */ { "\x34\x1F\x12\x10\x12\x16\x0F", "\x1F\x11\x15\x16\x12\x0E\x0E\x1C" },//['Джерело', 'живлення'] + /* SleepTemperature */ { "\x2E\x12\x18\x1A\x12\x10\x1E", "\x1B\x0E\x14" },//['Темпер.', 'сну'] + /* SleepTimeout */ { "\x2E\x0D\x24\x18\x20\x0D\x14\x13", "\x1B\x0E\x14" },//['Тайм-аут', 'сну'] + /* ShutdownTimeout */ { "\x41\x0D\x1B\x14\x0C\x1D\x0F", "\x15\x11\x18\x19\x0E\x12\x0E\x0E\x1C" },//['Часу до', 'вимкнення'] + /* MotionSensitivity */ { "\x41\x14\x13\x16\x1E\x0C\x1B\x12\x0E\x1B\x0F\x20", "\x10\x14\x0C\x10\x14\x28\x14" },//['Чутл. сенсо-', 'ру руху'] + /* TemperatureUnit */ { "\x63\x0F\x10\x18\x0D\x13\x0C\x13\x12\x18\x1A\x12\x20", "\x10\x0D\x13\x14\x10\x11\x5C\x2A\x3A\x65\x44\x3A\x5B" },//['Формат темпе-', 'ратури(C°/F°)'] + /* AdvancedIdle */ { "\x34\x12\x13\x0D\x16\x21\x0E\x11\x24\x0C\x10\x12\x20", "\x1F\x11\x18\x0C\x0F\x22\x17\x19\x14\x15\x0D\x0E\x1E" },//['Детальний ре-', 'жим очікуван.'] + /* DisplayRotation */ { "\x2C\x15\x13\x0F\x1A\x0F\x15\x0F\x10\x0F\x13", "\x12\x19\x10\x0D\x0E\x14" },//['Автоповорот', 'екрану'] + /* BoostEnabled */ { "\x43\x12\x1F\x11\x18", "\x2E\x14\x10\x23\x0F" },//['Режим', 'Турбо'] + /* BoostTemperature */ { "\x2E\x12\x18\x1A\x12\x10\x1E", "\x2E\x14\x10\x23\x0F" },//['Темпер.', 'Турбо'] + /* AutoStart */ { "\x4C\x0D\x10\x1C\x22\x11\x24", "\x1B\x13\x0D\x10\x13" },//['Гарячий', 'старт'] + /* CooldownBlink */ { "\x26\x0F\x19\x0D\x25\x0C\x4D\x3A\x0C\x1A\x10\x11", "\x0F\x28\x0F\x16\x0F\x1D\x1F\x1E" },//['Показ t° при', 'охолодж.'] + /* TemperatureCalibration */ { "\x2B\x0D\x16\x17\x23\x10\x0F\x15\x19\x0D", "\x13\x12\x18\x1A\x12\x10\x0D\x13\x14\x10\x11" },//['Калібровка', 'температури'] + /* SettingsReset */ { "\x50\x19\x11\x0E\x14\x13\x11\x0C\x15\x1B\x17", "\x0E\x0D\x16\x0D\x27\x13\x14\x15\x0D\x0E\x0E\x1C\x5F" },//['Скинути всі', 'налаштування?'] + /* VoltageCalibration */ { "\x2B\x0D\x16\x17\x23\x10\x0F\x15\x19\x0D", "\x0E\x0D\x1A\x10\x14\x2D\x11" },//['Калібровка', 'напруги'] + /* AdvancedSoldering */ { "\x34\x12\x13\x0D\x16\x21\x0E\x11\x24\x0C\x10\x12\x20", "\x1F\x11\x18\x0C\x1A\x0D\x24\x19\x11" },//['Детальний ре-', 'жим пайки'] + /* ScrollingSpeed */ { "\x61\x15\x11\x1D\x19\x17\x1B\x13\x21", "\x13\x12\x19\x1B\x13\x14" },//['Швидкість', 'тексту'] + /* TipModel */ { "\x5D\x0F\x1D\x12\x16\x21", "\x2F\x0D\x16\x0F" },//['Модель', 'Жало'] + /* SimpleCalibrationMode */ { "\x26\x10\x0F\x1B\x13\x12", "\x2B\x0D\x16\x17\x23\x10\x14\x15\x0D\x0E\x0E\x1C" },//['Просте', 'Калібрування'] + /* AdvancedCalibrationMode */ { "\x34\x12\x13\x0D\x16\x21\x0E\x12", "\x2B\x0D\x16\x17\x23\x10\x14\x15\x0D\x0E\x0E\x1C" },//['Детальне', 'Калібрування'] + /* PowerInput */ { "\x26\x0F\x13\x14\x1F\x0E\x17\x1B\x13\x21", "\x1D\x1F\x1E\x0C\x1F\x11\x15\x16\x1E" },//['Потужність', 'дж. живл.'] }; const char* SettingsMenuEntries[4] = { - /* SolderingMenu */ "\x39\x0D\x27\x17\x0D\x01",//['Пайка', ''] - /* PowerSavingMenu */ "\x52\x0F\x0E\x01",//['Сон', ''] - /* UIMenu */ "\x64\x0E\x13\x11\x12\x5C\x11\x27\x1B\x01",//['Інтерфейс', ''] - /* AdvancedMenu */ "\x64\x0E\x2C\x18\x01",//['Інші', ''] + /* SolderingMenu */ "\x26\x0D\x10\x0D\x18\x12\x13\x10\x11\x01\x1A\x0D\x24\x19\x11",//['Параметри', 'пайки'] + /* PowerSavingMenu */ "\x43\x12\x1F\x11\x18\x01\x1B\x0E\x14",//['Режим', 'сну'] + /* UIMenu */ "\x68\x0E\x13\x12\x10\x40\x12\x24\x1B\x01",//['Інтерфейс', ''] + /* AdvancedMenu */ "\x34\x0F\x1D\x0D\x13\x19\x0F\x15\x17\x01\x1A\x0D\x10\x0D\x18\x12\x13\x10\x11",//['Додаткові', 'параметри'] }; const char* SettingsMenuEntriesDescriptions[4] = { - /* SolderingMenu */ "\x5E\x0D\x16\x0D\x2C\x13\x14\x15\x0D\x0E\x0E\x1D\x0C\x1E\x16\x1D\x0C\x12\x11\x23\x10\x19\x14\x0C\x1A\x0D\x27\x17\x10\x1C\x0C\x41\x18\x3C\x13\x28\x0C\x1A\x12\x10\x0C\x15\x17\x16\x3C\x24\x11\x0E\x0F\x19\x14\x0C\x23\x0D\x16\x18\x1C",//Налаштування для режиму пайки. Діють при включеному жалі. - /* PowerSavingMenu */ "\x5E\x0D\x16\x0D\x2C\x13\x14\x15\x0D\x0E\x0E\x1D\x0C\x1A\x12\x10\x0C\x2E\x11\x2D\x1E\x18\x1D\x16\x28\x0E\x0F\x1B\x13\x18\x1C\x0C\x38\x0F\x12\x10\x1B\x0E\x0F\x0C\x5D\x0F\x0C\x2E\x0C\x0E\x11\x0C\x0F\x2E\x1A\x11\x17\x13\x10\x1B\x1D\x0C\x18\x0C\x2D\x0C\x24\x0D\x1B\x0F\x19\x0C\x0E\x11\x0C\x1B\x1A\x0D\x16\x10\x13\x10\x0C\x23\x10\x13\x16\x0F\x1C",//Налаштування при бездіяльності. Корисно що б не обпектися і з часом не спалити житло. - /* UIMenu */ "\x38\x0F\x12\x10\x1B\x13\x14\x15\x0D\x16\x28\x0E\x10\x40\x28\x17\x10\x27\x0C\x18\x0E\x13\x11\x12\x5C\x11\x27\x1B\x1C",//Користувальницький інтерфейс. - /* AdvancedMenu */ "\x58\x0F\x2D\x2C\x10\x12\x11\x0E\x18\x0C\x0E\x0D\x16\x0D\x2C\x13\x14\x15\x0D\x0E\x0E\x1D\x1C\x0C\x41\x0F\x1E\x0D\x13\x17\x0F\x15\x18\x0C\x2D\x12\x14\x24\x0E\x0F\x1B\x13\x18\x1C",//Розширені налаштування. Додаткові зручності. + /* SolderingMenu */ "\x4F\x0D\x16\x0D\x27\x13\x14\x15\x0D\x0E\x0E\x1C\x0C\x1D\x16\x1C\x0C\x10\x12\x1F\x11\x18\x14\x0C\x1A\x0D\x24\x19\x11\x1E\x0C\x34\x17\x36\x13\x21\x0C\x1A\x10\x11\x0C\x15\x19\x16\x36\x22\x12\x0E\x0F\x18\x14\x0C\x1F\x0D\x16\x17\x1E",//Налаштування для режиму пайки. Діють при включеному жалі. + /* PowerSavingMenu */ "\x4F\x0D\x16\x0D\x27\x13\x14\x15\x0D\x0E\x0E\x1C\x0C\x1A\x10\x11\x0C\x23\x12\x25\x1D\x17\x1C\x16\x21\x0E\x0F\x1B\x13\x17\x1E\x0C\x2B\x0F\x10\x11\x1B\x0E\x0F\x0C\x4E\x0F\x0C\x23\x0C\x0E\x12\x0C\x0F\x23\x1A\x12\x19\x13\x11\x1B\x1C\x0C\x17\x0C\x25\x0C\x22\x0D\x1B\x0F\x18\x0C\x0E\x12\x0C\x1B\x1A\x0D\x16\x11\x13\x11\x0C\x1F\x11\x13\x16\x0F\x1E",//Налаштування при бездіяльності. Корисно що б не обпектися і з часом не спалити житло. + /* UIMenu */ "\x26\x0D\x10\x0D\x18\x12\x13\x10\x11\x0C\x19\x0F\x10\x11\x1B\x13\x14\x15\x0D\x16\x21\x0E\x11\x30\x21\x19\x0F\x2D\x0F\x0C\x17\x0E\x13\x12\x10\x40\x12\x24\x1B\x14\x1E",//Параметри користувальницького інтерфейсу. + /* AdvancedMenu */ "\x43\x0F\x25\x27\x11\x10\x12\x0E\x17\x0C\x0E\x0D\x16\x0D\x27\x13\x14\x15\x0D\x0E\x0E\x1C\x1E\x0C\x34\x0F\x1D\x0D\x13\x19\x0F\x15\x17\x0C\x25\x10\x14\x22\x0E\x0F\x1B\x13\x17\x1E",//Розширені налаштування. Додаткові зручності. }; #endif diff --git a/workspace/TS100/Core/Src/gui.cpp b/workspace/TS100/Core/Src/gui.cpp index abb0dadd..c82a1726 100644 --- a/workspace/TS100/Core/Src/gui.cpp +++ b/workspace/TS100/Core/Src/gui.cpp @@ -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,202 +557,41 @@ 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; - 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 = 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 OLED::clearScreen(); OLED::setCursor(0, 0); OLED::drawCheckbox(true); + OLED::printNumber(systemSettings.CalibrationOffset, 4); OLED::refresh(); - osDelay(1000); + osDelay(1200); } -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(); diff --git a/workspace/TS100/Core/Src/hardware.cpp b/workspace/TS100/Core/Src/hardware.cpp index 2fd574a1..080705b2 100644 --- a/workspace/TS100/Core/Src/hardware.cpp +++ b/workspace/TS100/Core/Src/hardware.cpp @@ -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,6 @@ 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 @@ -79,60 +41,15 @@ uint16_t getTipInstantTemperature() { readings[5] = hadc2.Instance->JDR2; readings[6] = hadc2.Instance->JDR3; readings[7] = hadc2.Instance->JDR4; - uint8_t minID = 0, maxID = 0; + for (int i = 0; i < 8; i++) { - if (readings[i] < readings[minID]) - minID = i; - else if (readings[i] > readings[maxID]) - maxID = i; + sum += readings[i]; } - for (int i = 0; i < 8; i++) { - if (i != maxID) - sum += readings[i]; - } - 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 rawTempFilter = { { 0 }, 0, 0 }; +history rawTempFilter = { { 0 }, 0, 0 }; uint16_t getTipRawTemp(uint8_t refresh) { if (refresh) { @@ -333,54 +250,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 +268,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; @@ -475,7 +345,6 @@ void HAL_TIM_PWM_PulseFinishedCallback(TIM_HandleTypeDef *htim) { } } - void vApplicationIdleHook(void) { HAL_IWDG_Refresh(&hiwdg); } diff --git a/workspace/TS100/Core/Src/main.cpp b/workspace/TS100/Core/Src/main.cpp index 488f511a..cbaf4c9e 100644 --- a/workspace/TS100/Core/Src/main.cpp +++ b/workspace/TS100/Core/Src/main.cpp @@ -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 @@ -47,7 +47,7 @@ int main(void) { HAL_Init(); Setup_HAL(); // Setup all the HAL objects HAL_IWDG_Refresh(&hiwdg); - setTipMilliWatts(0); // force tip off + setTipX10Watts(0); // force tip off FRToSI2C::init(&hi2c1); OLED::initialize(); // start up the LCD OLED::setFont(0); // default to bigger font @@ -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) */ @@ -108,11 +106,10 @@ void startPIDTask(void const *argument __unused) { * We take the current tip temperature & evaluate the next step for the tip * control PWM. */ - setTipMilliWatts(0); // disable the output driver if the output is set to be off + setTipX10Watts(0); // disable the output driver if the output is set to be off #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 @@ -121,37 +118,36 @@ void startPIDTask(void const *argument __unused) { #else #endif - history tempError = { { 0 }, 0, 0 }; - currentlyActiveTemperatureTarget = 0; // Force start with no output (off). If in sleep / soldering this will - // be over-ridden rapidly + 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(); 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) { + // 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 (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 // 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); // Now for the PID! - int32_t milliWattsOut = 0; + int32_t x10WattsOut = 0; // P term - total power needed to hit target temp next cycle. // thermal mass = 1690 milliJ/*C for my tip. @@ -160,24 +156,17 @@ 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 x10WattsNeeded = tempToX10Watts(tError); +// tempError.average()); // note that milliWattsNeeded is sometimes negative, this counters overshoot // from I term's inertia. - milliWattsOut += milliWattsNeeded; + x10WattsOut += x10WattsNeeded; // I term - energy needed to compensate for heat loss. // We track energy put into the system over some window. // Assuming the temp is stable, energy in = energy transfered. // (If it isn't, P will dominate). - milliWattsOut += milliWattHistory.average(); + x10WattsOut += x10WattHistory.average(); // D term - use sudden temp change to counter fast cooling/heating. // In practice, this provides an early boost if temp is dropping @@ -185,7 +174,7 @@ void startPIDTask(void const *argument __unused) { // basically: temp - lastTemp // Unfortunately, our temp signal is too noisy to really help. - setTipMilliWatts(milliWattsOut); + setTipX10Watts(x10WattsOut); } else { #ifdef MODEL_TS80 @@ -193,15 +182,15 @@ 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 + setTipX10Watts(25); // typically its around 5W to hold the current temp, so this wont raise temp much } else - setTipMilliWatts(0); + setTipX10Watts(0); //Then wait until the next 0.5 seconds if (xTaskGetTickCount() - lastPowerPulse > 50) { lastPowerPulse = xTaskGetTickCount(); } #else - setTipMilliWatts(0); + setTipX10Watts(0); #endif } @@ -210,7 +199,6 @@ void startPIDTask(void const *argument __unused) { asm("bkpt"); //ADC interrupt timeout - setTipMilliWatts(0); setTipPWM(0); } } @@ -241,7 +229,7 @@ void startMOVTask(void const *argument __unused) { int32_t avgx = 0, avgy = 0, avgz = 0; if (systemSettings.sensitivity > 9) systemSettings.sensitivity = 9; -#if ACCELDEBUG +#ifdef ACCELDEBUG uint32_t max = 0; #endif Orientation rotation = ORIENTATION_FLAT; @@ -288,9 +276,9 @@ void startMOVTask(void const *argument __unused) { osDelay(100); // Slow down update rate #ifdef MODEL_TS80 - if (currentlyActiveTemperatureTarget) { - seekQC(idealQCVoltage, systemSettings.voltageDiv); // Run the QC seek again to try and compensate for cable V drop - } +// if (currentlyActiveTemperatureTarget) { +// seekQC(idealQCVoltage, systemSettings.voltageDiv); // Run the QC seek again to try and compensate for cable V drop +// } #endif } } diff --git a/workspace/TS100/Core/Src/power.cpp b/workspace/TS100/Core/Src/power.cpp index 967a72e9..99887079 100644 --- a/workspace/TS100/Core/Src/power.cpp +++ b/workspace/TS100/Core/Src/power.cpp @@ -12,33 +12,30 @@ const uint16_t powerPWM = 255; const uint16_t totalPWM = 255 + 17; //htim2.Init.Period, the full PWM cycle -history milliWattHistory = { { 0 }, 0, 0 }; +expMovingAverage x10WattHistory = { 0 }; -int32_t tempToMilliWatts(int32_t rawTemp, uint8_t rawC) { +int32_t tempToX10Watts(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 * rawTemp; return milliJoules; } -void setTipMilliWatts(int32_t mw) { - //Enforce Max Watts Limiter # TODO - - int32_t output = milliWattsToPWM(mw, systemSettings.voltageDiv , 1); +void setTipX10Watts(int32_t mw) { + int32_t output = X10WattsToPWM(mw, 1); setTipPWM(output); - uint32_t actualMilliWatts = PWMToMilliWatts(output, - systemSettings.voltageDiv , 0); + uint32_t actualMilliWatts = PWMToX10Watts(output, 0); - milliWattHistory.update(actualMilliWatts); + x10WattHistory.update(actualMilliWatts); } -int32_t availableW10(uint8_t divisor, uint8_t sample) { +uint32_t availableW10(uint8_t sample) { //P = V^2 / R, v*v = v^2 * 100 // R = R*10 // P therefore is in V^2*100/R*10 = W*10. - int32_t v = getInputVoltageX10(divisor, sample); // 100 = 10v - int32_t availableWattsX10 = (v * v) / tipResistance; + uint32_t v = getInputVoltageX10(systemSettings.voltageDiv, sample); // 100 = 10v + uint32_t availableWattsX10 = (v * v) / tipResistance; //However, 100% duty cycle is not possible as there is a dead time while the ADC takes a reading //Therefore need to scale available milliwats by this @@ -50,27 +47,26 @@ int32_t availableW10(uint8_t divisor, uint8_t sample) { return availableWattsX10; } -uint8_t milliWattsToPWM(int32_t milliWatts, uint8_t divisor, uint8_t sample) { - - // Scale input milliWatts to the pwm rate - if (milliWatts < 10) // no pint driving tip +uint8_t X10WattsToPWM(int32_t milliWatts, uint8_t sample) { + // Scale input milliWatts to the pwm range available + if (milliWatts < 1) { + //keep the battery voltage updating the filter + getInputVoltageX10(systemSettings.voltageDiv, sample); return 0; - + } + // if (milliWatts > (int(systemSettings.pidPowerLimit) * 10)) +// milliWatts = (int(systemSettings.pidPowerLimit) * 10); //Calculate desired milliwatts as a percentage of availableW10 - int32_t pwm = (powerPWM * milliWatts) / availableW10(divisor, sample); + uint32_t pwm = (powerPWM * milliWatts) / availableW10(sample); if (pwm > powerPWM) { pwm = powerPWM; //constrain to max PWM counter, shouldnt be possible, but small cost for safety to avoid wraps - } else if (pwm < 0) { //cannot go negative - pwm = 0; } return pwm; } -int32_t PWMToMilliWatts(uint8_t pwm, uint8_t divisor, uint8_t sample) { - int32_t maxMW = availableW10(divisor, sample); //Get the milliwatts for the max pwm period +int32_t PWMToX10Watts(uint8_t pwm, uint8_t sample) { + uint32_t maxMW = availableW10(sample); //Get the milliwatts for the max pwm period //Then convert pwm into percentage of powerPWM to get the percentage of the max mw - int32_t res = (pwm * maxMW) / powerPWM; - if (res < 0) - res = 0; - return res; + return (((uint32_t) pwm) * maxMW) / powerPWM; + } diff --git a/workspace/TS100/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h b/workspace/TS100/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h index c83e14eb..eae02347 100644 --- a/workspace/TS100/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h +++ b/workspace/TS100/Middlewares/Third_Party/FreeRTOS/Source/CMSIS_RTOS/cmsis_os.h @@ -26,7 +26,7 @@ * *---------------------------------------------------------------------------- * - * Portions Copyright 2016 STMicroelectronics International N.V. All rights reserved. + * Portions Copyright � 2016 STMicroelectronics International N.V. All rights reserved. * Portions Copyright (c) 2013 ARM LIMITED * All rights reserved. * Redistribution and use in source and binary forms, with or without @@ -462,7 +462,7 @@ const osThreadDef_t os_thread_def_##name = \ #define osThreadStaticDef(name, thread, priority, instances, stacksz, buffer, control) \ const osThreadDef_t os_thread_def_##name = \ -{ #name, (thread), (priority), (instances), (stacksz), (buffer), (control) } +{(char*) #name, (thread), (priority), (instances), (stacksz), (buffer), (control) } #else //configSUPPORT_STATIC_ALLOCATION == 0 #define osThreadDef(name, thread, priority, instances, stacksz) \ diff --git a/workspace/TS100/build.sh b/workspace/TS100/build.sh index 0efcf1ff..89748dc8 100755 --- a/workspace/TS100/build.sh +++ b/workspace/TS100/build.sh @@ -133,7 +133,9 @@ then checkLastCommand echo "Cleaning previous builds" - make clean 1>/dev/null + rm -rf Hexfile/ >/dev/null + rm -rf Objects/ >/dev/null + make clean >/dev/null checkLastCommand for model in "${BUILD_MODELS[@]}" @@ -141,9 +143,9 @@ then for lang in "${BUILD_LANGUAGES[@]}" do echo "Building firmware for $model in $lang" - make -j16 lang="$lang" model="$model" 1>/dev/null + make -j lang="$lang" model="$model" >/dev/null checkLastCommand - rm -rf Objects/src 1>/dev/null + rm -rf Objects/src>/dev/null done done else