スタンドアロンにするぞ(6)

今回はこの保温器をスタンドアロンにします。現在WebのHPで行っている操作を止めて、下記の様な簡単な作業で保温出来ようにします。

  • 電源を入れたらスタンバイ状態になる
  • 缶内の温度と湿度を表示
  • 保温温度を入力しボタンを押したらスタート
  • ボタンをもう一度押したらストップ

必要部品

前回と重なる部分が多いですが、主な部品を挙げると

  • ESP32(本体)
    • 今回は、ESP32 Development Board WiFi+bluetoothを使用しました。
    • USBケーブルを繋ぐだけでArduinoで開発出来ます。
    • 以前使用したログを ここ にまとめています。参照下さい。
  • AQM1248A(LCD表示器)
    • I2C接続のLCD表示器です。解像度 48×128ドット。
    • 以前使用したログを ここ にまとめています。参照下さい。
  • AM2320(温湿度測定素子)
    • 2C接続の温湿度測定素子です。缶内温湿度測定用。
    • 以前使用したログを ここ にまとめています。参照下さい。
  • ADT7410(温度測定素子)
    • インターフェイスは、I2C。ヒーター温度測定用。
    • 温度のみ測定出来るが測定範囲はAM2320より広い。( -55°C~+150°C)
    • 以前使用したログが ここ に有ります。参照下さい。
  • ソリッド・ステート・リレー(SSR)キット 25A(20A)タイプ
    • ヒーターのオンオフに使用
  • DIPロータリースイッチ 10ポジション 0~9 正論理
    • 今回新たに追加した部品。これを2個使って保温温度を指定します。
    • 秋月さんで売っているロータリースイッチです。
  • その他
    • ヒューズ
    • コンセント
    • 基板
    • 配線コード
    • ヘッダーピン
    • など

回路と配線

  • 保温器の側面に小さい棚を作り、そこに全てを乗せました
  • 回路図の水色四角部分(SSR、ヒューズ、USB ADアダプター等)を棚の下に、それ以外は上に配置しています
  • 缶内温湿度測定用にAM2320をヒーター温度測定用にADT7410を使用しています。
  • AQM1248には、缶内の温度、湿度、経過時間(分)が表示されます。
  • 操作は下記の要領、
    • ACプラグをコンセントに接続。
    • 棚の上のスイッチで電源ON。
      • これで動作しますが、念の為にリセットスイッチを追加しています。
    • AQM1248に温湿度が表示。
    • ローターリースイッチで保温温度を設定します。
    • Stat/Stopボタンを押すとパイロットLEDが点灯して保温開始。
    • 動作時、ヒーターがオンの時にヒーターLEDが点灯。
    • 表示は5秒に1回更新されます。
    • 画面の PT:XXXX は経過時間です。開始からの経過時間を分で表示します。
    • もう一度、Stat/Stopボタンを押すとパイロットLEDが消灯して保温終了。

プログラムの変更

WebのHP、RTC、SDカードへのデーターの保存を止めたので、プログラムは非常に簡単になりました。前回までのメインのプログラム、”Monitor_00.ino” を ”chamber_00.ino” と新しく書き直しています。

chamber_00.ino

#include "Arduino.h"
#include <Wire.h>

#include "AM2320.h"
#include "AQM1248A.h"
#include "ADT7410.h"

// External Interrupt
// Only use GPIO:0,2,4,12-15,25-27,32-39
// Start Stop Bottom
#define St_btn          GPIO_NUM_27

// Pilot Lamp 
#define Pilot_Lamp      12

// Power Control 
#define Power_ctl       13
#define Power_Led       14

// Temp Data
#define dat_L1          35
#define dat_L2          39
#define dat_L4          34
#define dat_L8          36
#define dat_H1          26
#define dat_H2          33
#define dat_H4          25
#define dat_H8          32

// ADT7410_addr
#define ADT7410_addr     0x4b

int int_flg = 0;
int state_flg = 0;
float heat_tmp = 0;
int tm_cnt,past_time = 0;

hw_timer_t * timer = NULL;
portMUX_TYPE timerMux = portMUX_INITIALIZER_UNLOCKED;

void IRAM_ATTR onTimer()
{
    // Timer interrupt 
    portENTER_CRITICAL_ISR(&timerMux);
    int_flg = 2;
}

void IRAM_ATTR Handle_st()
{
    // Push Start / Stop Button
    portENTER_CRITICAL_ISR(&timerMux);
    int_flg = 1;
}

void setup() 
{
    Wire.begin();
    SPI.begin();

    Serial.begin(115200);
    
    pinMode(Pilot_Lamp, OUTPUT);
    digitalWrite(Pilot_Lamp,LOW);
    
    pinMode(Power_ctl, OUTPUT);
    digitalWrite(Power_ctl,LOW);
    
    pinMode(Power_Led, OUTPUT);
    digitalWrite(Power_Led,LOW);
    
    pinMode(St_btn, INPUT_PULLUP);

    pinMode(dat_L1, INPUT);
    pinMode(dat_L2, INPUT);
    pinMode(dat_L4, INPUT);
    pinMode(dat_L8, INPUT);
    
    pinMode(dat_H1, INPUT_PULLDOWN);
    pinMode(dat_H2, INPUT_PULLDOWN);
    pinMode(dat_H4, INPUT_PULLDOWN);
    pinMode(dat_H8, INPUT_PULLDOWN);

    attachInterrupt(St_btn, Handle_st, FALLING);

    timer = timerBegin(0, 80, true);
    timerAttachInterrupt(timer, &onTimer, true);
    timerAlarmWrite(timer, 5000000, true);
    timerAlarmEnable(timer);

    Init_LCD();
    disp_temp();
}

void loop() 
{
    float ht_temp;
    int a;
  
    while(int_flg == 0) delay(10);
    delay(500);
    disp_temp();
   
    switch(int_flg)
    {
        case 1: // Start or Stop
                for(a = 0; a< 5; a++)
                    while(!digitalRead(St_btn)) delay(10);
                delay(100);

                a = HIGH;
                if(state_flg) a = LOW;
                else heat_tmp = get_target_temp() * 1.92 - 24.14;

                digitalWrite(Power_ctl,a);
                digitalWrite(Power_Led,a);
                digitalWrite(Pilot_Lamp,a);
                tm_cnt = past_time = 0;
                state_flg = !state_flg;

                portEXIT_CRITICAL_ISR(&timerMux);
                break;

        case 2: // Interrupt 
                if(state_flg)
                {
                    ht_temp = ADT7410_get_temp(ADT7410_addr);
                    a = LOW;
                    if(ht_temp < heat_tmp) a = HIGH;
                    digitalWrite(Power_ctl,a);
                    digitalWrite(Power_Led,a);
                }
                
                portEXIT_CRITICAL_ISR(&timerMux);
                break;

    }

    int_flg = 0;
}


int get_target_temp()
{
  int a;

    a = 0;          
    if(digitalRead(dat_H1)) a = 1;
    if(digitalRead(dat_H2)) a += 2;
    if(digitalRead(dat_H4)) a += 4;
    if(digitalRead(dat_H8)) a += 8;
    a *= 10;

    if(digitalRead(dat_L1)) a += 1;
    if(digitalRead(dat_L2)) a += 2;
    if(digitalRead(dat_L4)) a += 4;
    if(digitalRead(dat_L8)) a += 8;
    
    return a;
}

void disp_temp()
{
    char c_buf[50];
    String buf; 
    float h_data[2];
    
    LCD_CLS(0);
                
    if(state_flg)
     {
        tm_cnt ++;
        if(tm_cnt == 12) {tm_cnt = 0; past_time ++;}
     } 
      
    AM2320(h_data);
    buf = "T:" + String(h_data[1]) + "'c ";
    buf.toCharArray(c_buf, 50);
    LCD_Print_Str(0,0,c_buf,1,2);
    
    buf = "H:" + String(h_data[0]) + "% ";
    buf.toCharArray(c_buf, 50);
    LCD_Print_Str(0,16,c_buf,1,2);

    buf = "PT:" + String(past_time) ;
    buf.toCharArray(c_buf, 50);
    LCD_Print_Str(0,32,c_buf,1,2);

}
  • 11行:#define St_btn GPIO_NUM_27
    • Start/Stop用ボタンの割り込みに使用
  • 14、17,18行:パイロットLED、SSR、ヒーターLED制御用端子
  • 21から28行: 温度設定用ロータリースイッチ読み取り用端子
  • 31行:ADT7410のI2Cアドレス。今回は、0X4B。
  • 38,39、85−88行:タイマーの設定です。
    • 今回はRTCを使わずESP32のタイマーで割り込みを行っています。
  • 41から46行:タイマー割り込みがかかるとここが実行される
  • 48から53行:Start/Stopボタンが押されるとここが実行される
  • 73から76行:温度設定用1の位読み取りポートの設定。
    • これらのポートはInput専用でかつ、プルダウン無し。
    • ハードで(抵抗を付けて)プルダウンしている
  • 78から81行:温度設定用10の位読み取りポートの設定
    • ソフトでプルダウンを設定
  • 83行:Start/Stopボタン割り込み設定
  • 103から136行: 割り込みの処理
    • 105から121行:スタート、ストップの処理
    • 123から134行:ヒーターの制御
  • 142から159行:設定温度読み取り
  • 161から188行:測定値の表示

その他、AM2320.cpp/.h、AQM1248A.cpp/.h、ADT7410.cpp/.h が必要です。これら全てまとめてここに保存して起きました ー> 今回のソフト

最後に

今回で最後です。面白い保温器が出来たと思います。納豆を作りたくて始めた今回ですが、保温器の製作に時間がかかり本来の納豆はまだ1回しか作っていません。