diff --git a/src/buttons/Button.cpp b/src/buttons/Button.cpp index bb18d58..6c46d6c 100644 --- a/src/buttons/Button.cpp +++ b/src/buttons/Button.cpp @@ -1,52 +1,46 @@ #include "Button.h" #include - // Constructor -Button::Button(ButtonKind kind, uint8_t pin) : kind(kind), pin(pin), state(ButtonState::IDLE) { +Button::Button(ButtonKind kind, uint8_t pin) : kind(kind), pin(pin), state(WrappedState(kind, ButtonState::IDLE)) +{ pinMode(pin, INPUT_PULLUP); - this->change = new ButtonStateChange(this->kind, ButtonState::IDLE, ButtonState::IDLE); - lastStateChangeTime = 0; } -ButtonKind Button::getKind() { +ButtonKind Button::getKind() +{ return this->kind; } -uint8_t Button::getPin() { +uint8_t Button::getPin() +{ return this->pin; } -ButtonState Button::getState() { - return this->state; +StateChangeEvent *Button::lastChange() +{ + return this->state.lastChangeEvent; } -ButtonStateChange* Button::lastChange() { - return this->change; -} +bool Button::loop() +{ + StateChangeEvent *evt = NULL; -void Button::setState(ButtonState state) { - if (this->state != state) { - delete this->change; // clear memory - this->change = new ButtonStateChange(this->kind, this->state, state); - lastStateChangeTime = millis(); - this->state = state; - } -} - -bool Button::loop() { - ButtonState prev = this->state; - if (digitalRead(this->pin) == LOW) { - if (this->state == ButtonState::IDLE && millis() - lastStateChangeTime > 50) { - this->setState(ButtonState::PRESSED); + if (digitalRead(this->pin) == LOW) + { + if (this->state.get() == ButtonState::IDLE && millis() - this->state.lastStateChangeTime > 50) + { + evt = this->state.set(ButtonState::PRESSED); } - } else if (this->state == ButtonState::PRESSED) { - this->setState(ButtonState::RELEASED); } - if (this->state == ButtonState::RELEASED && millis() - lastStateChangeTime > 50) { - this->setState(ButtonState::IDLE); + else if (this->state.get() == ButtonState::PRESSED) + { + evt = this->state.set(ButtonState::RELEASED); + } + if (this->state.get() == ButtonState::RELEASED && millis() - this->state.lastStateChangeTime > 50) + { + evt = this->state.set(ButtonState::IDLE); } - // Return true if the state changed - return prev != this->state; + return evt != NULL; } \ No newline at end of file diff --git a/src/buttons/Button.h b/src/buttons/Button.h index 8d6fa17..7a6a05e 100644 --- a/src/buttons/Button.h +++ b/src/buttons/Button.h @@ -1,5 +1,6 @@ #include "base.h" #include +#include "../statechangeevent.h" class Button { @@ -9,18 +10,13 @@ public: ButtonKind getKind(); uint8_t getPin(); - ButtonState getState(); - ButtonStateChange* lastChange(); - void setState(ButtonState state); + StateChangeEvent *lastChange(); /// @brief Call this method in the main loop to update the button state. /// @return true if the button state changed, false otherwise. bool loop(); - - private : - unsigned long lastStateChangeTime; - ButtonKind kind; - uint8_t pin; - ButtonState state; - ButtonStateChange* change; +private: + ButtonKind kind; + uint8_t pin; + WrappedState state; }; \ No newline at end of file diff --git a/src/buttons/Buttons.cpp b/src/buttons/Buttons.cpp index 9d2eafb..e2bd945 100644 --- a/src/buttons/Buttons.cpp +++ b/src/buttons/Buttons.cpp @@ -1,9 +1,7 @@ #include "Buttons.h" - Button *__buttons[4]; - void Buttons::setup() { __buttons[ButtonKind::UP] = new Button(ButtonKind::UP, upButton); @@ -13,15 +11,16 @@ void Buttons::setup() } /** * Handle buttons state changes and return first button state change that occurred. -*/ -ButtonStateChange* Buttons::handleButtons() + */ +StateChangeEvent *Buttons::handleButtons() { for (int i = 0; i < 4; i++) { // If a state change occurred, print it out and return the button that changed - if ( __buttons[i]->loop()) + if (__buttons[i]->loop()) { - ButtonStateChange *change = __buttons[i]->lastChange(); + StateChangeEvent *change = __buttons[i]->lastChange(); + Serial.println(STATECHANGE_STR((*change))); return change; } diff --git a/src/buttons/Buttons.h b/src/buttons/Buttons.h index 9fd026d..004d214 100644 --- a/src/buttons/Buttons.h +++ b/src/buttons/Buttons.h @@ -5,23 +5,21 @@ #include #include "Button.h" #include "leds/leds.h" - +#include "../statechangeevent.h" // Button pins #define upButton 21 #define downButton 22 #define backButton 23 #define selectButton 24 - class Buttons { public: // Constructor - Buttons() {}; + Buttons(){}; - ButtonStateChange* handleButtons(); + StateChangeEvent *handleButtons(); void setup(); - }; #endif // BUTTONS_H diff --git a/src/buttons/base.h b/src/buttons/base.h index b99cac5..a464e6e 100644 --- a/src/buttons/base.h +++ b/src/buttons/base.h @@ -22,13 +22,4 @@ enum ButtonKind #define STATE_STR(state) (state == ButtonState::IDLE ? "IDLE" : state == ButtonState::PRESSED ? "PRESSED" : "RELEASED") #define STATECHANGE_STR(change) (String("ButtonStateChange: kind=") + KIND_STR(change.kind) + ", " + STATE_STR(change.from) + " -> " + STATE_STR(change.to)) - -class ButtonStateChange { - public: - ButtonStateChange(ButtonKind kind, ButtonState from, ButtonState to) : kind(kind), from(from), to(to) {} - ButtonKind kind; - ButtonState from; - ButtonState to; - -}; #endif \ No newline at end of file diff --git a/src/displays/oled.cpp b/src/displays/oled.cpp new file mode 100644 index 0000000..8c72226 --- /dev/null +++ b/src/displays/oled.cpp @@ -0,0 +1,49 @@ +#include "./oled.h" +#include +#define SCREEN_WIDTH 128 +#define SCREEN_HEIGHT 64 +#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) +OledDisplay::OledDisplay() { + + display = Adafruit_SSD1306(SCREEN_WIDTH, SCREEN_HEIGHT); +} + +void OledDisplay::setup() { + // Setup implementation + bool initialized = display.begin(SSD1306_SWITCHCAPVCC, 0x3C); + if (!initialized) { + Serial.println("OLED Display failed to initialize"); + } else { + Serial.println("OLED Display initialized"); + } + display.setRotation(0); +} + +void OledDisplay::loop() { + display.clearDisplay(); + display.setTextSize(2); + display.setTextColor(SSD1306_WHITE); + display.setCursor(0, 0); + if (reflowProcessState == INITIALIZING) { + display.println("INITIALIZING"); + } else if (reflowProcessState == USER_INPUT) { + display.println("USER_INPUT"); + } else if (reflowProcessState == PREHEAT) { + display.println("PREHEAT"); + } else if (reflowProcessState == SOAK) { + display.println("SOAK"); + } else if (reflowProcessState == REFLOW) { + display.println("REFLOW"); + } else if (reflowProcessState == COOL) { + display.println("COOL"); + } else if (reflowProcessState == DONE) { + display.println("DONE"); + } + display.println("zz"); + display.display(); + // Loop implementation +} + +void OledDisplay::teardown() { + // delete display; +} diff --git a/src/displays/oled.h b/src/displays/oled.h new file mode 100644 index 0000000..929ae0a --- /dev/null +++ b/src/displays/oled.h @@ -0,0 +1,18 @@ +#ifndef __oled_h +#define __oled_h +#include +#include "../reflow.h" +class OledDisplay { + public: + OledDisplay(); + void setup(); + void loop(); + void teardown(); + + private: + Adafruit_SSD1306 display; +}; + + + +#endif \ No newline at end of file diff --git a/src/leds/Leds.cpp b/src/leds/Leds.cpp index fc49d17..7a69a94 100644 --- a/src/leds/Leds.cpp +++ b/src/leds/Leds.cpp @@ -14,7 +14,7 @@ void LEDS::setup() pinMode(greenLED, OUTPUT); pinMode(redLED, OUTPUT); } -void LEDS::handleButtonStateChange(ButtonStateChange change) +void LEDS::handleButtonStateChange(StateChangeEvent change) { switch (change.kind) { case ButtonKind::UP: diff --git a/src/leds/leds.h b/src/leds/leds.h index c0f9e2e..3971d0d 100644 --- a/src/leds/leds.h +++ b/src/leds/leds.h @@ -1,6 +1,7 @@ #ifndef __leds_h__ #define __leds_h__ #include "../buttons/base.h" +#include "../statechangeevent.h" //If you didnt solder the LEDS in order, change the order here #define yellowLED 18 @@ -12,7 +13,7 @@ class LEDS public: LEDS(); void setup(); - void handleButtonStateChange(ButtonStateChange change); + void handleButtonStateChange(StateChangeEvent change); }; #endif \ No newline at end of file diff --git a/src/main.cpp b/src/main.cpp index 4cb5045..e272fca 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,11 +3,15 @@ #include // Include the ST7789 library #include #include -#include #include #include #include "buttons/Buttons.h" #include "leds/leds.h" +#include "reflow.h" +#include "displays/oled.h" +#include "statechangeevent.h" + +ReflowProcessState reflowProcessState = INITIALIZING; // Define the analog ref used for the system voltage AnalogRef analogRef(5.0); @@ -24,11 +28,6 @@ TempCalibration calibration_100K_3950 = {25, 100000, 86, 10000, 170, 1000}; // 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); -// OLED display width and height, for a typical 128x64 display -#define SCREEN_WIDTH 128 -#define SCREEN_HEIGHT 64 -#define OLED_RESET -1 // Reset pin # (or -1 if sharing Arduino reset pin) -Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET); // Initalize the 3950 100K thermistors with ACTUAL reference resistor measurnment(Measured between Left pin and GND when the board is powered off) using the default calibration data for 100K thermistor Thermistor thermistor1(THERMISTOR1_PIN, 2500); @@ -43,6 +42,7 @@ Buttons buttons = Buttons(); LEDS leds = LEDS(); // Declare the PID ArduPID PID; +OledDisplay oled = OledDisplay(); void setup() { @@ -50,13 +50,11 @@ void setup() Serial.begin(9600); Serial.println("Starting OLED"); - display.begin(SSD1306_SWITCHCAPVCC, 0x3C); - display.setRotation(3); - // Set PWM frequency to 64 kHz analogWriteFrequency(64); buttons.setup(); leds.setup(); + oled.setup(); Serial.println("Starting LCD"); @@ -85,13 +83,14 @@ void setup() // // // Print text to screen // tft.print(text); Serial.println("Ready!"); + reflowProcessState = USER_INPUT; } void loop() { // Return the button that was pressed - ButtonStateChange* k = buttons.handleButtons(); + StateChangeEvent* k = buttons.handleButtons(); if (k != NULL) { leds.handleButtonStateChange(*k); @@ -100,38 +99,9 @@ void loop() float sysVoltage = analogRef.calculateSystemVoltage(); float inputVoltage = analogRef.calculateInputVoltage(); int thermistor1Temp = thermistor1.getTemperature(); - + oled.loop(); // Print the system voltage on the tft -return; - display.clearDisplay(); - Serial.print("Thermistor 1: "); - Serial.println(thermistor1Temp); - char *text = "Sys V: "; - display.setTextSize(2); - display.setTextColor(SSD1306_WHITE); - display.setCursor(0, 20); - display.println(text); - display.setCursor(0, 40); - display.println(sysVoltage); - char *text2 = "In V: "; - display.setTextSize(2); - display.setTextColor(SSD1306_WHITE); - display.setCursor(0, 60); - display.println(text2); - display.setCursor(0, 80); - display.println(inputVoltage); - char *text3 = "C:"; - display.setTextSize(2); - display.setTextColor(SSD1306_WHITE); - display.setCursor(0, 100); - display.println(text3); - display.setCursor(25, 100); - display.println(thermistor1Temp); - display.display(); - - // Serial.println("System voltage: "); - // Serial.print("Output voltage: "); // Serial.println(sysVoltage); diff --git a/src/reflow.h b/src/reflow.h new file mode 100644 index 0000000..4ea1d50 --- /dev/null +++ b/src/reflow.h @@ -0,0 +1,19 @@ +#ifndef __reflow_h__ +#define __reflow_h__ + +// STATE MACHINE +enum ReflowProcessState { + INITIALIZING, // default. This is the state the reflow oven/PCB is in when it is first turned on + USER_INPUT, // The user is selecting a profile to use for the reflow process + PREHEAT, // The oven/PCB is heating up to the preheat temperature + SOAK, // The oven/PCB is heating up to the soak temperature + REFLOW, // The oven/PCB is heating up to the reflow temperature + COOL, // The oven/PCB is cooling down to the cool temperature + DONE // The reflow process is complete +}; + +// Holds current reflow process state to be used by other classes +// Such as the menu class to display the current state +extern ReflowProcessState reflowProcessState; + +#endif \ No newline at end of file diff --git a/src/statechangeevent.h b/src/statechangeevent.h new file mode 100644 index 0000000..9fccd44 --- /dev/null +++ b/src/statechangeevent.h @@ -0,0 +1,37 @@ +#ifndef __basestatechange_h__ +#define __basestatechange_h__ +#include +template +class StateChangeEvent { + public: + StateChangeEvent(Kind kind, State from, State to) : kind(kind), from(from), to(to) {} + Kind kind; + State from; + State to; + +}; + + +template +class WrappedState { + public: + WrappedState(Kind kind, State defaultState) : kind(kind), state(defaultState), lastChangeEvent(new StateChangeEvent(kind, defaultState, defaultState)) {} + Kind kind; + StateChangeEvent * set(State state) { + if (this->state == state) { + return NULL; + } + delete this->lastChangeEvent; + lastChangeEvent = new StateChangeEvent(kind, this->state, state); + this->state = state; + this->lastStateChangeTime = millis(); + return lastChangeEvent; + } + State get() { + return this->state; + } + State state; + unsigned long lastStateChangeTime = 0; + StateChangeEvent * lastChangeEvent; +}; +#endif \ No newline at end of file