|
@@ -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;
|