前にゼルダエフェクトーンを自作してみましたが、電池の持ちが悪すぎたので今回スリープモードを導入した改良版を作りました。
具体的には「ドアを開けた時だけ起動して、ドアが閉まっている時にはスリープモードになる」ようにしています。
回路も一部変更しているので注意してください。使う材料は全く同じです。
1:回路図改良版
修正箇所は「マグネットスイッチから出ているIO12に繋いでいた線をGNDに繋げている」点のみです。IO14のピンのHIGH、LOWでスリープモードの切り替えを行うようにプログラムも修正します。
2:プログラム改良版
改良したプログラムは以下のようになります。
・Effectone_v2.ino
#include <esp_deep_sleep.h> #define BUZZER_PIN 23 // ブザーを鳴らすためのピン #define JUDGE_PIN 14 // 磁石スイッチの判断をするピン #define BEAT 150 // 一つの音を鳴らす時間 #define LEDC_CHANNEL 0 // チャンネル #define LEDC_TIMER_BIT 13 #define LEDC_BASE_FREQ 5000 void setup() { // マグネットスイッチに関係するピンの準備 pinMode(JUDGE_PIN, INPUT); // 音を鳴らす準備 ledcSetup(LEDC_CHANNEL, LEDC_BASE_FREQ, LEDC_TIMER_BIT); ledcAttachPin(BUZZER_PIN, LEDC_CHANNEL); callZeldaSound(); // ゼルダの謎解き音を鳴らす // スリープのための諸々の設定(今回はGPIO14ピンを使う) esp_deep_sleep_pd_config(ESP_PD_DOMAIN_RTC_PERIPH, ESP_PD_OPTION_AUTO); gpio_pullup_en(GPIO_NUM_14); gpio_pulldown_dis(GPIO_NUM_14); esp_deep_sleep_enable_ext0_wakeup(GPIO_NUM_14, 1); // GPIO14がHIGHになったらスリープモード解除 // 扉が閉まるまで待つ do { ; } while (digitalRead(JUDGE_PIN) == HIGH); // 扉が閉まったらスリープモード実行 esp_deep_sleep_start(); } void loop() { // loopではなにもしない } /** * ゼルダの謎解き音 */ void callZeldaSound() { ledcWriteTone(LEDC_CHANNEL, 3136); // ソ delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 2960); // ♯ファ delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 2489); // ♯レ delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 1760); // ラ delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 1661); // ♯ソ delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 2637); // ミ delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 3322); // ♯ソ delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 4186); // ド delay(BEAT); ledcWriteTone(LEDC_CHANNEL, 0); // 音を止める }
loop関数での処理を一切やめてsetup関数のみで色々やるようにしています。
今回使用しているマグネットスイッチは磁石が近づいている時がLOW、磁石が遠くにある時がHIGHなので、無限ループで扉が閉まるまで待っています。扉がしまったらスリープモードに移行するようにしています。
今回の改良で前回よりは電池の持ちがよくなりました。体感的には1日以上持つようになりました。(改良前は数時間で電池切れしていた)
ESP32は結構電池を食うので、コンセントから電源を取らない場合はスリープモードも考慮する必要があるようです。
■改良前の記事とスリープモードについて
【ESP32】ゼルダエフェクトーンを自作してみた - ソースに絡まるエスカルゴ
【ESP32】スリープモードについて - ソースに絡まるエスカルゴ