Tweakinmg reflow profiles and auto select. Works good now

This commit is contained in:
-help 2024-02-01 05:42:19 +02:00
parent f62a71352e
commit 8b78c29abc
12 changed files with 185 additions and 136 deletions

View File

@ -4,7 +4,6 @@
#include <Arduino.h>
#include <ArduPID.h>
struct PidControllerData { double currentTemp; double setPoint; double targetTemp;};
class PidController

View File

@ -1,6 +1,7 @@
#ifndef __basestatechange_h__
#define __basestatechange_h__
#include <Arduino.h>
template <typename State>
class StateChangeEvent
{
@ -58,7 +59,9 @@ public:
enum ThermistorZ_Placement
{
TOP,
BOTTOM
BOTTOM,
ON_PCB
};
enum ThermistorXY_Placement
@ -66,7 +69,7 @@ enum ThermistorXY_Placement
MIDDLE,
SIDE,
MIDDLE_LOW_TEMP,
MIDDLE_HIGH_TEMP
MIDDLE_HIGH_TEMP,
};

View File

@ -1,6 +1,7 @@
#include "./globals.h"
#include "./EEPROMDataManager.h"
#include "Adafruit_ST7789.h"
#include "thermistors/TemperatureController.h"
@ -30,7 +31,7 @@ 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, 2545 , ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE);
Thermistor thermistor1(THERMISTOR1_PIN, 2545 , ThermistorZ_Placement::ON_PCB, ThermistorXY_Placement::MIDDLE);
Thermistor thermistor2(THERMISTOR2_PIN, 2125, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE);
Thermistor thermistor3(THERMISTOR3_PIN, 9100, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_LOW_TEMP);
// 1k reference = Best accuracy around 173c
@ -66,9 +67,9 @@ int nReflowProfiles = 3;
ReflowProfile reflowProfiles[] = {
// 138c profile Sn42Bi58
ReflowProfile(new ReflowStep[5]{
ReflowStep(ReflowProcessState::PREHEAT, 100, 100, EASE_IN),
ReflowStep(ReflowProcessState::PREHEAT, 100, 100, EASE_OUT),
ReflowStep(ReflowProcessState::SOAK, 90, 140,EASE_IN_OUT),
ReflowStep(ReflowProcessState::REFLOW, 90, 185, HALF_SINE),
ReflowStep(ReflowProcessState::REFLOW, 90, 170, HALF_SINE),
ReflowStep(ReflowProcessState::COOL, 50, 85, EASE_IN),
ReflowStep(ReflowProcessState::DONE, 0, 0)},
"138c Sn42Bi58\0"),
@ -94,3 +95,4 @@ EEPROMDataManager eepromDataManager = EEPROMDataManager();
PidControllerData pidControllerData = {0 /*currentTemp*/, 60 /*TargetTemp*/, 255 /*PWM*/};
PidController pidController = PidController(&pidControllerData);
;

View File

@ -1,11 +1,18 @@
#ifndef GLOBALS_H
#define GLOBALS_H
#include "./common.h"
#include "./thermistors/Thermistor.h"
#include "./thermistors/ThermistorLookup.h"
#include "./reflow.h"
#include "./EEPROMDataManager.h"
#include "./PID/PidController.h"
#include "./thermistors/ThermistorLookup.h"
#include "./thermistors/TemperatureController.h"
@ -29,11 +36,14 @@
//PID Controller values
#define PID_P 2
#define PID_I 2
#define PID_D 5
#define PID_WINDUP_MIN -100
#define PID_WINDUP_MAX 255
#define PID_P .3
#define PID_I 1
#define PID_D .2
#define PID_WINDUP_MIN 60
#define PID_WINDUP_MAX -20
//This gets reversed inside the PID controller
#define PID_OUTPUT_MIN 0
#define PID_OUTPUT_MAX 255
@ -64,6 +74,7 @@ extern uint16_t reflow_COLOR;
extern uint16_t preheat_COLOR;
extern uint16_t soak_COLOR;
extern uint16_t cool_COLOR;
extern ThermistorLookup thermistorLookup;
@ -72,4 +83,8 @@ extern ThermistorLookup thermistorLookup;
#endif

View File

@ -15,7 +15,7 @@
#include "tools/ExecutionTimer.h"
#include "StopWatch.h"
#include "thermistors/Thermistor.h"
#include "thermistors/TemperatureController.h"
#define MOSTFET_PIN 17
@ -25,7 +25,8 @@ double pwmValue = 255;
ExecutionTimer executionTimer;
TemperatureController tempController;
TemperatureController tempController ;
Buttons buttons = Buttons();
LEDS leds = LEDS();
@ -107,12 +108,12 @@ void loop()
tftDisplay.init(&chosenReflowProfile);
tempController.checkPluggedInThermistors();
chosenReflowProfile.start();
chosenReflowProfile.start(tempController.getPlateTemperature());
// Start the PID
pidController.start();
thermMilisTimer.start();
thermTimer.start();
Serial.println("Time,Therm1,Therm2,Therm3,Therm4,Therm5,Therm6,,Scaling1,Scaling2,Scaling3,Scaling4,Scaling5,Scaling6,Averaged1,Weighting1,Weighting2,Weighting3");
//Serial.println("Time,Therm1,Therm2,Therm3,Therm4,Therm5,Therm6,,Scaling1,Scaling2,Scaling3,Scaling4,Scaling5,Scaling6,Averaged1,Weighting1,Weighting2,Weighting3");
}
}
state = newState;

View File

@ -1,13 +1,11 @@
#ifndef __reflow_h__
#define __reflow_h__
#ifndef _REFLOW_PROCESSSTATE_H_
#define _REFLOW_PROCESSSTATE_H_
#include "./common.h"
#include <EEPROM.h>
#include "StopWatch.h"
#include "thermistors/Thermistor.h"
#include "PID/PidController.h"
extern PidController pidController;
// STATE MACHINE
enum ReflowProcessState
@ -41,6 +39,7 @@ enum ReflowStepEaseFunction
MID_RAMP_HOLD,
FAST_RAMP_HOLD
};
class ReflowStep
{
public:
@ -111,11 +110,16 @@ public:
}
}
};
#endif
#ifndef __reflow_h__
#define __reflow_h__
#define PROFILE_SERIALIZED_SIZE 40
#define PROFILE_SERIALIZED_NAME_SIZE 20
#define STEPINDEX(step) (step.state - PREHEAT)
#define TOMILLIS(x) (((uint32_t)x) * (uint32_t)1000)
class ReflowProfile
{
public:
@ -140,11 +144,13 @@ public:
uint8_t endTemps[5] = {0};
uint8_t startTemps[5] = {0};
StopWatch timer;
uint8_t plateTemp = 0;
void start()
void start(uint8_t plateTemp)
{
timer = StopWatch(StopWatch::MILLIS);
timer.start();
this->plateTemp = plateTemp;
}
void calculateValues()
@ -163,8 +169,15 @@ public:
// We will grab the current PCB temp from the PID as the start temp otherwise the PID will be off
if (plateTemp > 30 && plateTemp < 60)
{
startTemps[0] = plateTemp; // USe ambient temp as the starting temp for the first step
}
startTemps[0] = 20; // USe ambient temp as the starting temp for the first step
else
{
startTemps[0] = 20;
}
endTemps[0] = steps[0].calcTempAtPercentage(startTemps[0], 1);
endTemps[1] = steps[1].calcTempAtPercentage(endTemps[0], 1);

View File

@ -1,5 +1,8 @@
#include "TemperatureController.h"
extern Thermistor thermistors[6];
TemperatureController::TemperatureController()
{
}
@ -37,8 +40,8 @@ void TemperatureController::checkPluggedInThermistors()
// debugC(isPluggedIn == 1 ? "true" : "false");
}
debugC("Active thermistor count: ");
debugC(activeThermistorCount);
Serial.print("Active thermistor count: ");
Serial.println(activeThermistorCount);
}
float TemperatureController::getThermistorTempFast(uint8_t thermistorIndex)

View File

@ -6,7 +6,7 @@
extern Thermistor thermistors[6];
class TemperatureController
{

View File

@ -64,6 +64,16 @@ float Thermistor::getTemperature()
*/
float Thermistor::getWeightingFactor()
{
// If the thermistor is mounted on PCB we give it a weighting factor of 10
switch (zPlacement)
{
case ON_PCB:
return 10;
break;
}
switch (xyPlacment)
{
@ -98,119 +108,118 @@ float Thermistor::getWeightingFactor()
return 0.1;
}
case MIDDLE_HIGH_TEMP:
case MIDDLE_HIGH_TEMP:
if (currenTemperature > MIDDLE_TEMP_THRESHOLD && currenTemperature < HIGH_TEMP_THRESHOLD)
{
return ThermistorLookup::interpolate(currenTemperature, MIDDLE_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD, 1, 1.5);
}
else if (currenTemperature > HIGH_TEMP_THRESHOLD)
{
return 1.5;
}
else if (currenTemperature < MIDDLE_TEMP_THRESHOLD)
{
return ThermistorLookup::interpolate(currenTemperature, START_TEMP, MIDDLE_TEMP_THRESHOLD, 0.1, 1);
}
else
{
return 0.1;
}
break;
default:
return 1;
break;
}
}
/**
* Calculates the coefficients for the thermistor based on the given temperature calibration.
*
* @param calibration The temperature calibration data.
*/
void Thermistor::calculateCoefficents(TempCalibration calibration)
{
float lowK = calibration.lowC + K;
float midK = calibration.midC + K;
float highK = calibration.highC + K;
float lowLnr = log(calibration.lowR);
float midLnr = log(calibration.midR);
float highLnr = log(calibration.highR);
float ln1 = lowLnr - midLnr;
float ln2 = lowLnr - highLnr;
float t1 = (1 / lowK) - (1 / midK);
float t2 = (1 / lowK) - (1 / highK);
float c = (t1 - ln1 * t2 / ln2) / ((pow(lowLnr, 3) - pow(midLnr, 3)) - ln1 * (pow(lowLnr, 3) - pow(highLnr, 3)) / ln2);
float b = (t1 - c * (pow(lowLnr, 3) - pow(midLnr, 3))) / ln1;
float a = 1 / lowK - c * pow(lowLnr, 3) - b * lowLnr;
coefficents.a = (a);
coefficents.b = (b);
coefficents.c = (c);
}
bool Thermistor::isPluggedIn()
{
// check if the resistnece is INF is so then the thermistor is not plugged in
if (getResistance() == INFINITY)
if (currenTemperature > MIDDLE_TEMP_THRESHOLD && currenTemperature < HIGH_TEMP_THRESHOLD)
{
return false;
return ThermistorLookup::interpolate(currenTemperature, MIDDLE_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD, 1, 1.5);
}
else if (currenTemperature > HIGH_TEMP_THRESHOLD)
{
return 1.5;
}
else if (currenTemperature < MIDDLE_TEMP_THRESHOLD)
{
return ThermistorLookup::interpolate(currenTemperature, START_TEMP, MIDDLE_TEMP_THRESHOLD, 0.1, 1);
}
else
{
return true;
return 0.1;
}
break;
default:
return 1;
break;
}
}
/**
* 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.
*/
/**
* Calculates the coefficients for the thermistor based on the given temperature calibration.
*
* @param calibration The temperature calibration data.
*/
void Thermistor::calculateCoefficents(TempCalibration calibration)
{
float Thermistor::getTemperatureFast()
float lowK = calibration.lowC + K;
float midK = calibration.midC + K;
float highK = calibration.highC + K;
float lowLnr = log(calibration.lowR);
float midLnr = log(calibration.midR);
float highLnr = log(calibration.highR);
float ln1 = lowLnr - midLnr;
float ln2 = lowLnr - highLnr;
float t1 = (1 / lowK) - (1 / midK);
float t2 = (1 / lowK) - (1 / highK);
float c = (t1 - ln1 * t2 / ln2) / ((pow(lowLnr, 3) - pow(midLnr, 3)) - ln1 * (pow(lowLnr, 3) - pow(highLnr, 3)) / ln2);
float b = (t1 - c * (pow(lowLnr, 3) - pow(midLnr, 3))) / ln1;
float a = 1 / lowK - c * pow(lowLnr, 3) - b * lowLnr;
coefficents.a = (a);
coefficents.b = (b);
coefficents.c = (c);
}
bool Thermistor::isPluggedIn()
{
// check if the resistnece is INF is so then the thermistor is not plugged in
if (getResistance() == INFINITY)
{
// Get only one reading
getResistance();
float temp = (int)1 / (coefficents.a + coefficents.b * log(sensorResistance) + coefficents.c * (pow(log(sensorResistance), 3))) - K;
// 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
// float scalingFactor = ThermistorLookup::getFactor(thermistorPin, temp);
return temp;
return false;
}
float Thermistor::getResistance()
else
{
float systemVoltage = analogRef.calculateSystemVoltage();
// int raw = analogRead(thermistorPin);
// // Get resistance value
// float buffer = raw * systemVoltage;
// float vOut = (buffer) / 1023;
// // Calculate the resistance of the thermistor with the system voltage accounted for
// buffer = (systemVoltage / vOut) - 1;
// // return the resistence
// sensorResistance = setRes * buffer;
int sensorValue = analogRead(thermistorPin); // Read the analog value (0-1023)
float voltage = sensorValue * (systemVoltage / 1023.0); // Convert to voltage
float R_unknown = (setRes * (systemVoltage - voltage)) / voltage; // Calculate the unknown resistor's value
sensorResistance = R_unknown;
return sensorResistance;
return true;
}
}
/**
* 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.
*/
float Thermistor::getTemperatureFast()
{
// Get only one reading
getResistance();
float temp = (int)1 / (coefficents.a + coefficents.b * log(sensorResistance) + coefficents.c * (pow(log(sensorResistance), 3))) - K;
// 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
// float scalingFactor = ThermistorLookup::getFactor(thermistorPin, temp);
return temp;
}
float Thermistor::getResistance()
{
float systemVoltage = analogRef.calculateSystemVoltage();
// int raw = analogRead(thermistorPin);
// // Get resistance value
// float buffer = raw * systemVoltage;
// float vOut = (buffer) / 1023;
// // Calculate the resistance of the thermistor with the system voltage accounted for
// buffer = (systemVoltage / vOut) - 1;
// // return the resistence
// sensorResistance = setRes * buffer;
int sensorValue = analogRead(thermistorPin); // Read the analog value (0-1023)
float voltage = sensorValue * (systemVoltage / 1023.0); // Convert to voltage
float R_unknown = (setRes * (systemVoltage - voltage)) / voltage; // Calculate the unknown resistor's value
sensorResistance = R_unknown;
return sensorResistance;
}

View File

@ -5,6 +5,8 @@
#include <voltageReference/AnalogRef.h>
#include <common.h>
struct Coefficents
{
float a;

View File

@ -66,6 +66,11 @@ const LookupEntry *ThermistorLookup::getTable(ThermistorZ_Placement zPlacement,
tableSize = sizeof(lookupSide) / sizeof(LookupEntry);
return lookupSide;
case ON_PCB:
return noScaling;
}
case BOTTOM:
@ -80,16 +85,15 @@ const LookupEntry *ThermistorLookup::getTable(ThermistorZ_Placement zPlacement,
tableSize = sizeof(lookupSide) / sizeof(LookupEntry);
return lookupSide;
case MIDDLE_LOW_TEMP:
case MIDDLE_LOW_TEMP:
tableSize = sizeof(lookupBottomMiddle) / sizeof(LookupEntry);
return lookupBottomMiddle;
case MIDDLE_HIGH_TEMP:
case MIDDLE_HIGH_TEMP:
tableSize = sizeof(lookupBottomMiddle) / sizeof(LookupEntry);
return lookupBottomMiddle;
}
}
}

View File

@ -170,10 +170,8 @@ const LookupEntry lookupSide[] = {
const LookupEntry noScaling[]{
{0, 1},
{100, 1},
{200, 1}
{300, 1}
};