前々からずっと作りたかったお家でできる簡単リフロー装置。やっとできました(ずっとサボっていました..)
リフロー装置もいくつかやり方がありますが、これはホットプレートを使っています。他にはオーブントースタやアイロンもあります。
本当はアイロンバージョンがあまり誰もやっていなくてやりたかったのですが、ホットプレートを先に購入してしまったのでホットプレートでやることにしました。
参考にしたのは、こちらのサイトです。( アイロンでやっています!)
Wemos D1 miniがなかったのですが、 esp8266を使っているだけなので、秋月のesp-wroom-02開発ボードを使用しました。
熱電対温度計測用のmax6675は、max31855に変更しています。
あとは、ほぼほぼ同じです。ソリットステートリレーはこれを使っているのですが、ON/OFF制御が3Vだとうまくいかなった(調べたら4V以上必要らしい)ので、2sc1815で5Vにレベル変換する回路を追加しています。
使い方は、シンプルで、ボリュームでリフロー時の最高温度を調整(210~250C)して、あとは、タクトスイッチを押すとoff => preheatの150Cになります。その後もう一度ボタンを押すとreflow温度まで到達します。
あとは、勝手にcoolingになって、終了です。以下のようなイメージです。ただ、実際は以下のように時間管理をすべきですが、厳密には行っていないので、ざっくりです。
回路図 (字が汚い。。。)
ソースコード
*以下のライブラリインストールしてください。
-Adafrute GFX
-Adafrute SSD1306
-Adafrute MAX31855
以下ソース
#include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h>//library ver1.4 installed #include <Adafruit_SSD1306.h> //#include "max6675.h" #include "Adafruit_MAX31855.h" #include <ESP8266WiFi.h> #define COOLDOWN_TIME 60 //60 #define PREHEAT_TIME 60 #define REFLOW_TIME 60 #define OLED_RESET 0 // GPIO0 Adafruit_SSD1306 display(OLED_RESET); int thermoDO = 12; int thermoCS = 13; int thermoCLK = 14; //MAX6675 thermocouple(thermoCLK, thermoCS, thermoDO); Adafruit_MAX31855 thermocouple(thermoCLK, thermoCS, thermoDO); const int button = 2; const int solidstate = 15; const int poti = A0; const int temp_preheat = 150; const int temp_reflow = 240; int temp_now = 0; int temp_next = 0; int temp_poti = 0; int temp_poti_old = 0; String state[] = {"OFF", "PREHEAT", "REFLOW", "COOLING"}; int state_now = 0; int time_count = 0; int perc = 0; int offset = 0; void setup() { Serial.begin(115200); Serial.println("/t"); Serial.println("hotplate reflow Started"); Wire.begin(4, 5);//SDA=4, SCL=5 pinMode(button, INPUT); pinMode(solidstate, OUTPUT); digitalWrite(solidstate, HIGH); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.display(); } long t = millis(); long t_solder = millis(); void loop() { temp_now = thermocouple.readCelsius(); temp_poti = map(analogRead(poti), 1023, 0, temp_preheat, temp_reflow); if (temp_poti != temp_poti_old) { int v = 0; display.fillScreen(WHITE); display.setTextColor(BLACK); display.setTextSize(1); display.setCursor(X(1, 7), Y(1, 0.1)); display.println("PREHEAT"); display.setTextSize(2); display.setCursor(X(2, 3), Y(2, 0.5)); while (v < 100) { temp_poti = map(analogRead(poti), 1023, 0, temp_preheat, temp_reflow); if (temp_poti > temp_poti_old + 1 || temp_poti < temp_poti_old - 1) { display.fillScreen(WHITE); display.setTextSize(1); display.setCursor(X(1, 6), Y(1, 0.1)); display.println("REFLOW"); display.setTextSize(2); display.setCursor(X(2, 3), Y(2, 0.5)); display.println(String(temp_poti)); display.display(); temp_poti_old = temp_poti; v = 0; } v++; delay(20); } temp_poti_old = temp_poti; } if (millis() > t + 200 || millis() < t) { PrintScreen(state[state_now], temp_next, temp_now, time_count, perc); t = millis(); } if (digitalRead(button) == 0) { delay(100); int c = 0; while (digitalRead(button) == 0) { c++; if (c > 150) { digitalWrite(solidstate, LOW); state_now = 0; display.fillScreen(WHITE); display.setTextColor(BLACK); display.setTextSize(2); display.setCursor(X(2, 3), Y(2, 0.5)); display.println("OFF"); display.display(); while (digitalRead(button) == 0) delay(1); return; } delay(10); } t_solder = millis(); perc = 0, state_now++; if (state_now == 0) temp_next = 0; else if (state_now == 1) temp_next = temp_preheat; else if (state_now == 2) temp_next = temp_poti; else if (state_now == 3) temp_next = 0; else if (state_now == 4) { state_now = 0; temp_next = 0; } } if (state_now == 1) { //PREHEAT regulate_temp(temp_now, temp_next); perc = int((float(temp_now) / float(temp_next)) * 100.00); } else if (state_now == 2) { //REFLOW regulate_temp(temp_now, temp_next); perc = int((float(temp_now) / float(temp_next)) * 100.00); if (perc >= 100) { state_now = 3; t_solder = millis(); perc = 0; temp_next = 0; } } else if (state_now == 3) { //COOLING digitalWrite(solidstate, HIGH); time_count = int((t_solder + COOLDOWN_TIME * 1000 - millis()) / 1000); if (time_count <= 0) { state_now = 0; } } else { digitalWrite(solidstate, HIGH); time_count = 0; } delay(30); } void regulate_temp(int temp, int should) { if (should <= temp - offset) { digitalWrite(solidstate, HIGH); } else if (should > temp + offset) { digitalWrite(solidstate, LOW); } } void PrintScreen(String state, int soll_temp, int ist_temp, int tim, int percentage) { display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(1); display.setCursor(0, 0); display.println(state); display.setCursor(80, 0); String str = String(soll_temp) + " deg"; display.println(str); if (tim != 0) { display.setCursor(0, 20); str = String(tim) + " sec"; display.println(str); } if (percentage != 0) { display.setCursor(50, 20); str = String(percentage) + " %"; display.println(str); } display.setTextSize(1); display.setCursor(10, 10); str = String(ist_temp) + " deg"; display.println(str); display.display(); } int X(int textgroesse, int n) { //gibt die X koordinate aus, damit text mit n zeichen mittig ist return (0.5 * (display.width() - textgroesse * (6 * n - 1))); }//end int X int Y(int textgroesse, float f) { //gibt die Y koordinate aus, damit text mittig ist return (f * display.height() - (textgroesse * 4)); }//end int Y