1
0

2 Commits 9326ea518e ... cb2ca85757

Autor SHA1 Nachricht Datum
  Abhinav Sinha cb2ca85757 Add profile functionality, PLA and PETG drying profiles vor 5 Jahren
  Abhinav Sinha 444dbcbb18 use easybutton library vor 5 Jahren
2 geänderte Dateien mit 62 neuen und 99 gelöschten Zeilen
  1. 1 0
      platformio.ini
  2. 61 99
      src/main.cpp

+ 1 - 0
platformio.ini

@@ -12,3 +12,4 @@
 platform = atmelavr
 platform = atmelavr
 board = nanoatmega328
 board = nanoatmega328
 framework = arduino
 framework = arduino
+lib_deps = evert-arias/EasyButton@^2.0.1

+ 61 - 99
src/main.cpp

@@ -2,14 +2,12 @@
 #include <U8g2lib.h>
 #include <U8g2lib.h>
 #include <PID_v1.h>
 #include <PID_v1.h>
 #include <MAX6675.h>
 #include <MAX6675.h>
-#include <SPI.h>
-
-#define THERMOCOUPLE_CS_PIN 7
+#include <EasyButton.h>
 
 
 #define DISPLAY_RESET_PIN 10
 #define DISPLAY_RESET_PIN 10
 #define DISPLAY_DC_PIN 9
 #define DISPLAY_DC_PIN 9
 #define DISPLAY_CS_PIN 8
 #define DISPLAY_CS_PIN 8
-
+#define THERMOCOUPLE_CS_PIN 7
 #define DONE_LED_PIN 5
 #define DONE_LED_PIN 5
 #define SSR_PIN 4
 #define SSR_PIN 4
 #define BUTTON_PIN 3
 #define BUTTON_PIN 3
@@ -41,25 +39,24 @@ typedef enum REFLOW_STATUS
   REFLOW_STATUS_ON
   REFLOW_STATUS_ON
 } reflowStatus_t;
 } reflowStatus_t;
 
 
-typedef enum DEBOUNCE_STATE
-{
-  DEBOUNCE_STATE_IDLE,
-  DEBOUNCE_STATE_CHECK,
-  DEBOUNCE_STATE_RELEASE
-} debounceState_t;
 
 
-typedef	enum SWITCH
-{
-	SWITCH_NONE,
-	SWITCH_1
-}	switch_t;
+struct reflowProfile{
+  const char* profileName;
+  int soakTemp;
+  unsigned long soakPeriodMS;
+};
+
+#define NUM_REFLOW_PROFILES 3
+reflowProfile profiles[NUM_REFLOW_PROFILES] = {
+  {"Sanitize Masks", 70, 1800000}, // 30*60*1000 30 minutes
+  {"Dry PLA", 45, 1800000*8},
+  {"Dry PETG", 70, 1800000*4}
+};
 
 
 // ***** CONSTANTS *****
 // ***** CONSTANTS *****
-#define TEMPERATURE_ROOM 70
-#define TEMPERATURE_SOAK 70
+#define TEMPERATURE_ROOM 45
 #define TEMPERATURE_COOL_MIN 50
 #define TEMPERATURE_COOL_MIN 50
 #define SENSOR_SAMPLING_TIME 1000
 #define SENSOR_SAMPLING_TIME 1000
-#define SOAK_PERIOD_MS 1800000 // 30*60*1000 30 minutes
 #define DEBOUNCE_PERIOD_MIN 50
 #define DEBOUNCE_PERIOD_MIN 50
 
 
 // ***** PID PARAMETERS *****
 // ***** PID PARAMETERS *****
@@ -82,7 +79,7 @@ double output;
 double kp = PID_KP_PREHEAT;
 double kp = PID_KP_PREHEAT;
 double ki = PID_KI_PREHEAT;
 double ki = PID_KI_PREHEAT;
 double kd = PID_KD_PREHEAT;
 double kd = PID_KD_PREHEAT;
-int windowSize;
+unsigned int windowSize;
 unsigned long now;
 unsigned long now;
 unsigned long windowStartTime;
 unsigned long windowStartTime;
 unsigned long nextRead;
 unsigned long nextRead;
@@ -93,23 +90,20 @@ unsigned long completePeriod;
 reflowState_t reflowState = REFLOW_STATE_IDLE;
 reflowState_t reflowState = REFLOW_STATE_IDLE;
 // Reflow oven controller status
 // Reflow oven controller status
 reflowStatus_t reflowStatus = REFLOW_STATUS_OFF;
 reflowStatus_t reflowStatus = REFLOW_STATUS_OFF;
-// Switch debounce state machine state variable
-debounceState_t debounceState;
-// Switch debounce timer
-long lastDebounceTime;
-// Switch press status
-switch_t switchStatus;
 // did encounter a thermocouple error?
 // did encounter a thermocouple error?
 int tcErrorCount = 0;
 int tcErrorCount = 0;
 bool TCError = false;
 bool TCError = false;
+bool startReflow = false;
+int activeReflowProfile = 0;
 
 
 MAX6675 tcouple(THERMOCOUPLE_CS_PIN);
 MAX6675 tcouple(THERMOCOUPLE_CS_PIN);
 U8G2_SSD1305_128X64_ADAFRUIT_F_4W_HW_SPI u8g2(U8G2_R0, DISPLAY_CS_PIN, DISPLAY_DC_PIN, DISPLAY_RESET_PIN);
 U8G2_SSD1305_128X64_ADAFRUIT_F_4W_HW_SPI u8g2(U8G2_R0, DISPLAY_CS_PIN, DISPLAY_DC_PIN, DISPLAY_RESET_PIN);
 PID reflowOvenPID(&inputTemp, &output, &setpoint, kp, ki, kd, DIRECT);
 PID reflowOvenPID(&inputTemp, &output, &setpoint, kp, ki, kd, DIRECT);
+EasyButton button(BUTTON_PIN);
 
 
 // Called once in setup, sets global display attributes.
 // Called once in setup, sets global display attributes.
-void u8g2_prepare(void) {
-  u8g2.setFont(u8g2_font_8x13_tf);
+inline void u8g2_prepare(void) {
+  u8g2.setFont(u8g2_font_8x13_tr);
   u8g2.setFontRefHeightExtendedText();
   u8g2.setFontRefHeightExtendedText();
   u8g2.setDrawColor(1);
   u8g2.setDrawColor(1);
   u8g2.setFontPosTop();
   u8g2.setFontPosTop();
@@ -137,66 +131,35 @@ void readTemp(void) {
   }
   }
 }
 }
 
 
-void handleSwitch(void) {
-  // If switch 1 is pressed
-  if (switchStatus == SWITCH_1)
-  {
-    // If currently reflow process is on going
-    if (reflowStatus == REFLOW_STATUS_ON)
-    {
-      // Button press is for cancelling
-      // Turn off reflow process
-      reflowStatus = REFLOW_STATUS_OFF;
-      // Reinitialize state machine
-      reflowState = REFLOW_STATE_IDLE;
-    }
-  } 
-
-  // Simple switch debounce state machine (for switch #1 (both analog & digital
-  // switch supported))
-  switch (debounceState)
+void buttonPressed(void) {
+  // If currently reflow process is on going
+  if (reflowStatus == REFLOW_STATUS_ON)
   {
   {
-  case DEBOUNCE_STATE_IDLE:
-    // No valid switch press
-    switchStatus = SWITCH_NONE;
-    // If switch #1 is pressed
-      if (digitalRead(BUTTON_PIN) == LOW)
-      {
-        // Intialize debounce counter
-        lastDebounceTime = millis();
-        // Proceed to check validity of button press
-        debounceState = DEBOUNCE_STATE_CHECK;
-      }  
-    break;
-
-  case DEBOUNCE_STATE_CHECK:
-    // If switch #1 is still pressed
-    if (digitalRead(BUTTON_PIN) == LOW)
-      {
-        // If minimum debounce period is completed
-        if ((millis() - lastDebounceTime) > DEBOUNCE_PERIOD_MIN)
-        {
-          // Proceed to wait for button release
-          debounceState = DEBOUNCE_STATE_RELEASE;
-        }
-      }
-      // False trigger
-      else
-      {
-        // Reinitialize button debounce state machine
-        debounceState = DEBOUNCE_STATE_IDLE; 
-      }
-    break;
+    // Button press is for cancelling
+    // Turn off reflow process
+    reflowStatus = REFLOW_STATUS_OFF;
+    // Reinitialize state machine
+    reflowState = REFLOW_STATE_IDLE;
+    activeReflowProfile = 0;
+  } else {
+    startReflow = true;
+  }
+}
 
 
-  case DEBOUNCE_STATE_RELEASE:
-    if (digitalRead(BUTTON_PIN) == HIGH)
-    {
-      // Valid switch 1 press
-      switchStatus = SWITCH_1;
-      // Reinitialize button debounce state machine
-      debounceState = DEBOUNCE_STATE_IDLE; 
+void buttonHeld(void) {
+  // If currently reflow process is on going
+  if (reflowStatus == REFLOW_STATUS_ON)
+  {// Button press is for cancelling
+    // Turn off reflow process
+    reflowStatus = REFLOW_STATUS_OFF;
+    // Reinitialize state machine
+    reflowState = REFLOW_STATE_IDLE;
+    activeReflowProfile = 0;
+  } else {
+    activeReflowProfile++;
+    if (activeReflowProfile >= NUM_REFLOW_PROFILES) {
+      activeReflowProfile = 0;
     }
     }
-    break;
   }
   }
 }
 }
 
 
@@ -211,16 +174,16 @@ void handleReflowState(void) {
       reflowState = REFLOW_STATE_TOO_HOT;
       reflowState = REFLOW_STATE_TOO_HOT;
     }
     }
     // If switch is pressed, start reflow process
     // If switch is pressed, start reflow process
-    else if (switchStatus == SWITCH_1)
+    else if (startReflow)
     {
     {
       // Turn off done LED if it was on from a previous cycle.
       // Turn off done LED if it was on from a previous cycle.
       digitalWrite(DONE_LED_PIN, LOW);
       digitalWrite(DONE_LED_PIN, LOW);
       // Reset switch state to prevent triggering later code erroneously.
       // Reset switch state to prevent triggering later code erroneously.
-      switchStatus = SWITCH_NONE;
+      startReflow = false;
       // Initialize PID control window starting time
       // Initialize PID control window starting time
       windowStartTime = millis();
       windowStartTime = millis();
       // Ramp up to minimum soaking temperature
       // Ramp up to minimum soaking temperature
-      setpoint = TEMPERATURE_SOAK;
+      setpoint = profiles[activeReflowProfile].soakTemp;
       // Tell the PID to range between 0 and the full window size
       // Tell the PID to range between 0 and the full window size
       reflowOvenPID.SetOutputLimits(0, windowSize);
       reflowOvenPID.SetOutputLimits(0, windowSize);
       reflowOvenPID.SetSampleTime(PID_SAMPLE_TIME);
       reflowOvenPID.SetSampleTime(PID_SAMPLE_TIME);
@@ -234,11 +197,11 @@ void handleReflowState(void) {
   case REFLOW_STATE_PREHEAT:
   case REFLOW_STATE_PREHEAT:
     reflowStatus = REFLOW_STATUS_ON;
     reflowStatus = REFLOW_STATUS_ON;
     // If minimum soak temperature is achieved.
     // If minimum soak temperature is achieved.
-    if (inputTemp >= TEMPERATURE_SOAK)
+    if (inputTemp >= profiles[activeReflowProfile].soakTemp)
     {
     {
       soakStartTime = millis();
       soakStartTime = millis();
       // Chop soaking period into smaller sub-period
       // Chop soaking period into smaller sub-period
-      timerSoak = soakStartTime + SOAK_PERIOD_MS;
+      timerSoak = soakStartTime + profiles[activeReflowProfile].soakPeriodMS;
       // Set less agressive PID parameters for soaking ramp
       // Set less agressive PID parameters for soaking ramp
       reflowOvenPID.SetTunings(PID_KP_SOAK, PID_KI_SOAK, PID_KD_SOAK);
       reflowOvenPID.SetTunings(PID_KP_SOAK, PID_KI_SOAK, PID_KD_SOAK);
       // Proceed to soaking state
       // Proceed to soaking state
@@ -250,7 +213,7 @@ void handleReflowState(void) {
     // If micro soak temperature is achieved       
     // If micro soak temperature is achieved       
     if (millis() > timerSoak)
     if (millis() > timerSoak)
     {
     {
-      timerSoak = millis() + SOAK_PERIOD_MS;
+      timerSoak = millis() + profiles[activeReflowProfile].soakPeriodMS;
       reflowStatus = REFLOW_STATUS_OFF;
       reflowStatus = REFLOW_STATUS_OFF;
       reflowState = REFLOW_STATE_COOL; 
       reflowState = REFLOW_STATE_COOL; 
     }
     }
@@ -274,6 +237,7 @@ void handleReflowState(void) {
     {
     {
       // Reflow process ended
       // Reflow process ended
       reflowState = REFLOW_STATE_IDLE; 
       reflowState = REFLOW_STATE_IDLE; 
+      activeReflowProfile = 0;
     }
     }
     break;
     break;
   
   
@@ -340,13 +304,8 @@ void drawScreen(void) {
   u8g2.drawStr( 100, rowOffset, "C");
   u8g2.drawStr( 100, rowOffset, "C");
   rowOffset += rowSize;
   rowOffset += rowSize;
 
 
-  // Thermocouple Status row
-  u8g2.drawStr( 0, rowOffset, "tc_err: ");
-  if (TCError) {
-    u8g2.drawStr( 60, rowOffset, "true");
-  } else {
-    u8g2.drawStr( 60, rowOffset, "false");
-  }
+  // Current Profile
+  u8g2.drawStr( 0, rowOffset, profiles[activeReflowProfile].profileName);
   rowOffset += rowSize;
   rowOffset += rowSize;
   
   
   // General status row
   // General status row
@@ -372,7 +331,10 @@ void setup(void) {
   pinMode(SSR_PIN, OUTPUT);
   pinMode(SSR_PIN, OUTPUT);
 
 
   pinMode(BUTTON_PIN, INPUT_PULLUP);
   pinMode(BUTTON_PIN, INPUT_PULLUP);
-  
+  button.begin();
+  button.onPressed(buttonPressed);
+  button.onPressedFor(1000, buttonHeld);
+
   digitalWrite(DONE_LED_PIN, LOW);
   digitalWrite(DONE_LED_PIN, LOW);
   pinMode(DONE_LED_PIN, OUTPUT);
   pinMode(DONE_LED_PIN, OUTPUT);
 
 
@@ -393,7 +355,7 @@ void loop(void) {
 
 
   handleReflowState();
   handleReflowState();
 
 
-  handleSwitch();
+  button.read();
 
 
   handleSSR();
   handleSSR();