Toby Chui пре 9 месеци
родитељ
комит
68687eae24

+ 2 - 0
firmware/README.txt

@@ -0,0 +1,2 @@
+For PCB versions before 6 (v1 - v5), use the reflow.ino firmware.
+For PCB versions 6 or above, use the reflow-v6 firmware.

+ 18 - 0
firmware/reflow-v6/desolder.ino

@@ -0,0 +1,18 @@
+/* desolder.ino handles desoldering (aka just a basic heated plate) procedures */
+
+void handleDesolderProcedures() {
+  bool tempReached = updateHeaterPowerState();  //This take around 100ms
+  if (reflowStages == 10 && tempReached) {
+    //Temperature reached. Stop red blinking and light up red light
+    fastblinkRed = false;
+    digitalWrite(LED_REFLOW, HIGH);
+    desolderCountdown = MAX_CONTINUE_OPR_TIME;  //Start counting down max operation time
+    reflowStages = 11; //Move to consistent heating mode
+  }
+
+  if (desolderCountdown == 0) {
+    enterStandbyMode();
+    desolderCountdown = 0;  //Prevent underflow
+  }
+  desolderCountdown--;
+}

+ 28 - 88
firmware/reflow-v6/reflow-v6.ino

@@ -2,10 +2,10 @@
    60W PD Powered Automatic Reflow Hoteplate
    Author: tobychui
 
-   Firmware version for v6 PCB
+   Firmware version for v6 or above PCB
    
    Notes:
-   - Temperature sensing is done using 1k 1% resistor and a 10k Thermistor
+   - Temperature sensing is done using 1k 1% resistor and a 100k Thermistor
      You might need to change the code if you are using other values
    - If you are using the type-C 6p version of the reflow PCB, and after
      pluggin in the type C cable no led lights up, try flip the type C
@@ -21,6 +21,7 @@
 */
 #include <Serial.h>
 
+/* Hardware Definations */
 #define TEMP_PIN 11     //P1.1
 #define HEATER_PIN 34   //P3.4
 #define LED_PREHEAT 15  //P1.5
@@ -28,11 +29,12 @@
 #define START_BTN 14    //P1.4
 #define STOP_BTN 17     //P1.7
 
+/* Software Definations */
 //Timing settings. Each cycle is approximately 100ms
-#define HOLDSTART_TIME 30  //START Button hold down time in cycles
-#define HOLDSTOP_TIME 10   //STOP Button hold down time in cycles
-#define SOAKING_TIME 600   //SOAKING temperature upkeep time in cycles
-
+#define HOLDSTART_TIME 30           //START Button hold down time in cycles
+#define HOLDSTOP_TIME 10            //STOP Button hold down time in cycles
+#define SOAKING_TIME 600            //SOAKING temperature upkeep time in cycles
+#define MAX_CONTINUE_OPR_TIME 3000  //MAX_CONTINUE_OPR automatic shutdown desolder heatbed if continue operate for ~5 minutes for safty reasons
 /*
    Temperature Settings
 
@@ -55,17 +57,21 @@
 //Overheat cutoff temp
 #define CUTOFF_TEMP_ADC 53  //250 degree C
 
-//Func def
+/* Function Prototypes */
 bool updateHeaterPowerState();
 void updateKeyStates();
+void handleLEDBlinking();
+void handleReflowProcedures();
+void handleDesolderProcedures();
+void enterStandbyMode();
 int readTemp();
 
 
-//Runtimes
+/* Runtime Variables */
 bool reflowing = false;       //Reflow has started
 bool reflowComplete = false;  //Indicate if the stopping is done because of reflow complete
 bool startPressed = false;    //Start button is pressed down
-bool stopPressed = false;  //Stop button is pressed down
+bool stopPressed = false;     //Stop button is pressed down
 
 /*
   Reflow Stages define what is the next state the hotplate should reach
@@ -74,12 +80,16 @@ bool stopPressed = false;  //Stop button is pressed down
   2: Preheat Holding / Soaking
   3: Reflowing
   4: Cooling down
+
+  10: Preheating to reflow temp for desoldering
+  11: Desolder Mode (Keep at REFLOW_TEMP_ADC)
 */
 int reflowStages = 0;
 int startCountdown = HOLDSTART_TIME;  //Hold for HOLDSTART_TIME to start to prevent accidental touches
 int stopcountdown = HOLDSTOP_TIME;    //Hold for HOLDSTOP_TIME to stop reflowing
 int cycleCounter = 0;                 //Record cycle time up to 10 seconds
 int soakingCountdown = SOAKING_TIME;
+int desolderCountdown = MAX_CONTINUE_OPR_TIME; //Prevent overheat
 
 //Blink state controls
 bool blinkState = false;  //If blinking this will be switching between true and false
@@ -122,97 +132,27 @@ void loop() {
 
   /* Main reflowing logics */
   //Add delay to the end of each conditions so each loop cycle is approximate 100ms
-  if (reflowing) {
-    /* Currently is in reflow stage */
-    bool tempReached = updateHeaterPowerState();  //This action takes 100ms
-    if (tempReached) {
-      //This stage temperature reached. Move to next stage
-      if (reflowStages == 1) {
-        //Preheat stage completed. Enter soaking stage
-        USBSerial_println("Preheat temperature reached. Soaking started");
-        targetTempADC = PREHEAT_TEMP_ADC;  //Set temperature to soaking end temp
-        reflowStages = 2;                  //Set reflow stage to soaking
-        soakingCountdown = SOAKING_TIME;
-        fastblinkRed = true;
-      } else if (reflowStages == 3) {
-        //Reflowing target temperature reached. Start cooldown and shut down heater
-        USBSerial_println("Reflow completed. Cooling down");
-        reflowStages = 4;
-        blinkYellow = false;
-        blinkRed = true;
-        targetTempADC = COOLDOWN_TEMP_ADC;
-        targetPwrPWM = 0;
-
-        //Reflow ended. Wait until stop being press to exit this state
-      }
-    }
-
-    if (reflowStages == 2) {
-      //Wait for the soaking to complete and enter reflow stage
-      soakingCountdown--;
-      if (soakingCountdown <= 0) {
-        //Soaking completed. Enter reflow stage
-        USBSerial_println("Soaking time ended. Reflow started");
-
-        //Set Reflow LED to high
-        fastblinkRed = false;
-        digitalWrite(LED_REFLOW, HIGH);
-
-        //Set to reflow temperature
-        targetTempADC = REFLOW_TEMP_ADC;  //Set the target temp to reflow
-        targetPwrPWM = REFLOW_PWR_PWM;    //Set power rating to reflow
-
-        //Update the reflow stage to 3
-        reflowStages = 3;
-      } else if (soakingCountdown % 100 == 0) {
-        USBSerial_print("Soaking cycles left: ");
-        USBSerial_println(soakingCountdown);
-      }
-    }
-    
-    delay(1); 
+  if (reflowing && reflowStages < 10) {
+    //Automatic Reflow
+    handleReflowProcedures();
+  } else if (reflowing && reflowStages >= 10) {
+    //Desolder hotplate
+    handleDesolderProcedures();
   } else {
     /* Standby Mode */
     digitalWrite(HEATER_PIN, LOW);
     blinkYellow = true;
-    delay(100); //adjust this if needed to make sure reflow cycles use the same time as standby cycles
+    delay(100);  //adjust this if needed to make sure reflow cycles use the same time as standby cycles
   }
 
   /* Blink Signal Handlers */
-  //FastBlink handler, execute every 500ms
-  if (cycleCounter % 5 == 0 && fastblinkRed) {
-    digitalWrite(LED_PREHEAT, LOW);
-    if (fastBlinkState) {
-      digitalWrite(LED_REFLOW, HIGH);
-    } else {
-      digitalWrite(LED_REFLOW, LOW);
-    }
-    fastBlinkState = !fastBlinkState;
-  }
-
-  //Blink handler, execute every 2 seconds
-  if (cycleCounter % 20 == 0) {
-    if (blinkYellow) {
-      if (blinkState) {
-        digitalWrite(LED_PREHEAT, HIGH);
-      } else {
-        digitalWrite(LED_PREHEAT, LOW);
-      }
-    } else if (blinkRed) {
-      if (blinkState) {
-        digitalWrite(LED_REFLOW, HIGH);
-      } else {
-        digitalWrite(LED_REFLOW, LOW);
-      }
-    }
-    blinkState = !blinkState;
-  }
+  handleLEDBlinking();
 
   /* 
     Cycle Counter 
     Counter are limited to 600 to prevent overflow.
   */
-  
+
   cycleCounter++;
   if (cycleCounter > 600) {
     cycleCounter = 0;

+ 52 - 0
firmware/reflow-v6/reflow.ino

@@ -0,0 +1,52 @@
+/* reflow.ino handles reflow procedures */
+
+void handleReflowProcedures() {
+  /* Currently is in reflow stage */
+  bool tempReached = updateHeaterPowerState();  //This action takes 100ms
+  if (tempReached) {
+    //This stage temperature reached. Move to next stage
+    if (reflowStages == 1) {
+      //Preheat stage completed. Enter soaking stage
+      USBSerial_println("Preheat temperature reached. Soaking started");
+      targetTempADC = PREHEAT_TEMP_ADC;  //Set temperature to soaking end temp
+      reflowStages = 2;                  //Set reflow stage to soaking
+      soakingCountdown = SOAKING_TIME;
+      fastblinkRed = true;
+    } else if (reflowStages == 3) {
+      //Reflowing target temperature reached. Start cooldown and shut down heater
+      USBSerial_println("Reflow completed. Cooling down");
+      reflowStages = 4;
+      blinkYellow = false;
+      blinkRed = true;
+      targetTempADC = COOLDOWN_TEMP_ADC;
+      targetPwrPWM = 0;
+
+      //Reflow ended. Wait until stop being press to exit this state
+    }
+  }
+
+  if (reflowStages == 2) {
+    //Wait for the soaking to complete and enter reflow stage
+    soakingCountdown--;
+    if (soakingCountdown <= 0) {
+      //Soaking completed. Enter reflow stage
+      USBSerial_println("Soaking time ended. Reflow started");
+
+      //Set Reflow LED to high
+      fastblinkRed = false;
+      digitalWrite(LED_REFLOW, HIGH);
+
+      //Set to reflow temperature
+      targetTempADC = REFLOW_TEMP_ADC;  //Set the target temp to reflow
+      targetPwrPWM = REFLOW_PWR_PWM;    //Set power rating to reflow
+
+      //Update the reflow stage to 3
+      reflowStages = 3;
+    } else if (soakingCountdown % 100 == 0) {
+      USBSerial_print("Soaking cycles left: ");
+      USBSerial_println(soakingCountdown);
+    }
+  }
+
+  delay(1);
+}

+ 32 - 0
firmware/reflow-v6/signals.ino

@@ -17,3 +17,35 @@ void updateButtonPressState(){
   x = digitalRead(STOP_BTN);
   stopPressed = (x == LOW);
 }
+
+//Handle LED states in this cycle
+void handleLEDBlinking(){
+  //FastBlink handler, execute every 500ms
+  if (cycleCounter % 5 == 0 && fastblinkRed) {
+    digitalWrite(LED_PREHEAT, LOW);
+    if (fastBlinkState) {
+      digitalWrite(LED_REFLOW, HIGH);
+    } else {
+      digitalWrite(LED_REFLOW, LOW);
+    }
+    fastBlinkState = !fastBlinkState;
+  }
+
+  //Blink handler, execute every 2 seconds
+  if (cycleCounter % 20 == 0) {
+    if (blinkYellow) {
+      if (blinkState) {
+        digitalWrite(LED_PREHEAT, HIGH);
+      } else {
+        digitalWrite(LED_PREHEAT, LOW);
+      }
+    } else if (blinkRed) {
+      if (blinkState) {
+        digitalWrite(LED_REFLOW, HIGH);
+      } else {
+        digitalWrite(LED_REFLOW, LOW);
+      }
+    }
+    blinkState = !blinkState;
+  }
+}

+ 62 - 40
firmware/reflow-v6/utils.ino

@@ -14,74 +14,110 @@
  * Each reading takes around 100ms
  */
 int readTemp() {
-  int numReadings = 10; // Number of readings to average
+  int numReadings = 10;  // Number of readings to average
   int totalSensorValue = 0;
-  
+
   for (int i = 0; i < numReadings; ++i) {
     totalSensorValue += analogRead(TEMP_PIN);
-    delay(10); // Optional: add a small delay between readings if needed
+    delay(10);  // Optional: add a small delay between readings if needed
   }
 
   // Calculate the average sensor value
   int averageSensorValue = totalSensorValue / numReadings;
-  
+
   return averageSensorValue;
 }
 
+//enterStandbyMode move the hotplate state to standby and cutoff power to hotplate
+void enterStandbyMode() {
+  reflowing = false;
+  USBSerial_println("Reflow Stopped");
+  //Set target temperature to room temp and shut down heater
+  targetTempADC = COOLDOWN_TEMP_ADC;
+  targetPwrPWM = 0;
+
+  //Set yellow LED to slow blinkRed
+  digitalWrite(LED_REFLOW, LOW);
+  digitalWrite(LED_PREHEAT, LOW);
+  blinkYellow = true;
+  blinkRed = false;
+  fastblinkRed = false;
+
+  //Set reflow stage to standby
+  reflowStages = 0;
+}
+
 //Update heater power state base on temp reading
 //The hotter the plate, the smaller the ADC reading
 //Return true when the temperature is within target range
-bool updateHeaterPowerState(){
+bool updateHeaterPowerState() {
   int currentADC = readTemp();
-  if (currentADC <= CUTOFF_TEMP_ADC){
+  if (currentADC <= CUTOFF_TEMP_ADC) {
     digitalWrite(HEATER_PIN, LOW);
     USBSerial_println("!!! OVERHEAT !!!");
     digitalWrite(LED_PREHEAT, HIGH);
     digitalWrite(LED_REFLOW, HIGH);
     return false;
   }
-  if (currentADC > targetTempADC + offset){
+  if (currentADC > targetTempADC + offset) {
     //Temperature too low. Turn on the heater
     analogWrite(HEATER_PIN, targetPwrPWM);
     //USBSerial_print("+ ");
     //USBSerial_println(currentADC);
     return false;
-  }else if (currentADC < targetTempADC - offset){
+  } else if (currentADC < targetTempADC - offset) {
     //Temperature too high. Turn off the heater
     analogWrite(HEATER_PIN, 0);
     //USBSerial_print("- ");
     //USBSerial_println(currentADC);
     return false;
-  }else{
+  } else {
     //Within range. Keep the current state
     return true;
   }
 }
 
 //Update Key States handle touch button events listening and global state update
-void updateKeyStates(){
+void updateKeyStates() {
   //Read the current buttons state
   updateButtonPressState();
 
   //Start button, require hold down for 3 seconds to start
   if (startPressed) {
     startCountdown--;
-    if (startCountdown <= 0 && !reflowing){
-      /* START REFLOW PROCESS - PREHEAT */
-      USBSerial_println("!!! Reflow Started !!!");
-      reflowing = true;
-      startCountdown = 0; //Prevent it from going underflow
-      playStartingLEDBlinks(); //Play fast blink start warning
-      targetTempADC = PREHEAT_START_ADC; //Set the target temp to preheat starting temp
-      targetPwrPWM = PREHEAT_PWR_PWM; //Set power rating to preheat
-      reflowStages = 1; //Set the reflow stage to preheating
+    if (startCountdown <= 0 && !reflowing) {
+      if (stopPressed) {
+        //Holding two buttons together. Enter desolder mode
+        USBSerial_println("!!! Desolder Mode Started !!!");
+        reflowing = true;
+        startCountdown = 0;               //Prevent underflow counter
+        playStartingLEDBlinks();          //Play fast blink start warning
+        targetTempADC = REFLOW_TEMP_ADC;  //Set the target temp to reflow target temp
+        targetPwrPWM = REFLOW_PWR_PWM;    //Set power rating to 100%
+        reflowStages = 10;                //Set the reflow stage to desolder
+
+        //Set red LED to blink fast
+        blinkYellow = false;
+        blinkRed = false;
+        fastblinkRed = true;
+      } else {
+        //Holding start button only. Enter automatic reflow mode
+        /* START REFLOW PROCESS - PREHEAT */
+        USBSerial_println("!!! Reflow Started !!!");
+        reflowing = true;
+        startCountdown = 0;                 //Prevent it from going underflow
+        playStartingLEDBlinks();            //Play fast blink start warning
+        targetTempADC = PREHEAT_START_ADC;  //Set the target temp to preheat starting temp
+        targetPwrPWM = PREHEAT_PWR_PWM;     //Set power rating to preheat
+        reflowStages = 1;                   //Set the reflow stage to preheating
 
-      //Set the blinking LED status to off
-      blinkYellow = false;
-      blinkRed = false;
-      fastblinkRed = false;
-      digitalWrite(LED_PREHEAT, HIGH); //Light up the preheat LED
-      
+        //Set the blinking LED status to off
+        blinkYellow = false;
+        blinkRed = false;
+        fastblinkRed = false;
+        digitalWrite(LED_PREHEAT, HIGH);  //Light up the preheat LED
+      }
+      return;
     }
   } else {
     //Press released
@@ -90,20 +126,6 @@ void updateKeyStates(){
 
   //Stop button, stop immediately
   if (stopPressed) {
-    reflowing= false;
-    USBSerial_println("Reflow Stopped");
-    //Set target temperature to room temp and shut down heater
-    targetTempADC = COOLDOWN_TEMP_ADC;
-    targetPwrPWM = 0;
-
-    //Set yellow LED to slow blinkRed
-    digitalWrite(LED_REFLOW, LOW);
-    digitalWrite(LED_PREHEAT, LOW);
-    blinkYellow = true;
-    blinkRed = false;
-    fastblinkRed = false;
-
-    //Set reflow stage to standby
-    reflowStages = 0;
+    enterStandbyMode();
   }
 }

BIN
model/lockfile.lck