From 24e93d0af5e1d26460d0c710c1e1eb8267b14374 Mon Sep 17 00:00:00 2001 From: -help Date: Tue, 30 Jan 2024 04:27:14 +0200 Subject: [PATCH] Update thermistor placement and pin assignments and impilmented Thermistor Positioning lookup tables that are calculated from the top middle sensor. Need to gather more data and then add the lookup tables. --- src/common.h | 14 ++++ src/displays/tft.cpp | 8 +- src/globals.cpp | 15 ++-- src/globals.h | 9 ++ src/leds/leds.h | 4 +- src/main.cpp | 46 +++++++++-- src/thermistors/Thermistor.cpp | 75 ++++++----------- src/thermistors/Thermistor.h | 39 +++------ src/thermistors/ThermistorLookup.cpp | 88 ++++++++++++++++++++ src/thermistors/ThermistorLookup.h | 118 +++++++++++++++++++++++++++ 10 files changed, 319 insertions(+), 97 deletions(-) create mode 100644 src/thermistors/ThermistorLookup.cpp create mode 100644 src/thermistors/ThermistorLookup.h diff --git a/src/common.h b/src/common.h index 8783f7c..a771b48 100644 --- a/src/common.h +++ b/src/common.h @@ -55,4 +55,18 @@ public: First first; Second second; }; +enum ThermistorZ_Placement +{ + TOP, + BOTTOM +}; + +enum ThermistorXY_Placement +{ + MIDDLE, + SIDE +}; + + + #endif \ No newline at end of file diff --git a/src/displays/tft.cpp b/src/displays/tft.cpp index 6669bff..25e0349 100644 --- a/src/displays/tft.cpp +++ b/src/displays/tft.cpp @@ -62,10 +62,10 @@ void TFT_Display::drawRealTemp(double *temp, float percentage) float temperature = static_cast(*temp); - Serial.print("Time:"); - Serial.print(percentage); - Serial.print(" Temp:"); - Serial.println(temperature); + // Serial.print("Time:"); + // Serial.print(percentage); + // Serial.print(" Temp:"); + // Serial.println(temperature); uint16_t eplased = drawTimer.elapsed(); diff --git a/src/globals.cpp b/src/globals.cpp index 08e50b3..ed09dd9 100644 --- a/src/globals.cpp +++ b/src/globals.cpp @@ -3,9 +3,14 @@ #include "Adafruit_ST7789.h" + WrappedState reflowProcessState = WrappedState(INITIALIZING); + AnalogRef analogRef(5.0); +ThermistorLookup thermistorLookup = ThermistorLookup(); + + // Calibration data for 100K thermistors ->https://datasheet.lcsc.com/lcsc/1810161311_Nanjing-Shiheng-Elec-MF58-104F3950_C123399.pdf ->Glass thermistor NTC 3950 100K TempCalibration calibration_100K_3950 = {25, 100000, 107, 4957, 167, 1000}; // Initalize the 3950 100K thermistors with ACTUAL reference resistor measurnment(Measured between Left pin and GND when the board is powered off) using the default calibration data for 100K thermistor @@ -23,11 +28,11 @@ TempCalibration calibration_100K_3950 = {25, 100000, 107, 4957, 167, 1000}; // To measure the resistence turn off the controller completley and measure between GND and the left pin of the connector with the thermistor unplugged // 2.5k reference = Best accuracy around 138C -Thermistor thermistor1(THERMISTOR1_PIN, 2500, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); -Thermistor thermistor2(THERMISTOR2_PIN, 2500, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); -Thermistor thermistor3(THERMISTOR3_PIN, 2500, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); +Thermistor thermistor1(THERMISTOR1_PIN, 2570, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); +Thermistor thermistor2(THERMISTOR2_PIN, 2520, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE); +Thermistor thermistor3(THERMISTOR3_PIN, 2542, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); // 1k reference = Best accuracy around 173c -Thermistor thermistor4(THERMISTOR4_PIN, 1000, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); +Thermistor thermistor4(THERMISTOR4_PIN, 2545, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); // 515R reference = Best accuracy around 210C Thermistor thermistor5(THERMISTOR5_PIN, 515, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE); // 9k reference = Best accuracy around 90C -> This thermistor is used for the preheat phase if attached @@ -52,8 +57,6 @@ uint16_t cool_COLOR = 0x00a8; - - // These are the reflow profiles that you can choose from, you can add more if you want (up to 5) but you will have to change the nReflowProfiles variable to the number of profiles you have int nReflowProfiles = 3; diff --git a/src/globals.h b/src/globals.h index 7db285c..a401e95 100644 --- a/src/globals.h +++ b/src/globals.h @@ -5,6 +5,7 @@ #include "./reflow.h" #include "./EEPROMDataManager.h" #include "./PID/PidController.h" +#include "./thermistors/ThermistorLookup.h" //Comment out to enable debug messages @@ -20,6 +21,8 @@ #endif + + extern WrappedState reflowProcessState; extern AnalogRef analogRef; extern Thermistor thermistor1; @@ -42,5 +45,11 @@ extern uint16_t reflow_COLOR; extern uint16_t preheat_COLOR; extern uint16_t soak_COLOR; extern uint16_t cool_COLOR; +extern ThermistorLookup thermistorLookup; + + + + + #endif \ No newline at end of file diff --git a/src/leds/leds.h b/src/leds/leds.h index 1cc00c4..dbad881 100644 --- a/src/leds/leds.h +++ b/src/leds/leds.h @@ -9,8 +9,8 @@ // DO NOT TOUCH #define LEFT_LED_PIN 20 //Should be RED -#define MID_LED_PIN 19 //Should be YELLOW -#define RIGHT_LED_PIN 18 //Should be GREEN +#define MID_LED_PIN 18 //Should be YELLOW +#define RIGHT_LED_PIN 19 //Should be GREEN diff --git a/src/main.cpp b/src/main.cpp index e19f834..e4b222b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -14,6 +14,8 @@ #include "EEPROMDataManager.h" #include "thermistors/TemperatureController.h" #include "tools/ExecutionTimer.h" +#include "StopWatch.h" +#include "thermistors/Thermistor.h" #define MOSTFET_PIN 17 @@ -32,11 +34,14 @@ OledDisplay oled = OledDisplay(); TFT_Display tftDisplay; TemperatureController temperatureController; +StopWatch thermTimer = StopWatch(); +StopWatch thermMilisTimer = StopWatch(); + void setup() { pinMode(MOSTFET_PIN, OUTPUT); - analogWrite(MOSTFET_PIN, 255); // VERY IMPORTANT, DONT CHANGE! + analogWrite(MOSTFET_PIN, 255); // VERY IMPORTANT, DONT CHANGE! 255=off, 0=full power Serial.begin(38400); @@ -54,11 +59,15 @@ void setup() temperatureController.checkPluggedInThermistors(); tftDisplay.start(); + + thermTimer.setResolution(StopWatch::Resolution::MILLIS); + thermTimer.start(); + thermMilisTimer.setResolution(StopWatch::Resolution::MILLIS); } void loop() { -// executionTimer.start(); + // executionTimer.start(); // Return the button that changed state Pair> *k = buttons.handleButtons(); @@ -99,6 +108,8 @@ void loop() chosenReflowProfile.start(); // Start the PID pidController.start(); + thermMilisTimer.start(); + Serial.println("Time,Therm1,Therm2,Therm3,Therm4"); } } state = newState; @@ -110,13 +121,36 @@ void loop() { pidController.loop(); - // #ifdef DEBUG - pidController.debug(); - // #endif + // #ifdef DEBUG + // pidController.debug(); + // #endif tftDisplay.drawRealTemp(pidController.getInput(), chosenReflowProfile.getPercentage()); ReflowStep step = chosenReflowProfile.reflowStep(); // Here we draw the actual temp vs time to the display + if (thermTimer.elapsed() > 500) + { + + Serial.print(thermTimer.elapsed()); + Serial.print(","); + Serial.print(thermistor1.getTemperature()); + Serial.print(","); + Serial.print(thermistor2.getTemperature()); + Serial.print(","); + Serial.print(thermistor3.getTemperature()); + Serial.print(","); + Serial.print(thermistor4.getTemperature()); + Serial.print(","); + Serial.print(thermistor1.scalingFactor); + Serial.print(","); + Serial.print(thermistor2.scalingFactor); + Serial.print(","); + Serial.print(thermistor3.scalingFactor); + Serial.print(","); + Serial.print(thermistor4.scalingFactor); + Serial.println(); + } + if (step.state != newState) { reflowProcessState.set(step.state); @@ -127,5 +161,5 @@ void loop() } } -// executionTimer.stop(); + // executionTimer.stop(); } diff --git a/src/thermistors/Thermistor.cpp b/src/thermistors/Thermistor.cpp index a9a6994..de8a26a 100644 --- a/src/thermistors/Thermistor.cpp +++ b/src/thermistors/Thermistor.cpp @@ -1,4 +1,5 @@ #include "Thermistor.h" +#include "../globals.h" /** * @brief Calculates and returns the temperature based on the resistance of the thermistor. @@ -9,9 +10,29 @@ * * @return The temperature in degrees Celsius. */ -float Thermistor::getTemperature() +Thermistor::Thermistor() +{ +} +Thermistor::Thermistor(uint8_t pin, uint16_t resistance, TempCalibration calibration, ThermistorZ_Placement zPlacement1, ThermistorXY_Placement xyPlacment1) : thermistorPin(pin), setRes(resistance), calibration(calibration) +{ + calculateCoefficents(calibration); + + zPlacement = zPlacement1; + + xyPlacment = xyPlacment1; +} +Thermistor::Thermistor(uint8_t pin, uint16_t resistance, ThermistorZ_Placement zPlacement1, ThermistorXY_Placement xyPlacment1) : thermistorPin(pin), setRes(resistance), calibration(calibration_100K_3950) { + calculateCoefficents(calibration); + + zPlacement = zPlacement1; + + xyPlacment = xyPlacment1; +} +float Thermistor::getTemperature() +{ + scalingFactor = 1; // Get an average of 5 readings float temp = 0; @@ -25,14 +46,8 @@ float Thermistor::getTemperature() temp = temp / samples; - // The scaling factor should only be applied when the plate is being heated up -> 60C seems like a good threshold unless you live in the sahara desert with no AC - // Its non-linear so it will be more accurate so we will probably need to impliment a refrence table for the scaling factor this is just a rough estimate it will be based on a sensor calibrated on the top middle of the plate - - //TODO: Impliment a method to calculate the scaling factor based on the placement of the thermistor by measurnment sof refrence center thermistor to other positions - if (temp > 60) - { - temp = temp * scalingFactor; - } + scalingFactor = thermistorLookup.getFactor(zPlacement, xyPlacment, temp); + temp = temp * scalingFactor; return temp; } @@ -84,42 +99,6 @@ bool Thermistor::isPluggedIn() * Calculates the scaling factor for the thermistor based on its placement in the 3D space. * The scaling factor is used to adjust the temperature readings of the thermistor. */ -void Thermistor::calculateScalingFactor() -{ - - switch (zPlacement) - { - case TOP: - switch (xyPlacment) - { - case MIDDLE: - scalingFactor = 1; - break; - case LEFT: - scalingFactor = 1.1; - break; - case RIGHT: - scalingFactor = 1.1; - break; - } - break; - - case BOTTOM: - switch (xyPlacment) - { - case MIDDLE: - scalingFactor = 1.1; - break; - case LEFT: - scalingFactor = 1.2; - break; - case RIGHT: - scalingFactor = 1.2; - break; - } - break; - } -} float Thermistor::getTemperatureFast() { @@ -133,11 +112,7 @@ float Thermistor::getTemperatureFast() // Its non-linear so it will be more accurate so we will probably need to impliment a refrence table for the scaling factor this is just a rough estimate it will be based on a sensor calibrated on the top middle of the plate - if (temp > 60) - { - temp = temp * scalingFactor; - } - + // float scalingFactor = ThermistorLookup::getFactor(thermistorPin, temp); return temp; } diff --git a/src/thermistors/Thermistor.h b/src/thermistors/Thermistor.h index 503aec8..921cc90 100644 --- a/src/thermistors/Thermistor.h +++ b/src/thermistors/Thermistor.h @@ -3,6 +3,9 @@ #include #include +#include + + struct Coefficents { @@ -32,37 +35,16 @@ extern TempCalibration calibration_100K_3950; extern AnalogRef analogRef; -enum ThermistorZ_Placement -{ - TOP, - BOTTOM -}; - -enum ThermistorXY_Placement -{ - MIDDLE, - LEFT, - RIGHT -}; - class Thermistor { public: // Constructor Thermistor(); - Thermistor(uint8_t pin, uint16_t resistance, TempCalibration calibration, ThermistorZ_Placement zPlacement, ThermistorXY_Placement xyPlacment) : thermistorPin(pin), setRes(resistance), calibration(calibration), zPlacement(zPlacement), xyPlacment(xyPlacment) - { - calculateCoefficents(calibration); - calculateScalingFactor(); - } - - Thermistor(uint8_t pin, uint16_t resistance, ThermistorZ_Placement zPlacement, ThermistorXY_Placement xyPlacment) : thermistorPin(pin), setRes(resistance), calibration(calibration_100K_3950), zPlacement(zPlacement), xyPlacment(xyPlacment) - { - calculateCoefficents(calibration); - calculateScalingFactor(); - } + Thermistor(uint8_t pin, uint16_t resistance, TempCalibration calibration, ThermistorZ_Placement zPlacement1, ThermistorXY_Placement xyPlacment1); + Thermistor(uint8_t pin, uint16_t resistance, ThermistorZ_Placement zPlacement1, ThermistorXY_Placement xyPlacment1) ; + // Public Methods float getTemperature(); float getResistance(); @@ -70,14 +52,14 @@ public: uint16_t getPotentiometerResistance() { return setRes; }; // Public Variables void calculateCoefficents(TempCalibration calibration); - float getScalingFactor() { return scalingFactor; }; bool isPluggedIn(); float getTemperatureFast(); + ThermistorXY_Placement xyPlacment; + ThermistorZ_Placement zPlacement; + float scalingFactor ; private: - ThermistorZ_Placement zPlacement; - ThermistorXY_Placement xyPlacment; const double K = 273.15; float sensorResistance; uint8_t thermistorPin; @@ -85,8 +67,7 @@ private: Coefficents coefficents; float referenceResistance; TempCalibration calibration; - float scalingFactor; - void calculateScalingFactor(); + }; #endif // THERMISTOR_H diff --git a/src/thermistors/ThermistorLookup.cpp b/src/thermistors/ThermistorLookup.cpp new file mode 100644 index 0000000..f83535e --- /dev/null +++ b/src/thermistors/ThermistorLookup.cpp @@ -0,0 +1,88 @@ +#include "ThermistorLookup.h" + +ThermistorLookup::ThermistorLookup() +{ +} + +ThermistorLookup::~ThermistorLookup() +{ +} + +float ThermistorLookup::getFactor(ThermistorZ_Placement zPlacement, ThermistorXY_Placement xyPlacment, uint8_t temperature) +{ + const LookupEntry *lookupTable = getTable(zPlacement, xyPlacment); + int numEntries = tableSize; + + if (lookupTable == noScaling) + { + return 1; + } + else + { + // Handle boundary cases + if (temperature <= lookupTable[0].temperature) + { + return lookupTable[0].value; + } + if (temperature >= lookupTable[numEntries - 1].temperature) + { + return lookupTable[numEntries - 1].value; + } + + // Find the interval containing the temperature + for (int i = 0; i < numEntries - 1; ++i) + { + if (temperature >= lookupTable[i].temperature && temperature < lookupTable[i + 1].temperature) + { + // Perform linear interpolation + uint8_t t0 = lookupTable[i].temperature; + float v0 = lookupTable[i].value; + uint8_t t1 = lookupTable[i + 1].temperature; + float v1 = lookupTable[i + 1].value; + + float slope = (v1 - v0) / (t1 - t0); + return v0 + slope * (temperature - t0); + } + } + } + // This point should never be reached + return 1; +} + +const LookupEntry *ThermistorLookup::getTable(ThermistorZ_Placement zPlacement, ThermistorXY_Placement xyPlacment) +{ + tableSize = 0; + switch (zPlacement) + { + case TOP: + switch (xyPlacment) + { + case MIDDLE: + + tableSize = sizeof(noScaling) / sizeof(LookupEntry); + return noScaling; + case SIDE: + + tableSize = sizeof(lookupTopSide) / sizeof(LookupEntry); + return lookupTopSide; + } + case BOTTOM: + + switch (xyPlacment) + { + case MIDDLE: + + tableSize = sizeof(lookupBottomMiddle) / sizeof(LookupEntry); + return lookupBottomMiddle; + case SIDE: + + tableSize = sizeof(lookupTopSide) / sizeof(LookupEntry); + return lookupTopSide; + } + } +} + +float ThermistorLookup::interpolate(float x, float x0, float x1, float y0, float y1) +{ + return y0 + (x - x0) * (y1 - y0) / (x1 - x0); +} diff --git a/src/thermistors/ThermistorLookup.h b/src/thermistors/ThermistorLookup.h new file mode 100644 index 0000000..a96bdbd --- /dev/null +++ b/src/thermistors/ThermistorLookup.h @@ -0,0 +1,118 @@ +#ifndef THERMISTOR_LOOKUP_H +#define THERMISTOR_LOOKUP_H + +#include +#include + +struct LookupEntry +{ + uint8_t temperature; + float value; +}; + +const LookupEntry lookupBottomMiddle[] = { + {30, 0.995205469483767}, + {35, 1.11724354649558}, + {40, 1.16221262415921}, + {45, 1.12448359746383}, + {50, 1.14499238909032}, + {55, 1.12793950375559}, + {60, 1.12337287712101}, + {65, 1.10545110139771}, + {70, 1.10234749124935}, + {75, 1.08567465426014}, + {80, 1.07869989037226}, + {85, 1.06930433073885}, + {90, 1.0538318430518}, + {95, 1.03201418470286}, + {100, 1.01896914997622}, + {105, 1.03251768817139}, + {110, 1.04022066012968}, + {115, 1.03674422635691}, + {120, 1.04064666742085}, + {125, 1.03913188754372}, + {130, 1.0442917352224}, + {135, 1.04499116157739}, + {140, 1.04135817519154}, + {145, 1.03658285343317}, + {150, 1.0259509365488}, + {155, 1.02598110989319}, + {160, 1.03930608139151}, + {165, 1.03583584549012}, + {170, 1.03308702915583}, + {175, 1.03114013373797}, + {180, 1.01800272746916}, + {185, 1.0084029872169}, + +}; + +const LookupEntry lookupTopSide[] = { + {30, 0.995205469483767}, + {35, 1.11724354649558}, + {40, 1.16221262415921}, + {45, 1.12448359746383}, + {50, 1.14499238909032}, + {55, 1.12793950375559}, + {60, 1.12337287712101}, + {65, 1.10545110139771}, + {70, 1.10234749124935}, + {75, 1.08567465426014}, + {80, 1.07869989037226}, + {85, 1.06930433073885}, + {90, 1.0538318430518}, + {95, 1.03201418470286}, + {100, 1.01896914997622}, + {105, 1.03251768817139}, + {110, 1.04022066012968}, + {115, 1.03674422635691}, + {120, 1.03245955349587}, + {125, 0.985668882970875}, + {130, 1.0020830920359}, + {135, 0.992462503013065}, + {140, 0.991221866504337}, + {145, 1.00439387665255}, + {150, 1.00334435684778}, + {155, 0.999788726679194}, + {160, 1.00049372788227}, + {165, 1.00610676732641}, + {170, 0.998992362621583}, + {175, 1.00239035441939}, + {180, 1.00496908541176}, + {185, 1.0084029872169}}; + +const LookupEntry noScaling[]{ + + {100, 1.4}, + + {423, 5342}, + + {423, 532} + +}; + +class ThermistorLookup +{ + +public: + ThermistorLookup(); + ~ThermistorLookup(); + + // Add your member functions and variables here + + float getFactor(ThermistorZ_Placement zPlacement, ThermistorXY_Placement xyPlacment, uint8_t temperature); + + const LookupEntry *getTable(ThermistorZ_Placement zPlacement, ThermistorXY_Placement xyPlacment); + + // Function to get the size of a lookup table + template + constexpr size_t getLookupTableSize(const LookupEntry (&)[N]) + { + return N; + } + float interpolate(float x, float x0, float x1, float y0, float y1); + uint8_t tableSize; + +private: +}; + +#endif // THERMISTOR_LOOKUP_H