Browse Source

Added ES firmware

Toby Chui 7 months ago
parent
commit
ed3ada3c6a

+ 4 - 1
firmware/reflow-v6/reflow-v6.ino

@@ -28,6 +28,7 @@
 #define LED_REFLOW 16   //P1.6
 #define START_BTN 14    //P1.4
 #define STOP_BTN 17     //P1.7
+#define FAN_PIN 33      //P3.3
 
 /* Software Definations */
 //Timing settings. Each cycle is approximately 100ms
@@ -89,7 +90,7 @@ int startCountdown = HOLDSTART_TIME;  //Hold for HOLDSTART_TIME to start to prev
 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
+int desolderCountdown = MAX_CONTINUE_OPR_TIME;  //Prevent overheat
 
 //Blink state controls
 bool blinkState = false;  //If blinking this will be switching between true and false
@@ -121,6 +122,8 @@ void setup() {
   //Set mosfet control pins to output and disable it
   pinMode(HEATER_PIN, OUTPUT);
   digitalWrite(HEATER_PIN, LOW);
+  pinMode(FAN_PIN, OUTPUT);
+  digitalWrite(FAN_PIN, LOW);
 
   USBSerial_println("Reflow Hotplate Ready!");
 }

+ 2 - 0
firmware/reflow_v6_ES/README.txt

@@ -0,0 +1,2 @@
+This is the Engineering Sample firmware for testing ES version of the hotplates
+Do not use in production

+ 18 - 0
firmware/reflow_v6_ES/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--;
+}

+ 52 - 0
firmware/reflow_v6_ES/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);
+}

+ 163 - 0
firmware/reflow_v6_ES/reflow_v6_ES.ino

@@ -0,0 +1,163 @@
+/*
+   60W PD Powered Automatic Reflow Hoteplate
+   Author: tobychui
+
+   Firmware version for v6 or above PCB
+   
+   Notes:
+   - 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
+     cable upside down
+
+   Button Mappings (Active Low, aka not pressing = HIGH)
+   Start Btn: P1.4
+   Stop Btn: P1.7
+
+   Download Settings
+   CH552
+   16Mhz (internal, 3.3V or 5V)
+*/
+#include <Serial.h>
+
+/* Hardware Definations */
+#define TEMP_PIN 11     //P1.1
+#define HEATER_PIN 34   //P3.4
+#define LED_PREHEAT 15  //P1.5
+#define LED_REFLOW 16   //P1.6
+#define START_BTN 14    //P1.4
+#define STOP_BTN 17     //P1.7
+#define FAN_PIN 33      //P3.3
+
+/* 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 MAX_CONTINUE_OPR_TIME 3000  //MAX_CONTINUE_OPR automatic shutdown desolder heatbed if continue operate for ~5 minutes for safty reasons
+/*
+   Temperature Settings
+
+   The ADC value can be calculated using the following line equation
+   t=-0.7x+250
+
+   where X is ADC reading and t is target temp in degree C
+
+   Note that different setup (e.g. ref resistor value / NTC resistor value) might have different equations
+   You can experiment with yours and get a few data point to plot your own line
+*/
+#define COOLDOWN_TEMP_ADC 255  //Room temperature
+//Preheat temp & power
+#define PREHEAT_START_ADC 149  //150 degree C
+#define PREHEAT_TEMP_ADC 126   //160 degree C
+#define PREHEAT_PWR_PWM 155    //60% power output
+//Reflow temp & power
+#define REFLOW_TEMP_ADC 62  //220 degree C
+#define REFLOW_PWR_PWM 255  //100% power output
+//Overheat cutoff temp
+#define CUTOFF_TEMP_ADC 57  //250 degree C
+
+/* Function Prototypes */
+bool updateHeaterPowerState();
+void updateKeyStates();
+void handleLEDBlinking();
+void handleReflowProcedures();
+void handleDesolderProcedures();
+void enterStandbyMode();
+int readTemp();
+
+
+/* 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
+
+/*
+  Reflow Stages define what is the next state the hotplate should reach
+  0: Standby
+  1: Preheating
+  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
+bool blinkYellow = true;  //Slow blink yellow if enabled (Standby). Do not enable both yellow and red at the same time
+bool blinkRed = false;    //Slow blink red if enable (End of Reflow). Do not enable both yellow and red at the same time
+bool fastBlinkState = false;
+bool fastblinkRed = false;
+
+
+//Real-time temperature control targets
+int targetTempADC = 255;  //Target ADC reading to reach, 255 = room temperature
+int targetPwrPWM = 0;     //Target PWM cycle for heater, 255 = full power, 0 = off
+int offset = 0;           //Allow +-offset for the ADC reading before reheating / cooling
+
+void setup() {
+  //Set button pins to input
+  pinMode(START_BTN, INPUT);
+  pinMode(STOP_BTN, INPUT);
+
+  //Set LED pins to output
+  pinMode(LED_PREHEAT, OUTPUT);
+  pinMode(LED_REFLOW, OUTPUT);
+  digitalWrite(LED_PREHEAT, LOW);
+  digitalWrite(LED_REFLOW, LOW);
+
+  //Set temp sense pin to input
+  pinMode(TEMP_PIN, INPUT);
+
+  //Set mosfet control pins to output and disable it
+  pinMode(HEATER_PIN, OUTPUT);
+  digitalWrite(HEATER_PIN, LOW);
+  pinMode(FAN_PIN, OUTPUT);
+  digitalWrite(FAN_PIN, LOW);
+
+  USBSerial_println("Reflow Hotplate Ready!");
+}
+
+
+void loop() {
+  /* State Check */
+  updateKeyStates();
+
+  /* Main reflowing logics */
+  //Add delay to the end of each conditions so each loop cycle is approximate 100ms
+  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
+  }
+
+  /* Blink Signal Handlers */
+  handleLEDBlinking();
+
+  /* 
+    Cycle Counter 
+    Counter are limited to 600 to prevent overflow.
+  */
+
+  cycleCounter++;
+  if (cycleCounter > 600) {
+    cycleCounter = 0;
+  }
+}

+ 51 - 0
firmware/reflow_v6_ES/signals.ino

@@ -0,0 +1,51 @@
+//When the reflow starts, preheat leds will fast blink 
+//to indicate auto reflow will start in 5 seconds
+void playStartingLEDBlinks(){
+  digitalWrite(LED_PREHEAT, LOW);
+  for(int i = 0; i < 10; i++){
+    digitalWrite(LED_PREHEAT, HIGH);
+    delay(200);
+    digitalWrite(LED_PREHEAT, LOW);
+    delay(200);
+  }
+}
+
+//Update the button press state to global variable
+void updateButtonPressState(){
+  int x = digitalRead(START_BTN);
+  startPressed = (x == LOW);
+  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;
+  }
+}

+ 131 - 0
firmware/reflow_v6_ES/utils.ino

@@ -0,0 +1,131 @@
+//Read Temp read the current temperature of the hotplate
+/*
+ * Read Current temperature from ADC
+ * The ADC is reading from a voltage divider
+ * 5V --- 1k Ohm --- (ADC) --- 100k NTC --- GND
+ * 
+ * ADC Reading / Temperature (degree C)
+ * 250 / 25 
+ * 225 / 100 
+ * 155 / 160 (Preheat Temp)
+ * 123 / 220 (Reflow Temp)
+ * 100 / 240 (Hard cutoff Temp)
+ * 
+ * Each reading takes around 100ms
+ */
+int readTemp() {
+  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
+  }
+
+  // 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() {
+  int currentADC = readTemp();
+  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) {
+    //Temperature too low. Turn on the heater
+    analogWrite(HEATER_PIN, targetPwrPWM);
+    //USBSerial_print("+ ");
+    //USBSerial_println(currentADC);
+    return false;
+  } else if (currentADC < targetTempADC - offset) {
+    //Temperature too high. Turn off the heater
+    analogWrite(HEATER_PIN, 0);
+    //USBSerial_print("- ");
+    //USBSerial_println(currentADC);
+    return false;
+  } else {
+    //Within range. Keep the current state
+    return true;
+  }
+}
+
+//Update Key States handle touch button events listening and global state update
+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) {
+      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
+      }
+      return;
+    }
+  } else {
+    //Press released
+    startCountdown = HOLDSTART_TIME;
+  }
+
+  //Stop button, stop immediately
+  if (stopPressed) {
+    enterStandbyMode();
+  }
+}

BIN
pcb/v8/Gerber_Reflow-Hotplate_PCB_Reflow-Hotplate-v8_2024-07-24.zip