浏览代码

Added v6 firmware

Toby Chui 9 月之前
父节点
当前提交
c60a0d45aa

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

@@ -0,0 +1,220 @@
+/*
+   60W PD Powered Automatic Reflow Hoteplate
+   Author: tobychui
+
+   Firmware version for v6 PCB
+   
+   Notes:
+   - Temperature sensing is done using 1k 1% resistor and a 10k 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>
+
+#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
+
+//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
+
+/*
+   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 143  //150 degree C
+#define PREHEAT_TEMP_ADC 122   //160 degree C
+#define PREHEAT_PWR_PWM 155    //60% power output
+//Reflow temp & power
+#define REFLOW_TEMP_ADC 58  //220 degree C
+#define REFLOW_PWR_PWM 255  //100% power output
+//Overheat cutoff temp
+#define CUTOFF_TEMP_ADC 53  //250 degree C
+
+//Func def
+bool updateHeaterPowerState();
+void updateKeyStates();
+int readTemp();
+
+
+//Runtimes
+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
+*/
+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;
+
+//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);
+
+  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) {
+    /* 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); 
+  } 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 */
+  //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;
+  }
+
+  /* 
+    Cycle Counter 
+    Counter are limited to 600 to prevent overflow.
+  */
+  
+  cycleCounter++;
+  if (cycleCounter > 600) {
+    cycleCounter = 0;
+  }
+}

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

@@ -0,0 +1,19 @@
+//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);
+}

+ 109 - 0
firmware/reflow-v6/utils.ino

@@ -0,0 +1,109 @@
+//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;
+}
+
+//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){
+      /* 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
+      
+    }
+  } else {
+    //Press released
+    startCountdown = HOLDSTART_TIME;
+  }
+
+  //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;
+  }
+}

+ 1 - 1
firmware/reflow/reflow.ino

@@ -47,7 +47,7 @@
 #define REFLOW_TEMP_ADC 58  //220 degree C
 #define REFLOW_PWR_PWM 255  //100% power output
 //Overheat cutoff temp
-#define CUTOFF_TEMP_ADC 53  //230 degree C
+#define CUTOFF_TEMP_ADC 53  //250 degree C
 
 //Func def
 bool updateHeaterPowerState();

二进制
model/OldVersions/base v2.0014.ipt


二进制
model/OldVersions/base v6.0017.ipt


二进制
model/base v2.ipt


二进制
model/base v2.stl


二进制
model/base v6.ipt


二进制
model/base v6.stl


二进制
model/lockfile.lck


二进制
package/package-zh.png


二进制
package/package-zh.psd


二进制
package/package.png


二进制
package/package.psd


二进制
package/screws-pack.png


二进制
package/screws-pack.psd


+ 0 - 0
pcb/BOM v4.1 modified.csv → pcb/v4.1/BOM v4.1 modified.csv


+ 0 - 0
pcb/BOM_PCB_Reflow Hotplate v4_2023-10-31.csv → pcb/v4.1/BOM_PCB_Reflow Hotplate v4_2023-10-31.csv


+ 0 - 0
pcb/Gerber_PCB_Reflow Hotplate v4.1.zip → pcb/v4.1/Gerber_PCB_Reflow Hotplate v4.1.zip


+ 0 - 0
pcb/PickAndPlace_PCB_Reflow Hotplate v4_2023-10-31.csv → pcb/v4.1/PickAndPlace_PCB_Reflow Hotplate v4_2023-10-31.csv


二进制
pcb/v6/Gerber_Reflow-Hotplate_PCB_Reflow-Hotplate-v6_2024-06-08.zip


文件差异内容过多而无法显示
+ 34 - 0
pcb/v6/PCB_PCB_Reflow-Hotplate-v6_2024-06-08.json


部分文件因为文件数量过多而无法显示