Fixed all bugs for overflow in reflow.h Bug was caused by multipling a uint_16t or uint_32t or uint_8t BEFORE casting it to a float or a unit that can handle the number. Type casting should ONLY be done WITHOUT multiplication in the cast. Its easy to create overflows like this.

This commit is contained in:
-help 2024-01-28 04:53:54 +02:00
parent a99d8d4071
commit 15302f72c7
7 changed files with 67 additions and 36 deletions

View File

@ -55,4 +55,5 @@ void PidController::stop()
void PidController::start() void PidController::start()
{ {
controller.start(); controller.start();
} }

View File

@ -147,6 +147,7 @@ void TFT_Display::drawGraph()
drawGraphAxis(); drawGraphAxis();
drawGraphAxisLabels(); drawGraphAxisLabels();
drawGraphAxisTicks(); drawGraphAxisTicks();
drawGraphAxisTickLabels();
} }
void TFT_Display::drawGraphAxis() void TFT_Display::drawGraphAxis()
@ -166,18 +167,29 @@ void TFT_Display::drawGraphAxisLabels()
tft.setCursor(5, 10); tft.setCursor(5, 10);
tft.println("Temp"); tft.println("Temp");
TFT_XY position = getCenteredTextXY("Time"); tft.setCursor(150, 228);
tft.setCursor(position.x, position.y +228);
tft.println("Time"); tft.println("Time");
} }
void TFT_Display::drawGraphAxisTicks() void TFT_Display::drawGraphAxisTicks()
{ {
}
void TFT_Display::drawGraphAxisTickLabels()
{
//Always starts at 20c
tft.setTextColor(ST77XX_WHITE); tft.setTextColor(ST77XX_WHITE);
tft.setTextSize(1); tft.setTextSize(1);
TFT_XY position = getRightAlignedTextXY("20", graphXY.x, graphXY.y); TFT_XY position = getRightAlignedTextXY("20", graphXY.x, graphXY.y);
tft.setCursor(position.x, position.y); tft.setCursor(position.x, position.y);
tft.println("20"); tft.println("20");
//Always ends at maxTemp
// tft.setTextColor(ST77XX_WHITE);
// tft.setTextSize(1);
// position = getRightAlignedTextXY(maxTemp, graphXY.x, graphXY.y - graphHeight);
// tft
} }

View File

@ -42,6 +42,7 @@ private:
void drawGraphAxis(); void drawGraphAxis();
void drawGraphAxisLabels(); void drawGraphAxisLabels();
void drawGraphAxisTicks(); void drawGraphAxisTicks();
void drawGraphAxisTickLabels();
}; };
#endif // TFT_H #endif // TFT_H

View File

@ -56,10 +56,10 @@ int nReflowProfiles = 3;
ReflowProfile reflowProfiles[] = { ReflowProfile reflowProfiles[] = {
// 138c profile Sn42Bi58 // 138c profile Sn42Bi58
ReflowProfile(new ReflowStep[5]{ ReflowProfile(new ReflowStep[5]{
ReflowStep(ReflowProcessState::PREHEAT, 120, 100, EASE_OUT), ReflowStep(ReflowProcessState::PREHEAT, 2, 100, EASE_OUT),
ReflowStep(ReflowProcessState::SOAK, 90, 155), ReflowStep(ReflowProcessState::SOAK, 5, 155),
ReflowStep(ReflowProcessState::REFLOW, 45, 185, EASE_OUT), ReflowStep(ReflowProcessState::REFLOW, 90, 185, HALF_SINE),
ReflowStep(ReflowProcessState::COOL, 45, 155, EASE_OUT), ReflowStep(ReflowProcessState::COOL, 60, 95, EASE_OUT),
ReflowStep(ReflowProcessState::DONE, 0, 0)}, ReflowStep(ReflowProcessState::DONE, 0, 0)},
"138c Sn42Bi58\0"), "138c Sn42Bi58\0"),

View File

@ -6,8 +6,8 @@
// If you didnt solder the LEDS in order, change the order here just change the pin numbers till it matches your board // If you didnt solder the LEDS in order, change the order here just change the pin numbers till it matches your board
#define LEFT_LED_PIN 20 //Should be RED #define LEFT_LED_PIN 20 //Should be RED
#define MID_LED_PIN 19 //Should be YELLOW #define MID_LED_PIN 18 //Should be YELLOW
#define RIGHT_LED_PIN 18 //Should be GREEN #define RIGHT_LED_PIN 19 //Should be GREEN
#define GREEN_LED_PIN RIGHT_LED_PIN #define GREEN_LED_PIN RIGHT_LED_PIN

View File

@ -93,9 +93,11 @@ void loop()
if (newState == ReflowProcessState::PREHEAT) { if (newState == ReflowProcessState::PREHEAT) {
tftDisplay.init(&chosenReflowProfile); tftDisplay.init(&chosenReflowProfile);
chosenReflowProfile.start(); chosenReflowProfile.start();
// Start the PID // Start the PID
pidController.start(); pidController.start();
} }
} }
state = newState; state = newState;
@ -108,6 +110,7 @@ void loop()
pidController.loop(); pidController.loop();
pidController.debug();
ReflowStep step = chosenReflowProfile.reflowStep(); ReflowStep step = chosenReflowProfile.reflowStep();
// Here we draw the actual temp vs time to the display // Here we draw the actual temp vs time to the display
@ -117,6 +120,7 @@ void loop()
if (step.state == ReflowProcessState::DONE) if (step.state == ReflowProcessState::DONE)
{ {
pidController.stop(); pidController.stop();
} }
} }
} }

View File

@ -32,7 +32,8 @@ enum ReflowStepEaseFunction
LINEAR, LINEAR,
EASE_IN_OUT, EASE_IN_OUT,
EASE_IN, EASE_IN,
EASE_OUT EASE_OUT,
HALF_SINE
}; };
class ReflowStep class ReflowStep
{ {
@ -56,7 +57,6 @@ public:
{ {
case LINEAR: case LINEAR:
return startTemp + (this->targetTempAtEnd - startTemp) * percentage; return startTemp + (this->targetTempAtEnd - startTemp) * percentage;
case EASE_IN_OUT: case EASE_IN_OUT:
return startTemp + (this->targetTempAtEnd - startTemp) * -(cos(percentage * PI) - 1) / (double)2; return startTemp + (this->targetTempAtEnd - startTemp) * -(cos(percentage * PI) - 1) / (double)2;
case EASE_IN: case EASE_IN:
@ -64,6 +64,8 @@ public:
case EASE_OUT: case EASE_OUT:
return startTemp + (this->targetTempAtEnd - startTemp) * (sin(percentage * PI / (double)2)); return startTemp + (this->targetTempAtEnd - startTemp) * (sin(percentage * PI / (double)2));
case HALF_SINE:
return startTemp + (this->targetTempAtEnd - startTemp) * (sin(percentage * PI));
} }
} }
}; };
@ -89,13 +91,13 @@ public:
} }
ReflowStep steps[5]; ReflowStep steps[5];
char name[20]; char name[20];
uint32_t endTimes[5] = {0}; float endTimes[5] = {0};
uint32_t startTimes[5] = {0}; float startTimes[5] = {0};
StopWatch timer; StopWatch timer;
void start() void start()
{ {
timer = StopWatch(StopWatch::Resolution::MILLIS); timer.setResolution(StopWatch::MILLIS);
timer.start(); timer.start();
calculateTimes(); calculateTimes();
} }
@ -128,7 +130,14 @@ public:
{ {
for (int i = 0; i < 5; i++) for (int i = 0; i < 5; i++)
{ {
if (elapsedMS >= startTimes[i] * 1000 && elapsedMS < endTimes[i] * 1000)
float startTimeFloat = startTimes[i];
float endTimeFloat = endTimes[i];
startTimeFloat *= 1000;
endTimeFloat *= 1000;
if (elapsedMS >= startTimeFloat && elapsedMS <endTimeFloat)
{ {
// Serial.println(String(elapsedMS) + " " + String(startTimes[i] * 1000) + " " + String(endTimes[i] * 1000) + " " + String(i) + " " + String(steps[i].state)); // Serial.println(String(elapsedMS) + " " + String(startTimes[i] * 1000) + " " + String(endTimes[i] * 1000) + " " + String(i) + " " + String(steps[i].state));
return steps[i]; return steps[i];
@ -138,8 +147,15 @@ public:
return steps[4]; // DONE by default return steps[4]; // DONE by default
} }
float getPercentage() { float getPercentage()
return (double)timer.elapsed() / (double)(endTimes[4] * 1000); {
float timerElapsed = timer.elapsed();
float endTimesFloat[4];
return timerElapsed / (float)(endTimes[4] * 1000);
} }
float getTargetTemp() float getTargetTemp()
@ -148,9 +164,10 @@ public:
{ {
return 20; return 20;
} }
return getTargetTemp(timer.elapsed()); return getTargetTemp(timer.elapsed());
} }
float getTargetTemp(uint32_t elapsedMS) { float getTargetTemp(uint32_t elapsedMS)
{
uint8_t startTemp = 20; // always assume 20 degrees at the start uint8_t startTemp = 20; // always assume 20 degrees at the start
ReflowStep curStep = reflowStep(elapsedMS); ReflowStep curStep = reflowStep(elapsedMS);
@ -161,25 +178,31 @@ public:
// startTemp => 20 or the targetTempAtEnd of the previous step // startTemp => 20 or the targetTempAtEnd of the previous step
uint32_t startTimeMS = startTimes[STEPINDEX(curStep)] * 1000; uint32_t startTimeMS = startTimes[STEPINDEX(curStep)];
startTimeMS *= 1000;
uint32_t relativeElapsedTime = elapsedMS - startTimeMS; uint32_t relativeElapsedTime = elapsedMS - startTimeMS;
float percentage = (double)relativeElapsedTime / ((double)(curStep.duration) * 1000);
float duration = curStep.duration ;
duration *= 1000;
float relativeElapsedTimeF = relativeElapsedTime;
float percentage = relativeElapsedTime / duration;
// Serial.println(String(percentage)+ "%" + String(STATE_STR(curStep.state)) + " Elapsed: " + String(elapsedMS) + " ___ " + String(curStep.duration * 1000)); // Serial.println(String(percentage)+ "%" + String(STATE_STR(curStep.state)) + " Elapsed: " + String(elapsedMS) + " ___ " + String(curStep.duration * 1000));
return curStep.calcTempAtPercentage(startTemp, percentage); return curStep.calcTempAtPercentage(startTemp, percentage);
} }
/** /**
* @brief Get the Target Temp At Process Percentage. * @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 * @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 * @return float the target temperature at the given percentage of the full process
*/ */
float getTargetTempFromPercentage(double processPercentage) float getTargetTempFromPercentage(double processPercentage)
{ {
uint32_t duration = endTimes[4]; uint16_t duration = endTimes[4];
uint8_t startTemp = 20; // always assume 20 degrees at the start uint8_t startTemp = 20; // always assume 20 degrees at the start
return getTargetTemp(duration * 1000 * processPercentage); return getTargetTemp(duration * 1000 * processPercentage);
} }
@ -191,16 +214,6 @@ public:
return (elapsedMS - startTimeMS) / 1000; return (elapsedMS - startTimeMS) / 1000;
} }
void toBuffer(uint8_t *b) void toBuffer(uint8_t *b)
{ {
memset(b, 0, PROFILE_SERIALIZED_SIZE); memset(b, 0, PROFILE_SERIALIZED_SIZE);