はじめに
暖かい飲み物は、机に置いておいてもすぐに冷めてしまう。
机上でペットボトル等を保温しておける製品はAmazonで何種類か見つけたが、怪しい中華製ばかり・・・
仕組みは難しくないだろうし、自作してみようと考えた。
目次
作りたかったもの
机の上でペットボトルを暖めておけるホルダー
ハード設計
・全体構成
下図のような構成で作ることにした。
M5Stickに付けた温度センサでペットボトルの温度を読み取り、その値をもとにヒーターの電源をON/OFFして温度を調整する。この調整はPWMのDutyをPID制御して行う。
可変抵抗を回すと設定温度を変えられる。
今回引き出しの中にあったヒーターが200Ωのものであったため、それに合わせてヒーター電源は45Vとした。大体10Wくらいあればいいだろうという見積もり。
・温度センサ
たまたま手元にあったM5Stick用のMLX90614ハットを使用した。
非接触であるため、温度制御対象(ペットボトル)を密着させる必要はなく、使い勝手がいい。
https://www.switch-science.com/products/6067
[M5Stickにハットを付けた写真を挿入]
プログラム作成
下記のプログラムで動かす。
ただし、PIDのゲイン(KP、KI、KD)は最終形状で温度推移を見ながら適宜調整する。
また、最後のdelayは実働の様子を見て調整し、大体1秒ごと計測するようにしたい。
#include <M5StickCPlus2.h>
#include <Wire.h>
#define PWM_PIN 32
#define PWMCH 0
#define ADC_PIN 33
//Define maximum target temperature
#define TEMP_OBJ_MAX 80
//Define gain values for PID control
#define KP 1
#define KI 1
#define KD 1
float dp, di, dd;
float dp_pre;
float time_width = 1;
int loop_count;
uint16_t adc_dummy;
String display_text_set;
String display_text_now;
void setup() {
M5.begin();
Wire.begin(0, 26);
Serial.begin(115200);
pinMode(PWM_PIN, OUTPUT); //Prepare PWM
ledcSetup(PWMCH, 100, 8);
ledcAttachPin(PWM_PIN, PWMCH);
pinMode(ADC_PIN, ANALOG); //Prepare ADC
//Initialize valiables
loop_count = 0;
dp = 0;
di = 0;
dd = 0;
dp_pre = 0;
M5.Lcd.setRotation(1);
M5.Lcd.setTextColor(WHITE);
M5.Lcd.setTextSize(5);
// M5.Lcd.clear(BLACK);
M5.Lcd.setCursor(0, 40);
}
//PID Control
int pid_calc(int temp_set, float temp_now){
float duty = 0;
dp = (float)temp_set - temp_now;
dd = (dp - dp_pre) / time_width;
di = di + (dp + dp_pre) * time_width / 2;
duty = KP * dp + KI * di + KD * dd;
//Serial.printf("dp: %.2f, dd: %.2f, di: %.2f, duty: %.0f, ", dp, dd, di, duty);
dp_pre = dp;
return (int)duty;
}
void loop() {
float temp_now = 0;
int temp_now_int = 0;
int temp_set = 0;
int adc_val = 0;
int pwm_duty = 0;
Serial.printf("%d, ", loop_count); //DEBUG
//Measure target temperature
for(int i=0; i<4; i++)
{
Wire.beginTransmission(0x5A);
Wire.write(0x07);
Wire.endTransmission(false);
Wire.requestFrom(0x5A, 2);
adc_dummy = Wire.read();
adc_dummy |= Wire.read() << 8;
temp_now += adc_dummy * 0.02 - 273.15;
delay(100);
}
temp_now /= 4;
//Read set temperature
for(int i=0; i<4; i++)
{
adc_val += analogRead(ADC_PIN);
delay(100);
}
adc_val /= 4;
temp_set = (adc_val * TEMP_OBJ_MAX) / 4096;
//Calculate PWM duty
pwm_duty = pid_calc(temp_set, temp_now);
if(pwm_duty > 255)
pwm_duty = 255;
else if(pwm_duty < 0)
pwm_duty = 0;
ledcWrite(PWMCH, pwm_duty);
//Initialize LCD and display temperature
M5.Lcd.fillScreen(BLACK);
display_text_set = "SET: " + (String)temp_set;
M5.Lcd.setCursor(5, 5);
M5.Lcd.print(display_text_set);
temp_now_int = (int)temp_now;
display_text_now = "NOW: " + (String)temp_now_int;
if(temp_now_int < temp_set)
M5.Lcd.setTextColor(RED);
else if(temp_now_int > temp_set)
M5.Lcd.setTextColor(BLUE);
M5.Lcd.setCursor(5, 75);
M5.Lcd.print(display_text_now);
M5.Lcd.setTextColor(WHITE);
Serial.printf("%.2f\n", temp_now); //DEBUG
loop_count++;
//Wait
delay(100);
M5.update();
}
完成
適当にケースを作って完成。
ヒーターはとりあえず机に落ちていたものを使ったため、寸法は足りていない。
動作確認
早速、冷ましておいた「あたたか~い」飲み物を暖めてみる。
ホルダーに入れてヒーターとM5Stickの電源を入れ・・・
溶けました。
PETGの軟化温度は80℃くらいあるけれども、それでは足りないらしい。
肝心のペットボトルの温度は室温20℃に対して22℃までしか上がらず。
課題点
- 容器の耐熱性
保温だけでなく加熱も行う場合、容器が溶けない素材にする必要がある。
かといって金属製にするとコストがかかるし、良い案は今のところ思い浮かんでいない。
- ヒーターの電源電圧
そもそも45Vを出せる外部電源が手元にある人は少ない。
もっと実用的にするための策として思いつくのは下記3つ。
(1) 昇圧ICの使用
例えば「日清紡マイクロデバイス NJW4132 シリーズ」。
https://www.nisshinbo-microdevices.co.jp/ja/products/dc-dc-switching-regulator/spec/?product=njw4132
(2) ヒーターの置き換え
低抵抗のヒーターを使用すれば低い電圧でも消費電力を稼げる。
(3) 100Vの商用電源から供給
(2)が一番簡単かもしれない。
余裕があれば改修していきたい。