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.

This commit is contained in:
-help 2024-01-30 04:27:14 +02:00
parent 058d4c06a2
commit 24e93d0af5
10 changed files with 319 additions and 97 deletions

View File

@ -55,4 +55,18 @@ public:
First first;
Second second;
};
enum ThermistorZ_Placement
{
TOP,
BOTTOM
};
enum ThermistorXY_Placement
{
MIDDLE,
SIDE
};
#endif

View File

@ -62,10 +62,10 @@ void TFT_Display::drawRealTemp(double *temp, float percentage)
float temperature = static_cast<float>(*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();

View File

@ -3,9 +3,14 @@
#include "Adafruit_ST7789.h"
WrappedState<ReflowProcessState> reflowProcessState = WrappedState<ReflowProcessState>(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;

View File

@ -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> 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

View File

@ -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

View File

@ -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<ButtonKind, StateChangeEvent<ButtonState>> *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;
@ -111,12 +122,35 @@ void loop()
pidController.loop();
// #ifdef DEBUG
pidController.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();
}

View File

@ -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)
{
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;
}

View File

@ -3,6 +3,9 @@
#include <Arduino.h>
#include <voltageReference/AnalogRef.h>
#include <common.h>
struct Coefficents
{
@ -32,36 +35,15 @@ 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, TempCalibration calibration, ThermistorZ_Placement zPlacement1, ThermistorXY_Placement xyPlacment1);
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, ThermistorZ_Placement zPlacement1, ThermistorXY_Placement xyPlacment1) ;
// Public Methods
float getTemperature();
@ -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

View File

@ -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);
}

View File

@ -0,0 +1,118 @@
#ifndef THERMISTOR_LOOKUP_H
#define THERMISTOR_LOOKUP_H
#include <Arduino.h>
#include <common.h>
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 <size_t N>
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