表面実装リフロー装置の自作

前々からずっと作りたかったお家でできる簡単リフロー装置。やっとできました(ずっとサボっていました..)

リフロー装置もいくつかやり方がありますが、これはホットプレートを使っています。他にはオーブントースタやアイロンもあります。

本当はアイロンバージョンがあまり誰もやっていなくてやりたかったのですが、ホットプレートを先に購入してしまったのでホットプレートでやることにしました。

参考にしたのは、こちらのサイトです。( アイロンでやっています!)

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 &lt; 100) {
temp_poti = map(analogRead(poti), 1023, 0, temp_preheat, temp_reflow);
if (temp_poti &gt; temp_poti_old + 1 || temp_poti &lt; 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() &gt; t + 200 || millis() &lt; 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 &gt; 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 &gt;= 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 &lt;= 0) {
state_now = 0;
}
}
else {
digitalWrite(solidstate, HIGH);
time_count = 0;
}

delay(30);
}

&nbsp;
void regulate_temp(int temp, int should) {
if (should &lt;= temp - offset) {
digitalWrite(solidstate, HIGH);
}
else if (should &gt; 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

コメントはまだありません »

コメントはまだありません。

この投稿へのコメントの RSS フィード。 TrackBack URL

コメントする