mirror of
https://github.com/arwidcool/Solder-Plate.git
synced 2024-11-12 01:10:52 +01:00
Added temperature controller as main calc for temp used by PID and all display menus where applicable. Adjusted lookup table for opitions and added the PID settings to global
This commit is contained in:
parent
2a78a70c19
commit
620508b53c
@ -2,22 +2,22 @@
|
||||
#include "globals.h"
|
||||
#define MOSTFET_PIN 17
|
||||
#include "voltageReference/AnalogRef.h"
|
||||
#include "thermistors/TemperatureController.h"
|
||||
|
||||
extern AnalogRef analogRef;
|
||||
|
||||
extern TemperatureController tempController;
|
||||
|
||||
PidController::PidController(PidControllerData *data)
|
||||
{
|
||||
|
||||
this->data = data;
|
||||
kp = 5;
|
||||
kd = 10;
|
||||
ki = 1;
|
||||
|
||||
controller.begin(&(this->data->currentTemp), &(this->data->setPoint), &(this->data->targetTemp), kp, ki, kd);
|
||||
controller.begin(&(this->data->currentTemp), &(this->data->setPoint), &(this->data->targetTemp), PID_P, PID_I, PID_D);
|
||||
controller.reverse();
|
||||
controller.setOutputLimits(0, 255);
|
||||
//controller.setSampleTime(20);
|
||||
controller.setWindUpLimits(-100, 185);
|
||||
controller.setOutputLimits(PID_OUTPUT_MIN, PID_OUTPUT_MAX);
|
||||
controller.setSampleTime(PID_SAMPLE_TIME);
|
||||
controller.setWindUpLimits(PID_WINDUP_MIN, PID_WINDUP_MAX);
|
||||
}
|
||||
|
||||
double *PidController::compute()
|
||||
@ -37,12 +37,15 @@ void PidController::debug()
|
||||
}
|
||||
|
||||
void PidController::loop()
|
||||
|
||||
{
|
||||
data->targetTemp = chosenReflowProfile.getTargetTemp();
|
||||
|
||||
data->currentTemp = thermistor1.getTemperature();
|
||||
|
||||
float sysVoltage = analogRef.calculateSystemVoltage();
|
||||
// data->currentTemp = thermistor1.getTemperature();
|
||||
|
||||
data->currentTemp = tempController.getPlateTemperature();
|
||||
|
||||
// float sysVoltage = analogRef.calculateSystemVoltage();
|
||||
compute();
|
||||
analogWrite(MOSTFET_PIN, data->setPoint);
|
||||
}
|
||||
@ -55,17 +58,14 @@ void PidController::stop()
|
||||
analogWrite(MOSTFET_PIN, 255); // VERY IMPORTANT, DONT CHANGE!
|
||||
controller.reset();
|
||||
controller.stop();
|
||||
|
||||
|
||||
}
|
||||
|
||||
void PidController::start()
|
||||
{
|
||||
controller.start();
|
||||
|
||||
}
|
||||
|
||||
double* PidController::getInput()
|
||||
double *PidController::getInput()
|
||||
{
|
||||
return controller.input;
|
||||
}
|
||||
|
@ -21,14 +21,10 @@ public:
|
||||
void start();
|
||||
|
||||
double* getInput();
|
||||
|
||||
boolean started = false;
|
||||
|
||||
private:
|
||||
ArduPID controller;
|
||||
double kp;
|
||||
double ki;
|
||||
double kd;
|
||||
PidControllerData *data;
|
||||
double integral;
|
||||
double previousError;
|
||||
|
@ -2,6 +2,7 @@
|
||||
#include <Arduino.h>
|
||||
#include "../globals.h"
|
||||
#include "./menustatemachine.h"
|
||||
#include "./thermistors/TemperatureController.h"
|
||||
#define SCREEN_WIDTH 128
|
||||
#define SCREEN_HEIGHT 64
|
||||
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
|
||||
@ -10,6 +11,8 @@
|
||||
#define MENUID_PICK_PROFILE 100
|
||||
#define MENUITEM_PROFILE_START 100
|
||||
|
||||
extern TemperatureController tempController;
|
||||
|
||||
unsigned long lastProcessedReflowState = 0;
|
||||
OledDisplay::OledDisplay()
|
||||
{
|
||||
@ -46,6 +49,7 @@ void OledDisplay::handleButtonStateChange(Pair<ButtonKind, StateChangeEvent<Butt
|
||||
OledMenu *selectedMenu = curMenu->getNextMenu();
|
||||
if (selectedMenu != NULL)
|
||||
{
|
||||
tempController.checkPluggedInThermistors();
|
||||
curMenu = selectedMenu;
|
||||
}
|
||||
}
|
||||
@ -79,7 +83,9 @@ void OledDisplay::handleButtonStateChange(Pair<ButtonKind, StateChangeEvent<Butt
|
||||
}
|
||||
|
||||
void OledDisplay::handleDrawThermistorMenu(OledMenuItem menuItem)
|
||||
|
||||
{
|
||||
|
||||
int thermistorIndex = menuItem.identifier - MENUITEM_THERMISTOR_START;
|
||||
// Serial.println("Thermistor index: " + String(thermistorIndex));
|
||||
if (thermistorIndex == 6)
|
||||
@ -103,7 +109,7 @@ void OledDisplay::handleDrawThermistorMenu(OledMenuItem menuItem)
|
||||
{
|
||||
float thermR = thermistors[i].getResistance() / 1000;
|
||||
display.setCursor(i < 3 ? 0 : (SCREEN_WIDTH / 2 + 20), 20 * (i % 3));
|
||||
//A bit more data if it is a small number
|
||||
// A bit more data if it is a small number
|
||||
if (thermR < 100)
|
||||
{
|
||||
decimalPlaces = 2;
|
||||
@ -215,7 +221,7 @@ void OledDisplay::loop()
|
||||
display.setRotation(0);
|
||||
display.setTextSize(2);
|
||||
drawPositionedText("DONE :)", DisplayTextAlignment::CENTER, DisplayTextAlignment::START);
|
||||
uint8_t curTemp = thermistor1.getTemperature();
|
||||
uint8_t curTemp = tempController.getPlateTemperature();
|
||||
display.setTextSize(1, 2);
|
||||
drawPositionedText("Temperature", DisplayTextAlignment::START, DisplayTextAlignment::CENTER);
|
||||
drawPositionedText((String(curTemp) + " C").c_str(), DisplayTextAlignment::END, DisplayTextAlignment::CENTER);
|
||||
@ -236,7 +242,7 @@ void OledDisplay::drawDebug()
|
||||
{
|
||||
float sysVoltage = analogRef.calculateSystemVoltage();
|
||||
float inputVoltage = analogRef.calculateInputVoltage();
|
||||
int thermistor1Temp = thermistor1.getTemperature();
|
||||
int plateTemp = tempController.getPlateTemperature();
|
||||
display.clearDisplay();
|
||||
display.setTextSize(2);
|
||||
display.setTextColor(SSD1306_WHITE);
|
||||
@ -245,7 +251,7 @@ void OledDisplay::drawDebug()
|
||||
display.setCursor(0, 20);
|
||||
display.println("In V:" + String(inputVoltage));
|
||||
display.setCursor(0, 40);
|
||||
display.println("C: " + String(thermistor1Temp));
|
||||
display.println("C: " + String(plateTemp));
|
||||
display.display();
|
||||
}
|
||||
void OledDisplay::displayIndicators()
|
||||
@ -328,8 +334,11 @@ void OledDisplay::handleReflowState()
|
||||
drawPositionedText("Remaining", DisplayTextAlignment::START, DisplayTextAlignment::CENTER);
|
||||
drawPositionedText((String(chosenReflowProfile.reflowStep().duration - elapsedStep) + "s").c_str(), DisplayTextAlignment::START, DisplayTextAlignment::END);
|
||||
|
||||
// tempController.getPlateTemperature();
|
||||
|
||||
// Current temp center right + bottom right
|
||||
uint8_t curTemp = thermistor1.getTemperature();
|
||||
|
||||
uint8_t curTemp = pidControllerData.currentTemp;
|
||||
uint8_t targetTemp = pidControllerData.targetTemp;
|
||||
drawPositionedText(("Curr.: " + String(curTemp)).c_str(), DisplayTextAlignment::END, DisplayTextAlignment::CENTER);
|
||||
drawPositionedText(("Target: " + String(targetTemp)).c_str(), DisplayTextAlignment::END, DisplayTextAlignment::END);
|
||||
|
@ -3,6 +3,9 @@
|
||||
#include <Adafruit_SSD1306.h>
|
||||
#include "../reflow.h"
|
||||
#include "menustatemachine.h"
|
||||
|
||||
|
||||
|
||||
enum DisplayTextAlignment {
|
||||
START,
|
||||
CENTER,
|
||||
|
@ -311,7 +311,7 @@ void TFT_Display::drawGraphAxisTickLabels()
|
||||
// Draw three tick labels on the time axis at 1/4, 1/2 and 3/4 of the way along
|
||||
for (int i = 1; i <= 3; i++)
|
||||
{
|
||||
uint8_t time = totalTime * i / 4;
|
||||
uint16_t time = totalTime * i / 4;
|
||||
char *timeCharPtr = numberToCharPtr(time);
|
||||
position = getCenterAlignedBottomTextXY(timeCharPtr, graphXY.x + (graphWidth * i / 4), graphXY.y);
|
||||
tft.setCursor(position.x, position.y + tickMarkLength + 1);
|
||||
|
@ -4,6 +4,8 @@
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
WrappedState<ReflowProcessState> reflowProcessState = WrappedState<ReflowProcessState>(INITIALIZING);
|
||||
|
||||
AnalogRef analogRef(5.0);
|
||||
@ -28,15 +30,15 @@ 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, 2465 , ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE);
|
||||
Thermistor thermistor2(THERMISTOR2_PIN, 2520, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE);
|
||||
Thermistor thermistor3(THERMISTOR3_PIN, 9040, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_LOW_TEMP);
|
||||
Thermistor thermistor1(THERMISTOR1_PIN, 2545 , ThermistorZ_Placement::TOP, 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
|
||||
Thermistor thermistor4(THERMISTOR4_PIN, 573, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_HIGH_TEMP);
|
||||
Thermistor thermistor4(THERMISTOR4_PIN, 564, ThermistorZ_Placement::BOTTOM, ThermistorXY_Placement::MIDDLE_HIGH_TEMP);
|
||||
// 515R reference = Best accuracy around 210C
|
||||
Thermistor thermistor5(THERMISTOR5_PIN, 8111, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE_LOW_TEMP);
|
||||
Thermistor thermistor5(THERMISTOR5_PIN,5727, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE_LOW_TEMP);
|
||||
// 9k reference = Best accuracy around 90C -> This thermistor is used for the preheat phase if attached
|
||||
Thermistor thermistor6(THERMISTOR6_PIN, 526, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE_HIGH_TEMP);
|
||||
Thermistor thermistor6(THERMISTOR6_PIN, 467, ThermistorZ_Placement::TOP, ThermistorXY_Placement::MIDDLE_HIGH_TEMP);
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
@ -64,15 +66,20 @@ int nReflowProfiles = 3;
|
||||
ReflowProfile reflowProfiles[] = {
|
||||
// 138c profile Sn42Bi58
|
||||
ReflowProfile(new ReflowStep[5]{
|
||||
ReflowStep(ReflowProcessState::PREHEAT, 100, 100, EASE_OUT),
|
||||
ReflowStep(ReflowProcessState::SOAK, 90, 155,EASE_IN_OUT),
|
||||
ReflowStep(ReflowProcessState::PREHEAT, 100, 100, EASE_IN),
|
||||
ReflowStep(ReflowProcessState::SOAK, 90, 140,EASE_IN_OUT),
|
||||
ReflowStep(ReflowProcessState::REFLOW, 90, 185, HALF_SINE),
|
||||
ReflowStep(ReflowProcessState::COOL, 50, 85, EASE_IN),
|
||||
ReflowStep(ReflowProcessState::DONE, 0, 0)},
|
||||
"138c Sn42Bi58\0"),
|
||||
|
||||
ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 100, 150), ReflowStep(ReflowProcessState::SOAK, 30, 180), ReflowStep(ReflowProcessState::REFLOW, 80, 220, EASE_IN_OUT), ReflowStep(ReflowProcessState::COOL, 30, 183), ReflowStep(ReflowProcessState::DONE, 0, 0)}, "183C Sn63 Pb37 \0"),
|
||||
ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 5, 150), ReflowStep(ReflowProcessState::SOAK, 5, 180), ReflowStep(ReflowProcessState::REFLOW, 5, 220, EASE_IN_OUT), ReflowStep(ReflowProcessState::COOL, 5, 183), ReflowStep(ReflowProcessState::DONE, 0, 0)}, "debug profi \0"),
|
||||
ReflowProfile(new ReflowStep[5]{ReflowStep(
|
||||
ReflowProcessState::PREHEAT, 200, 100,MID_RAMP_HOLD),
|
||||
ReflowStep(ReflowProcessState::SOAK, 150, 150,FAST_RAMP_HOLD),
|
||||
ReflowStep(ReflowProcessState::REFLOW, 150, 220, SLOW_RAMP_HOLD),
|
||||
ReflowStep(ReflowProcessState::COOL, 200, 0,LINEAR),
|
||||
ReflowStep(ReflowProcessState::DONE, 0, 0)}, "Tuning Profile \0"),
|
||||
|
||||
};
|
||||
|
||||
|
@ -8,6 +8,8 @@
|
||||
#include "./thermistors/ThermistorLookup.h"
|
||||
|
||||
|
||||
|
||||
|
||||
//Comment out to enable debug messages
|
||||
//#define DEBUG
|
||||
|
||||
@ -26,6 +28,18 @@
|
||||
#define HIGH_TEMP_THRESHOLD 150
|
||||
|
||||
|
||||
//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
|
||||
//This gets reversed inside the PID controller
|
||||
#define PID_OUTPUT_MIN 0
|
||||
#define PID_OUTPUT_MAX 255
|
||||
#define PID_SAMPLE_TIME 0.1
|
||||
|
||||
|
||||
|
||||
extern WrappedState<ReflowProcessState> reflowProcessState;
|
||||
extern AnalogRef analogRef;
|
||||
@ -41,6 +55,7 @@ extern ReflowProfile chosenReflowProfile;
|
||||
extern uint16_t plateResistanceOhm;
|
||||
extern int nReflowProfiles;
|
||||
|
||||
|
||||
extern PidControllerData pidControllerData;
|
||||
extern PidController pidController;
|
||||
extern EEPROMDataManager eepromDataManager;
|
||||
@ -56,4 +71,5 @@ extern ThermistorLookup thermistorLookup;
|
||||
|
||||
|
||||
|
||||
|
||||
#endif
|
123
src/main.cpp
123
src/main.cpp
@ -12,10 +12,10 @@
|
||||
#include "PID/PidController.h"
|
||||
#include "globals.h"
|
||||
#include "EEPROMDataManager.h"
|
||||
#include "thermistors/TemperatureController.h"
|
||||
#include "tools/ExecutionTimer.h"
|
||||
#include "StopWatch.h"
|
||||
#include "thermistors/Thermistor.h"
|
||||
#include "thermistors/TemperatureController.h"
|
||||
|
||||
#define MOSTFET_PIN 17
|
||||
|
||||
@ -25,6 +25,8 @@ double pwmValue = 255;
|
||||
|
||||
ExecutionTimer executionTimer;
|
||||
|
||||
TemperatureController tempController;
|
||||
|
||||
Buttons buttons = Buttons();
|
||||
LEDS leds = LEDS();
|
||||
// Declare the PID
|
||||
@ -32,7 +34,6 @@ ArduPID PID;
|
||||
OledDisplay oled = OledDisplay();
|
||||
|
||||
TFT_Display tftDisplay;
|
||||
TemperatureController temperatureController;
|
||||
|
||||
StopWatch thermTimer = StopWatch();
|
||||
StopWatch thermMilisTimer = StopWatch();
|
||||
@ -56,7 +57,7 @@ void setup()
|
||||
|
||||
reflowProcessState.set(ReflowProcessState::USER_INPUT);
|
||||
|
||||
temperatureController.checkPluggedInThermistors();
|
||||
tempController.checkPluggedInThermistors();
|
||||
|
||||
tftDisplay.start();
|
||||
|
||||
@ -104,6 +105,7 @@ void loop()
|
||||
{
|
||||
|
||||
tftDisplay.init(&chosenReflowProfile);
|
||||
tempController.checkPluggedInThermistors();
|
||||
|
||||
chosenReflowProfile.start();
|
||||
// Start the PID
|
||||
@ -123,70 +125,71 @@ 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() > 1)
|
||||
{
|
||||
// if (thermTimer.elapsed() > 1)
|
||||
// {
|
||||
|
||||
Serial.print(thermTimer.elapsed());
|
||||
Serial.print(",");
|
||||
float temp1 = thermistor1.getTemperature();
|
||||
float temp2 = thermistor2.getTemperature();
|
||||
float temp3 = thermistor3.getTemperature();
|
||||
float temp4 = thermistor4.getTemperature();
|
||||
float temp5 = thermistor5.getTemperature();
|
||||
float temp6 = thermistor6.getTemperature();
|
||||
Serial.print(temp1);
|
||||
Serial.print(",");
|
||||
Serial.print(temp2);
|
||||
Serial.print(",");
|
||||
Serial.print(temp3);
|
||||
Serial.print(",");
|
||||
Serial.print(temp4);
|
||||
Serial.print(",");
|
||||
Serial.print(temp5);
|
||||
Serial.print(",");
|
||||
Serial.print(temp6);
|
||||
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.print(",");
|
||||
Serial.print(thermistor5.scalingFactor);
|
||||
Serial.print(",");
|
||||
Serial.print(thermistor6.scalingFactor);
|
||||
Serial.print(",");
|
||||
// Serial.print(thermTimer.elapsed());
|
||||
// Serial.print(",");
|
||||
// float temp1 = thermistor1.getTemperature();
|
||||
// float temp2 = thermistor2.getTemperature();
|
||||
// float temp3 = thermistor3.getTemperature();
|
||||
// float temp4 = thermistor4.getTemperature();
|
||||
// float temp5 = thermistor5.getTemperature();
|
||||
// float temp6 = thermistor6.getTemperature();
|
||||
// Serial.print(temp1);
|
||||
// Serial.print(",");
|
||||
// Serial.print(temp2);
|
||||
// Serial.print(",");
|
||||
// Serial.print(temp3);
|
||||
// Serial.print(",");
|
||||
// Serial.print(temp4);
|
||||
// Serial.print(",");
|
||||
// Serial.print(temp5);
|
||||
// Serial.print(",");
|
||||
// Serial.print(temp6);
|
||||
// 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.print(",");
|
||||
// Serial.print(thermistor5.scalingFactor);
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor6.scalingFactor);
|
||||
// Serial.print(",");
|
||||
|
||||
float values[] = {temp2,temp3,temp4};
|
||||
float weights[] = {thermistor2.getWeightingFactor(),thermistor3.getWeightingFactor(),thermistor4.getWeightingFactor()};
|
||||
uint8_t length = 3;
|
||||
float averaged = TemperatureController::getWeightedAverage(values, weights, length);
|
||||
Serial.print(averaged);
|
||||
Serial.print(",");
|
||||
Serial.print(weights[0]);
|
||||
Serial.print(",");
|
||||
Serial.print(weights[1]);
|
||||
Serial.print(",");
|
||||
Serial.print(weights[2]);
|
||||
Serial.print(",");
|
||||
Serial.println();
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor1.getWeightingFactor());
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor2.getWeightingFactor());
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor3.getWeightingFactor());
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor4.getWeightingFactor());
|
||||
}
|
||||
// float values[] = {temp2,temp3,temp4};
|
||||
// float weights[] = {thermistor2.getWeightingFactor(),thermistor3.getWeightingFactor(),thermistor4.getWeightingFactor()};
|
||||
// uint8_t length = 3;
|
||||
// float averaged = TemperatureController::getWeightedAverage(values, weights, length);
|
||||
// Serial.print(averaged);
|
||||
// Serial.print(",");
|
||||
// Serial.print(weights[0]);
|
||||
// Serial.print(",");
|
||||
// Serial.print(weights[1]);
|
||||
// Serial.print(",");
|
||||
// Serial.print(weights[2]);
|
||||
// Serial.print(",");
|
||||
// Serial.println();
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor1.getWeightingFactor());
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor2.getWeightingFactor());
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor3.getWeightingFactor());
|
||||
// Serial.print(",");
|
||||
// Serial.print(thermistor4.getWeightingFactor());
|
||||
//}
|
||||
|
||||
if (step.state != newState)
|
||||
{
|
||||
|
43
src/reflow.h
43
src/reflow.h
@ -33,7 +33,10 @@ enum ReflowStepEaseFunction
|
||||
EASE_IN_OUT,
|
||||
EASE_IN,
|
||||
EASE_OUT,
|
||||
HALF_SINE
|
||||
HALF_SINE,
|
||||
SLOW_RAMP_HOLD,
|
||||
MID_RAMP_HOLD,
|
||||
FAST_RAMP_HOLD
|
||||
};
|
||||
class ReflowStep
|
||||
{
|
||||
@ -65,6 +68,43 @@ public:
|
||||
return startTemp + (this->targetTemp - startTemp) * (sin(percentage * PI / (double)2));
|
||||
case HALF_SINE:
|
||||
return startTemp + (this->targetTemp - startTemp) * (sin(percentage * PI));
|
||||
case SLOW_RAMP_HOLD:
|
||||
|
||||
if (percentage <= 0.75)
|
||||
{
|
||||
// Ramp up to the target temperature over the first 25% of the time
|
||||
return startTemp + (this->targetTemp - startTemp) * (percentage / 0.75);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hold at the target temperature for the remaining 75% of the time
|
||||
return this->targetTemp;
|
||||
}
|
||||
|
||||
case MID_RAMP_HOLD:
|
||||
|
||||
if (percentage <= 0.50)
|
||||
{
|
||||
// Ramp up to the target temperature over the first half of the time
|
||||
return startTemp + (this->targetTemp - startTemp) * (percentage / 0.50);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hold at the target temperature for the remaining half of the time
|
||||
return this->targetTemp;
|
||||
}
|
||||
|
||||
case FAST_RAMP_HOLD:
|
||||
if (percentage <= 0.25)
|
||||
{
|
||||
// Ramp up to the target temperature over the first 75% of the time
|
||||
return startTemp + (this->targetTemp - startTemp) * (percentage / 0.25);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Hold at the target temperature for the remaining 25% of the time
|
||||
return this->targetTemp;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@ -112,7 +152,6 @@ public:
|
||||
endTimes[3] = endTimes[2] + steps[3].duration;
|
||||
endTimes[4] = endTimes[3] + steps[4].duration;
|
||||
|
||||
|
||||
startTimes[0] = 0;
|
||||
startTimes[1] = endTimes[0];
|
||||
startTimes[2] = endTimes[1];
|
||||
|
@ -15,28 +15,30 @@ TemperatureController::~TemperatureController()
|
||||
*/
|
||||
void TemperatureController::checkPluggedInThermistors()
|
||||
{
|
||||
activeThermistorCount = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
bool isPluggedIn = thermistors[i].isPluggedIn();
|
||||
|
||||
if (isPluggedIn)
|
||||
{
|
||||
thermistorIsActive[i] = true;
|
||||
// We do it before incrementing because the array is zero indexed
|
||||
|
||||
activeThermistorNumbers[activeThermistorCount] = i;
|
||||
activeThermistorCount++;
|
||||
}
|
||||
else
|
||||
{
|
||||
thermistorIsActive[i] = false;
|
||||
}
|
||||
|
||||
debugC("Thermistor ");
|
||||
debugC(i);
|
||||
debugC(" is plugged in: ");
|
||||
debugC(isPluggedIn == 1 ? "true" : "false");
|
||||
// debugC("Thermistor ");
|
||||
// debugC(i);
|
||||
// debugC(" is plugged in: ");
|
||||
// debugC(isPluggedIn == 1 ? "true" : "false");
|
||||
}
|
||||
|
||||
debugC("Active thermistor count: ");
|
||||
debugLine(activeThermistorCount);
|
||||
debugC(activeThermistorCount);
|
||||
}
|
||||
|
||||
float TemperatureController::getThermistorTempFast(uint8_t thermistorIndex)
|
||||
@ -71,16 +73,19 @@ float TemperatureController::getWeightedAverage(float *values, float *weights, u
|
||||
* @return The average temperature of the solder plate.
|
||||
*/
|
||||
float TemperatureController::getPlateTemperature()
|
||||
{
|
||||
float plateAveragedTemp = 0;
|
||||
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
float activeThermistorTemps[activeThermistorCount];
|
||||
float activeThermistorWeights[activeThermistorCount];
|
||||
|
||||
for (int i = 0; i < activeThermistorCount; i++)
|
||||
{
|
||||
if (thermistorIsActive[i])
|
||||
{
|
||||
plateAveragedTemp += thermistors[i].getTemperature();
|
||||
}
|
||||
|
||||
activeThermistorTemps[i] = thermistors[activeThermistorNumbers[i]].getTemperature();
|
||||
activeThermistorWeights[i] = thermistors[activeThermistorNumbers[i]].getWeightingFactor();
|
||||
}
|
||||
|
||||
return plateAveragedTemp / activeThermistorCount;
|
||||
float averaged = getWeightedAverage(activeThermistorTemps, activeThermistorWeights, activeThermistorCount);
|
||||
|
||||
return averaged;
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
#ifndef TEMPERATURE_CONTROLLER_H
|
||||
#define TEMPERATURE_CONTROLLER_H
|
||||
|
||||
#include "Thermistor.h"
|
||||
#include "globals.h"
|
||||
// #include "Thermistor.h"
|
||||
#include "../globals.h"
|
||||
|
||||
|
||||
|
||||
extern Thermistor thermistors[6];
|
||||
|
||||
@ -20,11 +22,12 @@ public:
|
||||
private:
|
||||
|
||||
|
||||
bool thermistorIsActive[6];
|
||||
uint8_t activeThermistorCount =0 ;
|
||||
uint8_t activeThermistorNumbers[6];
|
||||
uint8_t activeThermistorCount;
|
||||
float weightFactor;
|
||||
|
||||
|
||||
|
||||
|
||||
};
|
||||
#endif // TEMPERATURE_CONTROLLER_H
|
||||
|
@ -62,101 +62,69 @@ float Thermistor::getTemperature()
|
||||
* This should only be called after getTemperature() has been called.
|
||||
* @return The scaling factor.
|
||||
*/
|
||||
// float Thermistor::getWeightingFactor()
|
||||
// {
|
||||
// switch (xyPlacment)
|
||||
// {
|
||||
|
||||
// // Middle always have weighting factor of 1 and the factor can only increase for the other sensors
|
||||
// case MIDDLE:
|
||||
|
||||
// return 1;
|
||||
// break;
|
||||
|
||||
// case MIDDLE_LOW_TEMP:
|
||||
|
||||
// if (currenTemperature > START_TEMP && currenTemperature < LOW_TEMP_THRESHOLD)
|
||||
// {
|
||||
// return ThermistorLookup::interpolate(currenTemperature, START_TEMP, LOW_TEMP_THRESHOLD, 1, 1.5);
|
||||
// }
|
||||
|
||||
// else if (currenTemperature > LOW_TEMP_THRESHOLD && currenTemperature < MIDDLE_TEMP_THRESHOLD)
|
||||
// {
|
||||
// return ThermistorLookup::interpolate(currenTemperature, LOW_TEMP_THRESHOLD, MIDDLE_TEMP_THRESHOLD, 1.5, 1);
|
||||
// }
|
||||
|
||||
// else if (currenTemperature > MIDDLE_TEMP_THRESHOLD && currenTemperature < HIGH_TEMP_THRESHOLD)
|
||||
// {
|
||||
// return ThermistorLookup::interpolate(currenTemperature, MIDDLE_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD, 1, 0.1);
|
||||
// }
|
||||
// else if (currenTemperature < START_TEMP)
|
||||
// {
|
||||
// return 1;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return 0.1;
|
||||
// }
|
||||
|
||||
|
||||
// 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;
|
||||
// }
|
||||
// }
|
||||
|
||||
float Thermistor::getWeightingFactor()
|
||||
{
|
||||
float start = 1, end = 1;
|
||||
float temp_start = START_TEMP, temp_end = LOW_TEMP_THRESHOLD;
|
||||
switch (xyPlacment)
|
||||
{
|
||||
|
||||
if (xyPlacment == MIDDLE_HIGH_TEMP) {
|
||||
temp_start = MIDDLE_TEMP_THRESHOLD;
|
||||
temp_end = HIGH_TEMP_THRESHOLD;
|
||||
// Middle always have weighting factor of 1 and the factor can only increase for the other sensors
|
||||
case MIDDLE:
|
||||
|
||||
if (currenTemperature > HIGH_TEMP_THRESHOLD)
|
||||
return 1.5;
|
||||
|
||||
if (currenTemperature < MIDDLE_TEMP_THRESHOLD)
|
||||
return ThermistorLookup::interpolate(currenTemperature, START_TEMP, MIDDLE_TEMP_THRESHOLD, 0.1, 1);
|
||||
}
|
||||
return 1;
|
||||
break;
|
||||
|
||||
if (xyPlacment == MIDDLE_LOW_TEMP || xyPlacment == MIDDLE_HIGH_TEMP) {
|
||||
if (currenTemperature > temp_start && currenTemperature < temp_end)
|
||||
return ThermistorLookup::interpolate(currenTemperature, temp_start, temp_end, start, 1.5);
|
||||
|
||||
if (currenTemperature > temp_end && currenTemperature < HIGH_TEMP_THRESHOLD)
|
||||
return ThermistorLookup::interpolate(currenTemperature, temp_end, HIGH_TEMP_THRESHOLD, 1.5, 1);
|
||||
|
||||
if (currenTemperature > HIGH_TEMP_THRESHOLD && currenTemperature < HIGH_TEMP_THRESHOLD)
|
||||
return ThermistorLookup::interpolate(currenTemperature, HIGH_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD, 1, 0.1);
|
||||
|
||||
return (currenTemperature < START_TEMP) ? 1 : 0.1;
|
||||
}
|
||||
case MIDDLE_LOW_TEMP:
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (currenTemperature > START_TEMP && currenTemperature < LOW_TEMP_THRESHOLD)
|
||||
{
|
||||
return ThermistorLookup::interpolate(currenTemperature, START_TEMP, LOW_TEMP_THRESHOLD, 1, 1.5);
|
||||
}
|
||||
|
||||
else if (currenTemperature > LOW_TEMP_THRESHOLD && currenTemperature < MIDDLE_TEMP_THRESHOLD)
|
||||
{
|
||||
return ThermistorLookup::interpolate(currenTemperature, LOW_TEMP_THRESHOLD, MIDDLE_TEMP_THRESHOLD, 1.5, 1);
|
||||
}
|
||||
|
||||
else if (currenTemperature > MIDDLE_TEMP_THRESHOLD && currenTemperature < HIGH_TEMP_THRESHOLD)
|
||||
{
|
||||
return ThermistorLookup::interpolate(currenTemperature, MIDDLE_TEMP_THRESHOLD, HIGH_TEMP_THRESHOLD, 1, 0.1);
|
||||
}
|
||||
else if (currenTemperature < START_TEMP)
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
return 0.1;
|
||||
}
|
||||
|
||||
|
||||
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.
|
||||
|
@ -63,8 +63,8 @@ const LookupEntry *ThermistorLookup::getTable(ThermistorZ_Placement zPlacement,
|
||||
return noScaling;
|
||||
case SIDE:
|
||||
|
||||
tableSize = sizeof(lookupTopSide) / sizeof(LookupEntry);
|
||||
return lookupTopSide;
|
||||
tableSize = sizeof(lookupSide) / sizeof(LookupEntry);
|
||||
return lookupSide;
|
||||
|
||||
}
|
||||
case BOTTOM:
|
||||
@ -77,8 +77,8 @@ const LookupEntry *ThermistorLookup::getTable(ThermistorZ_Placement zPlacement,
|
||||
return lookupBottomMiddle;
|
||||
case SIDE:
|
||||
|
||||
tableSize = sizeof(lookupTopSide) / sizeof(LookupEntry);
|
||||
return lookupTopSide;
|
||||
tableSize = sizeof(lookupSide) / sizeof(LookupEntry);
|
||||
return lookupSide;
|
||||
|
||||
case MIDDLE_LOW_TEMP:
|
||||
|
||||
|
@ -12,40 +12,7 @@ struct LookupEntry
|
||||
|
||||
const LookupEntry lookupBottomMiddle[] = {
|
||||
|
||||
// {20, 1},
|
||||
// {25, 1},
|
||||
// {30, 1.05421},
|
||||
// {35, 1.15779326424813},
|
||||
// {40, 1.07137955413676},
|
||||
// {45, 1.02848510334699},
|
||||
// {50, 1.0166963542828},
|
||||
// {55, 1.00055351519777},
|
||||
// {60, 0.998966148199037},
|
||||
// {65, 1.00436499654204},
|
||||
// {70, 0.994176485727482},
|
||||
// {75, 0.996391553112729},
|
||||
// {80, 1.00113614372955},
|
||||
// {85, 1.00053768922283},
|
||||
// {90, 1.00020751145521},
|
||||
// {95, 1.00128249791913},
|
||||
// {100, 1.0025246862876},
|
||||
// {105, 1.01020841898173},
|
||||
// {110, 1.00848854034523},
|
||||
// {115, 1.00896686906428},
|
||||
// {120, 1.04794644679831},
|
||||
// {125, 1.01523894946},
|
||||
// {130, 1.03214558479698},
|
||||
// {135, 1.02223637810346},
|
||||
// {140, 1.02095852249947},
|
||||
// {145, 1.03452569295212},
|
||||
// {150, 1.03344468755321},
|
||||
// {155, 1.02978238847957},
|
||||
// {160, 1.03050853971874},
|
||||
// {165, 1.0362899703462},
|
||||
// {170, 1.02896213350023},
|
||||
// {175, 1.03246206505197},
|
||||
// {180, 1.03511815797411},
|
||||
// {185, 1.0386550768334},
|
||||
|
||||
// {0, 1},
|
||||
// {25, 1.00715513834484},
|
||||
// {35, 1.12484607155925},
|
||||
@ -56,62 +23,108 @@ const LookupEntry lookupBottomMiddle[] = {
|
||||
// {60, 1.08544627050144},
|
||||
// {65, 1.08660293694492},
|
||||
// {70, 1.08001421226446},
|
||||
// {75, 1.06027464588806},
|
||||
// {80, 1.05704474661452},
|
||||
// {85, 1.0483519592037},
|
||||
// {90, 1.03590936413276},
|
||||
// {95, 1.01755407120932},
|
||||
// {100, 0.997970532804681},
|
||||
// {105, 1.0022625340138},
|
||||
// {110, 1.00477823648416},
|
||||
// {115, 1.01527755445145},
|
||||
// {120, 1.01340733480523},
|
||||
// {125, 1.01488197269303},
|
||||
// {130, 1.01527719047251},
|
||||
// {135, 1.01613530209391},
|
||||
// {140, 1.01503246127647},
|
||||
// {145, 1.00589573878646},
|
||||
// {150, 0.99704724078137},
|
||||
// {155, 0.989621222331136},
|
||||
// {160, 0.997298663304549},
|
||||
// {165, 1.00001826143415},
|
||||
// {170, 0.994369457141502},
|
||||
// {175, 0.997960941911383},
|
||||
// {180, 1.00465186375123},
|
||||
// {185, 1.00123672344689},
|
||||
{0, 1},
|
||||
{25, 1.00715513834484},
|
||||
{35, 1.12484607155925},
|
||||
{40, 1.13743718719145},
|
||||
{45, 1.13506399305814},
|
||||
{50, 1.13067636137849},
|
||||
{55, 1.11648433361902},
|
||||
{60, 1.08544627050144},
|
||||
{65, 1.08660293694492},
|
||||
{70, 1.08001421226446},
|
||||
{75, 1.06027464588806},
|
||||
{80, 1.05704474661452},
|
||||
{85, 1.0483519592037},
|
||||
{90, 1.03590936413276},
|
||||
{95, 1.01755407120932},
|
||||
{100, 0.998508196505047},
|
||||
{105, 1.0022625340138},
|
||||
{110, 1.00477823648416},
|
||||
{115, 1.01527755445145},
|
||||
{120, 1.01340733480523},
|
||||
{125, 1.01488197269303},
|
||||
{130, 1.01527719047251},
|
||||
{135, 1.01613530209391},
|
||||
{140, 1.01503246127647},
|
||||
{145, 1.00589573878646},
|
||||
{150, 0.99704724078137},
|
||||
{155, 0.99429110718977},
|
||||
{160, 0.997298663304549},
|
||||
{165, 1.00001826143415},
|
||||
{170, 0.994369457141502},
|
||||
{175, 0.997960941911383},
|
||||
{180, 1.00465186375123},
|
||||
{185, 1.00123672344689},
|
||||
// {75, 1.16027464588806},
|
||||
// {80, 1.15704474661452},
|
||||
// {85, 1.1483519592037},
|
||||
// {90, 1.13590936413276},
|
||||
// {95, 1.11755407120932},
|
||||
// {100, 1.098508196505047},
|
||||
// {105, 1.1022625340138},
|
||||
// {110, 1.15477823648416},
|
||||
// {115, 1.07527755445145},
|
||||
// {120, 1.11340733480523},
|
||||
// {125, 1.11488197269303},
|
||||
// {130, 1.11527719047251},
|
||||
// {135, 1.11613530209391},
|
||||
// {140, 1.11503246127647},
|
||||
// {145, 1.11589573878646},
|
||||
// {150, 1.09704724078137},
|
||||
// {155, 1.07429110718977},
|
||||
// {160, 1.077298663304549},
|
||||
// {165, 1.06001826143415},
|
||||
// {170, 1.064369457141502},
|
||||
// {175, 1.077960941911383},
|
||||
// {180, 1.05465186375123},
|
||||
// {185, 1.04123672344689},
|
||||
|
||||
// {0, 1},
|
||||
// {25, 1},
|
||||
// {35, 1.1052933159867},
|
||||
// {40, 1.21609667854928},
|
||||
// {45, 1.2911142404736},
|
||||
// {50, 1.3025297616858},
|
||||
// {55, 1.23009750677688},
|
||||
// {60, 1.21020012832492},
|
||||
// {65, 1.1958744927507},
|
||||
// {70, 1.17736636429599},
|
||||
// {75, 1.16148454663088},
|
||||
// {80, 1.14128677245524},
|
||||
// {85, 1.12056018153759},
|
||||
// {90, 1.09751446890912},
|
||||
// {95, 1.0719327567656},
|
||||
// {100, 1.04444728765731},
|
||||
// {105, 1.01168280610488},
|
||||
// {110, 0.997951853293252},
|
||||
// {115, 0.997484122047861},
|
||||
// {120, 0.995485646422296},
|
||||
// {125, 0.991950691084749},
|
||||
// {130, 0.986936226835838},
|
||||
// {135, 0.980406736094767},
|
||||
// {140, 0.971610618160775},
|
||||
// {145, 0.960416571461218},
|
||||
// {150, 0.946838744739725},
|
||||
// {155, 0.939711842929308},
|
||||
// {160, 0.942063273857483},
|
||||
// {165, 0.944163192400784},
|
||||
// {170, 0.945540089910834},
|
||||
// {175, 0.947118566344439},
|
||||
// {180, 0.948725983429991},
|
||||
// {185, 0.948952977460463},
|
||||
// {190, 0.947112176288284},
|
||||
// {195, 0.94452632310351},
|
||||
// {200, 0.943146841233212},
|
||||
// {205, 0.940750491942809},
|
||||
// {210, 0.935013650790026},
|
||||
|
||||
{35, 1.1052933159867},
|
||||
{40, 1.21609667854928},
|
||||
{45, 1.2911142404736},
|
||||
{50, 1.3025297616858},
|
||||
{55, 1.23009750677688},
|
||||
{60, 1.21020012832492},
|
||||
{65, 1.1958744927507},
|
||||
{70, 1.17736636429599},
|
||||
{75, 1.16148454663088},
|
||||
{80, 1.14128677245524},
|
||||
{85, 1.12056018153759},
|
||||
{90, 1.07751446890912},
|
||||
{95, 1.0719327567656},
|
||||
{100, 1.04444728765731},
|
||||
{105, 1.08250060253222},
|
||||
{110, 1.06780848302378},
|
||||
{115, 1.06730801059121},
|
||||
{120, 1.06516964167186},
|
||||
{125, 1.06138723946068},
|
||||
{130, 1.05602176271435},
|
||||
{135, 1.0490352076214},
|
||||
{140, 1.03962336143203},
|
||||
{145, 1.0276457314635},
|
||||
{150, 1.01311745687151},
|
||||
{155, 1.04308014565153},
|
||||
{160, 1.04569023398181},
|
||||
{165, 1.04802114356487},
|
||||
{170, 1.04954949980103},
|
||||
{175, 1.05130160864233},
|
||||
{180, 1.05308584160729},
|
||||
{185, 1.05333780498111},
|
||||
{190, 1.05129451568},
|
||||
{195, 1.0484242186449},
|
||||
{200, 1.04689299376887},
|
||||
{205, 1.04423304605652},
|
||||
{210, 1.03786515237693},
|
||||
{215, 1.02786515237693},
|
||||
{220, 1.01786515237693},
|
||||
|
||||
|
||||
|
||||
|
||||
@ -120,7 +133,7 @@ const LookupEntry lookupBottomMiddle[] = {
|
||||
|
||||
};
|
||||
|
||||
const LookupEntry lookupTopSide[] = {
|
||||
const LookupEntry lookupSide[] = {
|
||||
{30, 0.995205469483767},
|
||||
{35, 1.11724354649558},
|
||||
{40, 1.16221262415921},
|
||||
|
Loading…
Reference in New Issue
Block a user