Merge branch 'master' menu and working stuff.

This commit is contained in:
Andrea Baccega 2024-01-27 17:25:06 +01:00
commit 5ce4ba6d5c
15 changed files with 505 additions and 103 deletions

54
src/PID/PidController.cpp Normal file
View File

@ -0,0 +1,54 @@
#include "PidController.h"
#include "globals.h"
#define MOSTFET_PIN 17
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.reverse();
controller.setOutputLimits(0, 255);
controller.setSampleTime(20);
controller.setWindUpLimits(-100, 185);
}
double *PidController::compute()
{
controller.compute();
return controller.output;
}
void PidController::debug()
{
controller.debug(&Serial, " ", PRINT_INPUT | // Can include or comment out any of these terms to print
PRINT_OUTPUT | // in the Serial plotter
PRINT_SETPOINT | PRINT_BIAS | PRINT_P | PRINT_I | PRINT_D);
}
void PidController::loop() {
pidControllerData.targetTemp = chosenReflowProfile.getTargetTemp();
pidControllerData.currentTemp = thermistor1.getTemperature();
compute();
analogWrite(MOSTFET_PIN, data->setPoint);
}
void PidController::stop()
{
// STOP
digitalWrite(MOSTFET_PIN, LOW);
controller.stop();
controller.reset();
}
void PidController::start()
{
controller.start();
}

38
src/PID/PidController.h Normal file
View File

@ -0,0 +1,38 @@
#ifndef PIDCONTROLLER_H
#define PIDCONTROLLER_H
#include <Arduino.h>
#include <ArduPID.h>
struct PidControllerData { double currentTemp; double setPoint; double targetTemp;};
class PidController
{
public:
PidController(PidControllerData* data);
void setSetpoint(double setpoint);
void setInput(double input);
double* compute();
void debug();
void stop();
void loop();
void start();
boolean started = false;
private:
ArduPID controller;
double kp;
double ki;
double kd;
PidControllerData *data;
double integral;
double previousError;
};
#endif // PIDCONTROLLER_H

View File

@ -21,7 +21,7 @@ Pair<ButtonKind, StateChangeEvent<ButtonState>>* Buttons::handleButtons()
{
StateChangeEvent<ButtonState> *change = __buttons[i]->lastChange();
Serial.println(String("ButtonStateChange: kind=") + KIND_STR(__buttons[i]->kind) + ", " + STATECHANGE_STR((*change)));
Serial.println(String("ButtonStateChange: kind=") + BTNKIND_STR(__buttons[i]->kind) + ", " + BTNSTATECHANGE_STR((*change)));
return new Pair<ButtonKind, StateChangeEvent<ButtonState>>(__buttons[i]->kind, *change);
}
}

View File

@ -17,12 +17,12 @@ enum ButtonKind
NONE
};
#define KIND_STR(kind) (kind == ButtonKind::UP ? "UP" : kind == ButtonKind::DOWN ? "DOWN" \
#define BTNKIND_STR(kind) (kind == ButtonKind::UP ? "UP" : kind == ButtonKind::DOWN ? "DOWN" \
: kind == ButtonKind::BACK ? "BACK" \
: kind == ButtonKind::SELECT ? "SELECT" \
: "NONE")
#define STATE_STR(state) (state == ButtonState::IDLE ? "IDLE" : state == ButtonState::PRESSED ? "PRESSED" \
#define BTNSTATE_STR(state) (state == ButtonState::IDLE ? "IDLE" : state == ButtonState::PRESSED ? "PRESSED" \
: "RELEASED")
#define STATECHANGE_STR(change) (String(STATE_STR(change.from)) + " -> " + STATE_STR(change.to))
#define BTNSTATECHANGE_STR(change) (String(BTNSTATE_STR(change.from)) + " -> " + BTNSTATE_STR(change.to))
#endif

View File

@ -7,6 +7,8 @@
#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin)
#define MENUID_DEBUG 2
#define MENUITEM_THERMISTOR_START 150
#define MENUID_PICK_PROFILE 100
#define MENUITEM_PROFILE_START 100
unsigned long lastProcessedReflowState = 0;
OledDisplay::OledDisplay()
@ -24,10 +26,28 @@ void OledDisplay::handleButtonStateChange(Pair<ButtonKind, StateChangeEvent<Butt
{
if (change.first == ButtonKind::SELECT)
{
OledMenu *selectedMenu = curMenu->getNextMenu();
if (selectedMenu != NULL)
if (curMenu->identifier == MENUID_PICK_PROFILE)
{
curMenu = selectedMenu;
int profileIndex = curMenu->getCurItem().identifier - MENUITEM_PROFILE_START;
if (profileIndex >= 0 && profileIndex < nReflowProfiles)
{
chosenReflowProfile = reflowProfiles[profileIndex];
reflowProcessState.set(PREHEAT);
Serial.println("Chosen profile: " + String(chosenReflowProfile.name));
}
else
{
Serial.println("Invalid profile index: " + String(profileIndex));
}
}
else
{
OledMenu *selectedMenu = curMenu->getNextMenu();
if (selectedMenu != NULL)
{
curMenu = selectedMenu;
}
}
}
else if (change.first == ButtonKind::BACK)
@ -96,11 +116,11 @@ void OledDisplay::setup()
},
3);
OledMenu *pickProfilesMenu = new OledMenu(1);
OledMenu *pickProfilesMenu = new OledMenu(MENUID_PICK_PROFILE);
OledMenuItem *pickProfilesMenuItems = new OledMenuItem[nReflowProfiles];
for (int i = 0; i < nReflowProfiles; i++)
{
pickProfilesMenuItems[i] = OledMenuItem(reflowProfiles[i].name, 100 + 1);
pickProfilesMenuItems[i] = OledMenuItem(reflowProfiles[i].name, MENUITEM_PROFILE_START + i);
}
pickProfilesMenu->setElements(pickProfilesMenuItems, nReflowProfiles);
@ -156,7 +176,7 @@ void OledDisplay::loop()
{
handleUserInputState();
}
else if (state >= REFLOW && state <= DONE)
else if (state >= PREHEAT && state <= DONE)
{
handleReflowState();
}
@ -193,12 +213,23 @@ void OledDisplay::displayIndicators()
display.setCursor(SCREEN_HEIGHT - 14, SCREEN_WIDTH / 2 - 5);
display.print(">");
}
void OledDisplay::centerText(const char *txt)
void OledDisplay::centerText(const char *txt, DisplayTextAlignment horizontal, DisplayTextAlignment vertical)
{
int16_t x1, y1;
uint16_t w, h;
display.getTextBounds(txt, 0, 0, &x1, &y1, &w, &h);
display.setCursor(display.width() / 2 - w / 2, display.height() / 2 - h / 2);
int cursorX = (horizontal == DisplayTextAlignment::CENTER ? display.width() / 2 - w / 2 : 0);
if (horizontal == DisplayTextAlignment::END)
{
cursorX = display.width() - w;
}
int cursorY = (vertical == DisplayTextAlignment::CENTER ? display.height() / 2 - h / 2 : 0);
if (vertical == DisplayTextAlignment::END)
{
cursorY = display.height() - h;
}
display.setCursor(cursorX, cursorY);
display.println(txt);
}
@ -231,8 +262,21 @@ void OledDisplay::handleUserInputState()
void OledDisplay::handleReflowState()
{
display.clearDisplay();
display.setRotation(0);
display.setCursor(0, 0);
display.setTextSize(2);
ReflowProcessState state = reflowProcessState.get();
centerText(STATE_STR(state));
centerText(STATE_STR(state), DisplayTextAlignment::CENTER, DisplayTextAlignment::START);
display.setTextSize(1, 2);
uint32_t elapsedStep = chosenReflowProfile.getCurrentStepRelativeTime();
centerText("Remaining", DisplayTextAlignment::START, DisplayTextAlignment::CENTER);
centerText((String(chosenReflowProfile.curReflowStep().duration - elapsedStep) + "s").c_str(), DisplayTextAlignment::START, DisplayTextAlignment::END);
uint8_t curTemp = thermistor1.getTemperature();
uint8_t targetTemp = pidControllerData.targetTemp;
centerText(("Curr.: " + String(curTemp)).c_str(), DisplayTextAlignment::END, DisplayTextAlignment::CENTER);
centerText(("Target: " + String(targetTemp)).c_str(), DisplayTextAlignment::END, DisplayTextAlignment::END);
display.display();
}

View File

@ -3,7 +3,11 @@
#include <Adafruit_SSD1306.h>
#include "../reflow.h"
#include "menustatemachine.h"
enum DisplayTextAlignment {
START,
CENTER,
END
};
class OledDisplay {
public:
OledDisplay();
@ -18,12 +22,12 @@ class OledDisplay {
void drawDebug();
void handleUserInputState();
void handleReflowState();
void centerText(const char * text);
void centerText(const char * text) {
centerText(text, DisplayTextAlignment::CENTER, DisplayTextAlignment::CENTER);
}
void centerText(const char * text, DisplayTextAlignment horizontal, DisplayTextAlignment vertical);
void displayIndicators();
void handleDrawThermistorMenu(OledMenuItem item);
};
#endif

View File

@ -14,23 +14,23 @@ Thermistor thermistor6(THERMISTOR6_PIN, 9000);
Thermistor thermistors[6] = {thermistor1, thermistor2, thermistor3, thermistor4, thermistor5, thermistor6};
ReflowProfile reflowProfiles[] = {
ReflowProfile(new ReflowStep[5] {
ReflowStep(ReflowProcessState::PREHEAT, 2, 150),
ReflowStep(ReflowProcessState::SOAK, 3, 180),
ReflowStep(ReflowProcessState::REFLOW, 3, 220, EASE_IN_OUT),
ReflowStep(ReflowProcessState::COOL, 3, 100),
ReflowStep(ReflowProcessState::DONE, 0, 0)
}, "Test\0"),
ReflowProfile(new ReflowStep[5] {
ReflowStep(ReflowProcessState::PREHEAT, 2, 150),
ReflowStep(ReflowProcessState::SOAK, 3, 180),
ReflowStep(ReflowProcessState::REFLOW, 3, 220, EASE_IN_OUT),
ReflowStep(ReflowProcessState::COOL, 3, 100),
ReflowStep(ReflowProcessState::DONE, 0, 0)
}, "Test2\0"),
//138c profile Sn42Bi58
ReflowProfile(new ReflowStep[5]{
ReflowStep(ReflowProcessState::PREHEAT, 60, 100, EASE_OUT),
ReflowStep(ReflowProcessState::SOAK, 90, 155),
ReflowStep(ReflowProcessState::REFLOW, 45, 185, EASE_OUT),
ReflowStep(ReflowProcessState::COOL, 45, 155, EASE_OUT),
ReflowStep(ReflowProcessState::DONE, 0, 0)},
"138c Sn42Bi58\0"),
ReflowProfile(new ReflowStep[5]{ReflowStep(ReflowProcessState::PREHEAT, 2, 150), ReflowStep(ReflowProcessState::SOAK, 3, 180), ReflowStep(ReflowProcessState::REFLOW, 3, 220, EASE_IN_OUT), ReflowStep(ReflowProcessState::COOL, 3, 100), ReflowStep(ReflowProcessState::DONE, 0, 0)}, "Test2\0"),
};
ReflowProfile chosenReflowProfile = reflowProfiles[0];
int nReflowProfiles = 2;
uint16_t plateResistanceOhm = 0;
EEPROMDataManager eepromDataManager = EEPROMDataManager();
PidControllerData pidControllerData = {0 /*currentTemp*/, 60 /*TargetTemp*/, 255 /*PWM*/};
PidController pidController = PidController(&pidControllerData);

View File

@ -4,6 +4,7 @@
#include "./thermistors/Thermistor.h"
#include "./reflow.h"
#include "./EEPROMDataManager.h"
#include "./PID/PidController.h"
extern WrappedState<ReflowProcessState> reflowProcessState;
extern AnalogRef analogRef;
@ -15,11 +16,12 @@ extern Thermistor thermistor5;
extern Thermistor thermistor6;
extern Thermistor thermistors[6];
extern ReflowProfile reflowProfiles[];
extern ReflowProfile chosenReflowProfile;
extern uint16_t plateResistanceOhm;
// EEPROM data manager is in its own file
extern int nReflowProfiles;
extern PidControllerData pidControllerData;
extern PidController pidController;
extern EEPROMDataManager eepromDataManager;
#endif

View File

@ -9,7 +9,8 @@
#include "leds/leds.h"
#include "reflow.h"
#include "displays/oled.h"
#include "globals.h"
#include "PID/PidController.h"
#include "globals.h"
#include "EEPROMDataManager.h"
// LCD display pins
@ -21,6 +22,11 @@
// Create an instance of the Adafruit ST7789 class using the custom SPI pins
Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, MOSI, SCK, TFT_RST);
#define MOSTFET_PIN 17
double currentTemp = 0;
double targetTemp = 60;
double pwmValue = 255;
Buttons buttons = Buttons();
LEDS leds = LEDS();
@ -29,9 +35,13 @@ ArduPID PID;
OledDisplay oled = OledDisplay();
void setup()
{
pinMode(MOSTFET_PIN, OUTPUT);
analogWrite(MOSTFET_PIN, 255); // VERY IMPORTANT, DONT CHANGE!
Serial.begin(38400);
Serial.println("Starting OLED");
@ -41,43 +51,66 @@ void setup()
leds.setup();
oled.setup();
eepromDataManager.setup();
reflowProcessState = USER_INPUT;
}
reflowProcessState.set(USER_INPUT);
}
void loop()
{
// Return the button that changed state
Pair<ButtonKind, StateChangeEvent<ButtonState>> *k = buttons.handleButtons();
if (k != NULL) {
ReflowProcessState state = reflowProcessState.get();
if (k != NULL)
{
leds.handleButtonStateChange(*k);
oled.handleButtonStateChange(*k);
// if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::SELECT, ButtonState::PRESSED)) {
// reflowProcessState.set(ReflowProcessState::PREHEAT);
// } else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::BACK, ButtonState::PRESSED)) {
// reflowProcessState.set(ReflowProcessState::USER_INPUT);
// } else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::UP, ButtonState::PRESSED)) {
// reflowProcessState.set(ReflowProcessState::COOL);
// } else if (ISBUTTONMIGRATEDTOSTATE(*k, ButtonKind::DOWN, ButtonState::PRESSED)) {
// reflowProcessState.set(ReflowProcessState::REFLOW);
// }
if (state == USER_INPUT)
{
oled.handleButtonStateChange(*k);
}
else if (state >= PREHEAT && state <= COOL)
{
if (k->first == ButtonKind::BACK && k->second.to == ButtonState::PRESSED)
{
// STOP REFLOW and restart
reflowProcessState.set(USER_INPUT);
pidControllerData.targetTemp = 0; // should not be needed but why not?
pidController.stop();
}
}
}
ReflowProcessState newState = reflowProcessState.get();
if (newState != state) {
Serial.println("State changed from " + String(STATE_STR(state)) + " to " + String(STATE_STR(newState)));
// State changed from state to newState (user input or wifi input needs to be above here)
if (newState == PREHEAT) {
chosenReflowProfile.start();
pidController.start();
}
}
// ReflowStep step = profile.curReflowStep();
// if (step.state != reflowProcessState.get()) {
// reflowProcessState.set(step.state);
// }
oled.loop();
if (state >= PREHEAT && state <= COOL)
{
pidController.loop();
ReflowStep step = chosenReflowProfile.curReflowStep();
if (step.state != newState)
{
reflowProcessState.set(step.state);
}
}
if (state == DONE)
{
// TODO: BUZZER
reflowProcessState.set(USER_INPUT);
}
oled.loop();
// if (step.state == ReflowProcessState::DONE) {
// profile.start();
// return;
// }
// Serial.print(String(STATE_STR(step.state)) + " " + String(step.duration) + " " + String(step.targetTempAtEnd) + " " + String(profile.getTargetTemp())+"\r");
}

View File

@ -3,7 +3,10 @@
#include "./common.h"
#include <EEPROM.h>
#include "StopWatch.h"
#include "thermistors/Thermistor.h"
#include "displays/oled.h"
extern Thermistor thermistor1;
// STATE MACHINE
enum ReflowProcessState
@ -18,13 +21,13 @@ enum ReflowProcessState
};
#define STATE_STR(state) (state == INITIALIZING ? "INITIALIZING" \
: state == USER_INPUT ? "USER_INPUT" \
: state == PREHEAT ? "PREHEAT" \
: state == SOAK ? "SOAK" \
: state == REFLOW ? "REFLOW" \
: state == COOL ? "COOL" \
: state == DONE ? "DONE" \
: "UNKNOWN")
: state == USER_INPUT ? "USER_INPUT" \
: state == PREHEAT ? "PREHEAT" \
: state == SOAK ? "SOAK" \
: state == REFLOW ? "REFLOW" \
: state == COOL ? "COOL" \
: state == DONE ? "DONE" \
: "UNKNOWN")
enum ReflowStepEaseFunction
{
@ -55,10 +58,14 @@ public:
{
case LINEAR:
return startTemp + (this->targetTempAtEnd - startTemp) * percentage;
case EASE_IN_OUT:
return startTemp + (this->targetTempAtEnd - startTemp) * -(cos(percentage * PI) - 1) / (double)2;
Serial.println(this->targetTempAtEnd);
case EASE_IN:
return startTemp + (this->targetTempAtEnd - startTemp) * (1 - cos(percentage * PI / (double)2));
case EASE_OUT:
return startTemp + (this->targetTempAtEnd - startTemp) * (sin(percentage * PI / (double)2));
}
@ -67,13 +74,31 @@ public:
#define PROFILE_SERIALIZED_SIZE 40
#define PROFILE_SERIALIZED_NAME_SIZE 20
class ReflowProfile
{
public:
uint8_t preheatEndTime;
uint8_t soakEndTime;
uint8_t reflowEndTime;
uint8_t coolEndTime;
int totalDuration;
float targetTempReflow;
float percentage;
ReflowProfile(ReflowStep steps[5], char name[20])
{
memcpy(this->steps, steps, 5 * sizeof(steps[0]));
memcpy(this->name, name, PROFILE_SERIALIZED_NAME_SIZE);
for (int i = 0; i < 5; i++)
{
this->steps[i] = steps[i];
}
for (int i = 0; i < 20; i++)
{
this->name[i] = name[i];
}
}
ReflowStep steps[5];
char name[20];
@ -81,54 +106,207 @@ public:
void start()
{
timer = StopWatch(StopWatch::Resolution::MILLIS);
timer = StopWatch(StopWatch::Resolution::SECONDS);
timer.start();
}
/**
* Calculates the current reflow step based on the elapsed time
*/
ReflowStep curReflowStep() {
int8_t reflowStep = curReflowStepIndexAt(timer.elapsed());
if (reflowStep == -1) {
return steps[4]; // DONE
}
return steps[reflowStep];
calculateEndTimes();
}
int8_t curReflowStepIndexAt(uint32_t elapsed) {
for (int i = 0; i < 5; i++)
void calculateEndTimes()
{
preheatEndTime = steps[0].duration;
int soakEnd = steps[1].duration;
soakEndTime = preheatEndTime + soakEnd;
reflowEndTime = soakEndTime + steps[2].duration;
coolEndTime = reflowEndTime + steps[3].duration;
// reflowEndTime = soakEndTime + (steps[2].duration*1000);
// coolEndTime = reflowEndTime + (steps[3].duration*1000);
Serial.print("preheatEndTime: ");
Serial.println(preheatEndTime);
Serial.print("soakEndTime: ");
Serial.println(soakEndTime);
Serial.print("reflowEndTime: ");
Serial.println(reflowEndTime);
Serial.print("coolEndTime: ");
Serial.println(coolEndTime);
totalDuration = coolEndTime + steps[4].duration;
Serial.print("totalDuration: ");
Serial.println(totalDuration);
}
ReflowStep curReflowStep()
{
uint8_t elapsed = timer.elapsed();
if (elapsed <= preheatEndTime)
{
if (elapsed < steps[i].duration * 1000)
{
return i;
}
else
{
elapsed -= steps[i].duration * 1000;
}
return steps[0];
}
else if (elapsed < soakEndTime)
{
return steps[1];
}
else if (elapsed < reflowEndTime)
{
return steps[2];
}
else if (elapsed < coolEndTime)
{
return steps[3];
}
else
{
return steps[4];
timer.stop();
timer.reset();
}
}
ReflowStep getPreviousSetep(ReflowStep step)
{
if (step.state == PREHEAT)
{
return steps[0];
}
else if (step.state == SOAK)
{
return steps[1];
}
else if (step.state == REFLOW)
{
return steps[2];
}
else if (step.state == COOL)
{
return steps[3];
}
else
{
return steps[4];
}
return -1; // we are done
}
float getTargetTemp()
{
uint32_t elapsedTime = timer.elapsed();
uint8_t startTemp = 20; // always assume 20 degrees at the start
int curStep = curReflowStepIndexAt(elapsedTime);
if (curStep == -1) {
// uint8_t startTemp=thermistor1.getTemperature();
ReflowStep curStep = curReflowStep();
ReflowStep prevStep = getPreviousSetep(curStep);
int currenStepIndex = getCurrentStepIndex(curStep);
int previousStepIndex = getCurrentStepIndex(prevStep);
float relativeTIme = calculateCurrentStepRelativeTime(curStep);
if (currenStepIndex == -1)
{
timer.reset();
timer.stop();
return startTemp; // We are done return 20 degrees
}
uint32_t relativeElapsedTime = elapsedTime;
for (int i=0; i<curStep; i++) {
relativeElapsedTime -= steps[i].duration * 1000;
for (int i = 0; i < currenStepIndex; i++)
{
relativeElapsedTime -= steps[i].duration;
startTemp = steps[i].targetTempAtEnd;
}
// Calculate percentage of current step
float percentage = (float)relativeElapsedTime / (float)(steps[curStep].duration * 1000);
return steps[curStep].calcTempAtPercentage(startTemp, percentage);
// float temp = curStep.calcTempAtPercentage(startTemp, percentage);
// Serial.print("relativeElapsedTime: ");
// Serial.println(relativeElapsedTime);
// Serial.print("relativeTIme: ");
// Serial.println(relativeTIme);
// Serial.print("startTemp: ");
// Serial.println(startTemp);
percentage = (float)relativeElapsedTime / (float)(steps[currenStepIndex].duration);
targetTempReflow = steps[currenStepIndex].calcTempAtPercentage(startTemp, percentage);
return targetTempReflow;
}
int getCurrentStepIndex()
{
uint8_t elapsed = timer.elapsed();
if (elapsed <= preheatEndTime)
{
return 0;
}
else if (elapsed < soakEndTime)
{
return 1;
}
else if (elapsed < reflowEndTime)
{
return 2;
}
else if (elapsed < coolEndTime)
{
return 3;
}
else
{
return 4;
}
}
int getCurrentStepIndex(ReflowStep step)
{
if (step.state == PREHEAT)
{
return 0;
}
else if (step.state == SOAK)
{
return 1;
}
else if (step.state == REFLOW)
{
return 2;
}
else if (step.state == COOL)
{
return 3;
}
else
{
return 4;
}
}
uint8_t getCurrentStepRelativeTime()
{
return calculateCurrentStepRelativeTime(curReflowStep());
};
uint8_t calculateCurrentStepRelativeTime(ReflowStep step)
{
uint32_t elapsed = timer.elapsed();
switch (step.state)
{
case PREHEAT:
return elapsed;
case SOAK:
return elapsed - preheatEndTime;
case REFLOW:
return elapsed - soakEndTime;
case COOL:
return elapsed - reflowEndTime;
case DONE:
return elapsed - coolEndTime;
}
}
void toBuffer(uint8_t *b)
@ -161,7 +339,7 @@ public:
(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]);
(ReflowStepEaseFunction)b[PROFILE_SERIALIZED_NAME_SIZE + 2 + i * 3]);
}
return ReflowProfile(steps, name);
}

BIN
src/reflow.rar Normal file

Binary file not shown.

BIN
src/reflow2.rar Normal file

Binary file not shown.

View File

@ -1,11 +1,11 @@
#include "Thermistor.h"
int Thermistor::getTemperature()
float Thermistor::getTemperature()
{
// Get an average of 5 readings
int temp = 0;
float temp = 0;
uint8_t samples = 5;

View File

@ -50,7 +50,7 @@ public:
}
// Public Methods
int getTemperature();
float getTemperature();
float getResistance();
void setPotentiometerResistance(uint16_t resistance) { setRes = resistance; };
uint16_t getPotentiometerResistance() { return setRes; };

View File

@ -0,0 +1,49 @@
#ifndef EXECUTIONTIMER_H
#define EXECUTIONTIMER_H
#include <Arduino.h>
class ExecutionTimer {
private:
unsigned long startTime;
unsigned long endTime;
bool isRunning;
public:
ExecutionTimer() {
startTime = 0;
endTime = 0;
isRunning = false;
}
void start() {
startTime = millis(); // Use micros() for microsecond precision
isRunning = true;
}
unsigned long stop() {
if (isRunning) {
endTime = millis(); // Use micros() for microsecond precision
isRunning = false;
Serial.print("Execution time: ");
Serial.print(endTime - startTime);
Serial.println(" ms");
return endTime - startTime;
} else {
return 0; // or retain the last execution time
}
}
// Optional: Function to get the elapsed time without stopping
unsigned long elapsed() const {
if (isRunning) {
return millis() - startTime; // Use micros() for microsecond precision
} else {
return endTime - startTime;
}
}
};
#endif // EXECUTIONTIMER_H