diff --git a/src/common.h b/src/common.h index f6aa7cf..7d914c7 100644 --- a/src/common.h +++ b/src/common.h @@ -70,4 +70,7 @@ enum ThermistorXY_Placement }; + + + #endif \ No newline at end of file diff --git a/src/reflow.cpp b/src/reflow.cpp new file mode 100644 index 0000000..9858f07 --- /dev/null +++ b/src/reflow.cpp @@ -0,0 +1,236 @@ +#include "reflow.h" + +//extern TemperatureController tempController; + +ReflowStep::ReflowStep() +{ +} + +ReflowStep::ReflowStep(ReflowProcessState state, uint8_t time, uint8_t targetTemp) : state(state), duration(time), targetTemp(targetTemp), easeFunction(LINEAR) {} + +ReflowStep::ReflowStep(ReflowProcessState state, uint8_t time, uint8_t targetTemp, ReflowStepEaseFunction fn) : state(state), + duration(time), + targetTemp(targetTemp), + easeFunction(fn) +{ +} + +float ReflowStep::calcTempAtPercentage(uint8_t startTemp, float percentage) + +{ + switch (this->easeFunction) + { + case LINEAR: + return startTemp + (this->targetTemp - startTemp) * percentage; + case EASE_IN_OUT: + return startTemp + (this->targetTemp - startTemp) * -(cos(percentage * PI) - 1) / (double)2; + case EASE_IN: + return startTemp + (this->targetTemp - startTemp) * (1 - cos(percentage * PI / (double)2)); + case EASE_OUT: + 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; + } + } +} + +ReflowProfile::ReflowProfile(ReflowStep steps[5], char name[20]) +{ + + { + + for (int i = 0; i < 5; i++) + { + this->steps[i] = steps[i]; + } + + for (int i = 0; i < 20; i++) + { + this->name[i] = name[i]; + } + calculateValues(); + } +} + +void ReflowProfile::start() + +{ + timer = StopWatch(StopWatch::MILLIS); + timer.start(); +} + +void ReflowProfile::calculateValues() + +{ + endTimes[0] = steps[0].duration; + endTimes[1] = endTimes[0] + steps[1].duration; + endTimes[2] = endTimes[1] + steps[2].duration; + 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]; + startTimes[3] = endTimes[2]; + startTimes[4] = endTimes[3]; + + startTemps[0] = 20; // USe ambient temp as the starting temp for the first step + + // We will grab the current PCB temp from the PID as the start temp otherwise the PID will be off + //startTemps[0] = tempController.getPlateTemperature(); + + endTemps[0] = steps[0].calcTempAtPercentage(startTemps[0], 1); + endTemps[1] = steps[1].calcTempAtPercentage(endTemps[0], 1); + endTemps[2] = steps[2].calcTempAtPercentage(endTemps[1], 1); + endTemps[3] = steps[3].calcTempAtPercentage(endTemps[2], 1); + endTemps[4] = steps[4].calcTempAtPercentage(endTemps[3], 1); + + startTemps[1] = endTemps[0]; + startTemps[2] = endTemps[1]; + startTemps[3] = endTemps[2]; + startTemps[4] = endTemps[3]; +} + +ReflowStep ReflowProfile::reflowStep() + +{ + if (!timer.isRunning()) + { + return steps[0]; + } + return reflowStep(timer.elapsed()); +} + +ReflowStep ReflowProfile::reflowStep(uint32_t elapsedMS) + +{ + if (!timer.isRunning()) + { + return steps[0]; + } + return reflowStep(timer.elapsed()); +} + +float ReflowProfile::getPercentage() + +{ + return timer.elapsed() / (double)TOMILLIS(endTimes[4]); +} + +float ReflowProfile::getTargetTemp() + +{ + if (!timer.isRunning()) + { + return startTemps[0]; + } + return getTargetTemp(timer.elapsed()); +} + +float ReflowProfile::getTargetTemp(uint32_t elapsedMS) + +{ + ReflowStep curStep = reflowStep(elapsedMS); + + uint32_t startTimeMS = TOMILLIS(startTimes[STEPINDEX(curStep)]); + uint32_t relativeElapsedTime = elapsedMS - startTimeMS; + + float stepPercentage = relativeElapsedTime / (double)TOMILLIS(curStep.duration); + return curStep.calcTempAtPercentage(startTemps[STEPINDEX(curStep)], stepPercentage); +} + +float ReflowProfile::getTargetTempFromPercentage(double processPercentage) + +{ + return getTargetTemp(TOMILLIS(endTimes[4]) * processPercentage); +} + +uint8_t ReflowProfile::getCurrentStepRelativeTime() + +{ + uint32_t elapsedMS = timer.elapsed(); + uint32_t startTimeMS = TOMILLIS(startTimes[STEPINDEX(reflowStep())]); + return (elapsedMS - startTimeMS) / 1000; +} + +void ReflowProfile::toBuffer(uint8_t *b) + +{ + memset(b, 0, PROFILE_SERIALIZED_SIZE); + memcpy(b, name, PROFILE_SERIALIZED_NAME_SIZE); + for (int i = 0; i < 5; i++) + { + b[PROFILE_SERIALIZED_NAME_SIZE + i * 3] = steps[i].duration; + b[PROFILE_SERIALIZED_NAME_SIZE + 1 + i * 3] = steps[i].targetTemp; + b[PROFILE_SERIALIZED_NAME_SIZE + 2 + i * 3] = steps[i].easeFunction; + } +} + +void ReflowProfile::toEEPROM(uint8_t index) + +{ + uint8_t b[40]; + toBuffer(b); + EEPROM.put(index * PROFILE_SERIALIZED_SIZE, b); +} + +ReflowProfile ReflowProfile::fromBuffer(const uint8_t *b) + +{ + char name[PROFILE_SERIALIZED_NAME_SIZE]; + memcpy(name, b, PROFILE_SERIALIZED_NAME_SIZE); + ReflowStep steps[5] = {}; + for (int i = 0; i < 5; i++) + { + steps[i] = ReflowStep( + (ReflowProcessState)(i + PREHEAT), + b[PROFILE_SERIALIZED_NAME_SIZE + i * 3], + b[PROFILE_SERIALIZED_NAME_SIZE + 1 + i * 3], + (ReflowStepEaseFunction)b[PROFILE_SERIALIZED_NAME_SIZE + 2 + i * 3]); + } + return ReflowProfile(steps, name); +} + +ReflowProfile ReflowProfile::fromEEPROM(uint8_t index) + +{ + uint8_t b[40]; + EEPROM.get(index * PROFILE_SERIALIZED_SIZE, b); + return fromBuffer(b); +} \ No newline at end of file diff --git a/src/reflow.h b/src/reflow.h index f33894b..ad930ee 100644 --- a/src/reflow.h +++ b/src/reflow.h @@ -4,10 +4,7 @@ #include #include "StopWatch.h" #include "thermistors/Thermistor.h" - - - - +//#include "thermistors/TemperatureController.h" // STATE MACHINE enum ReflowProcessState @@ -41,98 +38,35 @@ enum ReflowStepEaseFunction MID_RAMP_HOLD, FAST_RAMP_HOLD }; + class ReflowStep { public: - ReflowStep() {} - ReflowStep(ReflowProcessState state, uint8_t time, uint8_t targetTemp) : state(state), duration(time), targetTemp(targetTemp), easeFunction(LINEAR) {} - ReflowStep(ReflowProcessState state, uint8_t time, uint8_t targetTemp, ReflowStepEaseFunction fn) : state(state), - duration(time), - targetTemp(targetTemp), - easeFunction(fn) - { - } + ReflowStep() ; + ReflowStep(ReflowProcessState state, uint8_t time, uint8_t targetTemp) ; + ReflowStep(ReflowProcessState state, uint8_t time, uint8_t targetTemp, ReflowStepEaseFunction fn); + uint8_t duration; uint8_t targetTemp; ReflowProcessState state; ReflowStepEaseFunction easeFunction; - float calcTempAtPercentage(uint8_t startTemp, float percentage) - { - switch (this->easeFunction) - { - case LINEAR: - return startTemp + (this->targetTemp - startTemp) * percentage; - case EASE_IN_OUT: - return startTemp + (this->targetTemp - startTemp) * -(cos(percentage * PI) - 1) / (double)2; - case EASE_IN: - return startTemp + (this->targetTemp - startTemp) * (1 - cos(percentage * PI / (double)2)); - case EASE_OUT: - 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; - } - } - } + float calcTempAtPercentage(uint8_t startTemp, float percentage); }; + + #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: - ReflowProfile(ReflowStep steps[5], char name[20]) - { - - for (int i = 0; i < 5; i++) - { - this->steps[i] = steps[i]; - } - - for (int i = 0; i < 20; i++) - { - this->name[i] = name[i]; - } - calculateValues(); - } + ReflowProfile(ReflowStep steps[5], char name[20]); ReflowStep steps[5]; char name[20]; uint16_t endTimes[5] = {0}; @@ -141,146 +75,31 @@ public: uint8_t startTemps[5] = {0}; StopWatch timer; - void start() - { - timer = StopWatch(StopWatch::MILLIS); - timer.start(); - } + void start(); - void calculateValues() - { - endTimes[0] = steps[0].duration; - endTimes[1] = endTimes[0] + steps[1].duration; - endTimes[2] = endTimes[1] + steps[2].duration; - endTimes[3] = endTimes[2] + steps[3].duration; - endTimes[4] = endTimes[3] + steps[4].duration; + void calculateValues(); - startTimes[0] = 0; - startTimes[1] = endTimes[0]; - startTimes[2] = endTimes[1]; - startTimes[3] = endTimes[2]; - startTimes[4] = endTimes[3]; + ReflowStep reflowStep(); - // We will grab the current PCB temp from the PID as the start temp otherwise the PID will be off - - - startTemps[0] = 20; // USe ambient temp as the starting temp for the first step - - endTemps[0] = steps[0].calcTempAtPercentage(startTemps[0], 1); - endTemps[1] = steps[1].calcTempAtPercentage(endTemps[0], 1); - endTemps[2] = steps[2].calcTempAtPercentage(endTemps[1], 1); - endTemps[3] = steps[3].calcTempAtPercentage(endTemps[2], 1); - endTemps[4] = steps[4].calcTempAtPercentage(endTemps[3], 1); - - startTemps[1] = endTemps[0]; - startTemps[2] = endTemps[1]; - startTemps[3] = endTemps[2]; - startTemps[4] = endTemps[3]; - } - - ReflowStep reflowStep() - { - if (!timer.isRunning()) - { - return steps[0]; - } - return reflowStep(timer.elapsed()); - } - - ReflowStep reflowStep(uint32_t elapsedMS) - { - for (int i = 0; i < 5; i++) - { - if (elapsedMS >= TOMILLIS(startTimes[i]) && elapsedMS < TOMILLIS(endTimes[i])) - { - return steps[i]; - } - } - return steps[4]; // DONE by default - } - - float getPercentage() - { - return timer.elapsed() / (double)TOMILLIS(endTimes[4]); - } - - float getTargetTemp() - { - if (!timer.isRunning()) - { - return startTemps[0]; - } - return getTargetTemp(timer.elapsed()); - } - float getTargetTemp(uint32_t elapsedMS) - { - ReflowStep curStep = reflowStep(elapsedMS); - - uint32_t startTimeMS = TOMILLIS(startTimes[STEPINDEX(curStep)]); - uint32_t relativeElapsedTime = elapsedMS - startTimeMS; - - float stepPercentage = relativeElapsedTime / (double)TOMILLIS(curStep.duration); - return curStep.calcTempAtPercentage(startTemps[STEPINDEX(curStep)], stepPercentage); - } + ReflowStep reflowStep(uint32_t elapsedMS); + float getPercentage(); + float getTargetTemp(); + float getTargetTemp(uint32_t elapsedMS); /** * @brief Get the Target Temp At Process Percentage. * @param processPercentage a number between 0 and 1. 0 is the start of the process, 1 is the end of the process * @return float the target temperature at the given percentage of the full process */ - float getTargetTempFromPercentage(double processPercentage) - { - return getTargetTemp(TOMILLIS(endTimes[4]) * processPercentage); - } + float getTargetTempFromPercentage(double processPercentage); + uint8_t getCurrentStepRelativeTime(); - uint8_t getCurrentStepRelativeTime() - { - uint32_t elapsedMS = timer.elapsed(); - uint32_t startTimeMS = TOMILLIS(startTimes[STEPINDEX(reflowStep())]); - return (elapsedMS - startTimeMS) / 1000; - } + void toBuffer(uint8_t *b); - void toBuffer(uint8_t *b) - { - memset(b, 0, PROFILE_SERIALIZED_SIZE); - memcpy(b, name, PROFILE_SERIALIZED_NAME_SIZE); - for (int i = 0; i < 5; i++) - { - b[PROFILE_SERIALIZED_NAME_SIZE + i * 3] = steps[i].duration; - b[PROFILE_SERIALIZED_NAME_SIZE + 1 + i * 3] = steps[i].targetTemp; - b[PROFILE_SERIALIZED_NAME_SIZE + 2 + i * 3] = steps[i].easeFunction; - } - } + void toEEPROM(uint8_t index); + static ReflowProfile fromBuffer(const uint8_t *b); - void toEEPROM(uint8_t index) - { - uint8_t b[40]; - toBuffer(b); - EEPROM.put(index * PROFILE_SERIALIZED_SIZE, b); - } - - static ReflowProfile fromBuffer(const uint8_t *b) - { - char name[PROFILE_SERIALIZED_NAME_SIZE]; - memcpy(name, b, PROFILE_SERIALIZED_NAME_SIZE); - ReflowStep steps[5] = {}; - for (int i = 0; i < 5; i++) - { - steps[i] = ReflowStep( - (ReflowProcessState)(i + PREHEAT), - b[PROFILE_SERIALIZED_NAME_SIZE + i * 3], - b[PROFILE_SERIALIZED_NAME_SIZE + 1 + i * 3], - (ReflowStepEaseFunction)b[PROFILE_SERIALIZED_NAME_SIZE + 2 + i * 3]); - } - return ReflowProfile(steps, name); - } - - static ReflowProfile fromEEPROM(uint8_t index) - { - uint8_t b[40]; - EEPROM.get(index * PROFILE_SERIALIZED_SIZE, b); - return fromBuffer(b); - } + static ReflowProfile fromEEPROM(uint8_t index); }; #endif \ No newline at end of file diff --git a/src/thermistors/TemperatureController.cpp b/src/thermistors/TemperatureController.cpp index 7cf1e44..8a83dfb 100644 --- a/src/thermistors/TemperatureController.cpp +++ b/src/thermistors/TemperatureController.cpp @@ -37,8 +37,8 @@ void TemperatureController::checkPluggedInThermistors() // debugC(isPluggedIn == 1 ? "true" : "false"); } - debugC("Active thermistor count: "); - debugC(activeThermistorCount); + //debugC("Active thermistor count: "); + // debugC(activeThermistorCount); } float TemperatureController::getThermistorTempFast(uint8_t thermistorIndex) diff --git a/src/thermistors/TemperatureController.h b/src/thermistors/TemperatureController.h index f19bd46..7fbd003 100644 --- a/src/thermistors/TemperatureController.h +++ b/src/thermistors/TemperatureController.h @@ -1,8 +1,9 @@ #ifndef TEMPERATURE_CONTROLLER_H #define TEMPERATURE_CONTROLLER_H -// #include "Thermistor.h" -#include "../globals.h" + +#include "Thermistor.h" +