mirror of
https://github.com/arwidcool/Solder-Plate.git
synced 2025-02-17 19:09:23 +01:00
Tweakinmg reflow profiles and auto select. Works good now
This commit is contained in:
parent
f62a71352e
commit
8b78c29abc
@ -4,7 +4,6 @@
|
||||
#include <Arduino.h>
|
||||
#include <ArduPID.h>
|
||||
|
||||
|
||||
struct PidControllerData { double currentTemp; double setPoint; double targetTemp;};
|
||||
|
||||
class PidController
|
||||
|
@ -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,
|
||||
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
;
|
||||
|
@ -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
|
@ -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;
|
||||
|
29
src/reflow.h
29
src/reflow.h
@ -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);
|
||||
|
@ -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)
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
|
||||
|
||||
extern Thermistor thermistors[6];
|
||||
|
||||
|
||||
class TemperatureController
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -5,6 +5,8 @@
|
||||
#include <voltageReference/AnalogRef.h>
|
||||
#include <common.h>
|
||||
|
||||
|
||||
|
||||
struct Coefficents
|
||||
{
|
||||
float a;
|
||||
|
@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -170,10 +170,8 @@ const LookupEntry lookupSide[] = {
|
||||
const LookupEntry noScaling[]{
|
||||
|
||||
{0, 1},
|
||||
|
||||
{100, 1},
|
||||
|
||||
{200, 1}
|
||||
{300, 1}
|
||||
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user