ESP8266で植物栽培LEDをタイマー駆動、Deep-Sleepでちょっと・・・

2023年6月14日Arduino/ESP32D1 Mini,DeepSleep,ESP8266,ディープスリープ

折角マイコンを使ってLEDを制御しているのだから、毎日決まった時間に自動点灯させたい。

というわけで点灯をタイマー駆動する事に。

低消費電力モードをウリにしていた位だから、きっとサクサクいくだろうと思っていました。

この時は。

ESP8266のDeepSleepモードについて

どうやらESP8266及びESP32などEspressifのESPシリーズには3つのスリープモードがあるらしい。

ざっくりと以下の3つ。

松:Deep-Sleep

電流:10uAぐらい

RTCメモリとULPコントローラ、復帰以外は行えないガッツリスリープ。

各GPIOのウェイクアップ時ステータスもオフに出来る

タイマーかウェイクアップピンへの加印でしか起きられない。

復帰時はほぼ再起動。

竹:Light-Sleep

電流:0.9mAぐらい

CPUサスペンド、無線もOFF、GPIOも基本はOFF(設定で例外設定可)、まぁまぁのスリープ

GPIOや無線、UART等いろんな所から起床できる

メモリ状態も保持。一時停止ボタンみたいなイメージ

梅:Modem-Sleep

電流:15mAぐらい

無線モデムをスリープ

無線以外はあまりスリープしない

スリープという感じではなく、省電力モードというイメージ。

ざっくりと予習した内容がこんな感じ。

本当にざっくりと。

さて

うん、なんかいっぱいある。

読むのも覚えるのもまんどくさいので、とりあえず判りやすいDeep-Sleepから試してみる。

スリープの準備・実行

スリープはとりあえずこんな感じで突入するらしい。

	// ESP.deepSleep(時間, 起床モード指定);
	ESP.deepSleep(30 * 1000 * 1000 , WAKE_RF_DEFAULT);

タイマーによる起床トリガーの場合、指定時間を経過したらGPIO16がLOWに落とされるらしいので、ESP8266のGPIO16(D0)をRSTピンと直結しておく。

これで時間経過後、自動リセットボタンによる起床という塩梅。

らしい。

ESP8266 Deep Sleep with Arduino IDE (NodeMCU)

このGPIO16(D0)とRSTの間を結線するというのがミソらしく、ボードによっては抵抗を入れたり入れなかったりダイオードを入れたりという事みたい。

手元にあるのは恐らくD1 Mini V2っぽいので、抵抗よりダイオードかなって辺りで1N4148を入れる事に。

RSTピンがアノード側、→ GPIO16(D0)ピンがカソード側 で接続する模様。

Wakeup Modeについて

Esp.hを見ると起床モードには4種類くらいあるらしい。

enum RFMode {
    RF_DEFAULT = 0, // RF_CAL or not after deep-sleep wake up, depends on init data byte 108.
    RF_CAL = 1,      // RF_CAL after deep-sleep wake up, there will be large current.
    RF_NO_CAL = 2,   // no RF_CAL after deep-sleep wake up, there will only be small current.
    RF_DISABLED = 4 // disable RF after deep-sleep wake up, just like modem sleep, there will be the smallest current.
};

#define RF_MODE(mode) int __get_rf_mode() { return mode; }
#define RF_PRE_INIT() void __run_user_rf_pre_init()

// compatibility definitions
#define WakeMode RFMode
#define WAKE_RF_DEFAULT  RF_DEFAULT
#define WAKE_RFCAL       RF_CAL
#define WAKE_NO_RFCAL    RF_NO_CAL
#define WAKE_RF_DISABLED RF_DISABLED

起床後の動作を指定するものらしいけれど、コメントを見てもピンとこない。

ウォーー!朝だぜ!新しい日だぜMorning!!

って起床するか、

あ゛゛ ねもぃ・・・無線とか起動すんのダルいしOFFのままでいいか・・・

って起床するかって辺りか。

とりあえずよくわからんけれど、今は無線使わないのでRF_DISABLED!

  // とりあえず10秒スリープ
  Serial.println("Begin to Sleep.");
  ESP.deepSleep(10 * 1000 * 1000, RF_DISABLED);

時間指定はus(マイクロ秒)みたいなので、10秒となると結構な数字に。

早速実行してみると、プログラムが停止した様な感じに。

そしてちゃんとタイマーで立ち上がってきますた。

外部電源から3.3Vを入力して駆動させる方法で、テスターを当ててみたら見事に0mA~1mA。

※手持ちのテスターがuAの電流を測定できない罠・・・( ノД`)

RF_DISABLEDの起床時の電流は20mA前後。

RF_DEFAULTだと一瞬80mAくらいまで上がるのが見える。

※テスターでの計測なので、だいぶ粒度が・・・( ノД`)

テスターさんが、

テスターが…

とにかく起床モードの設定は、起動時の無線起動をどうするかをいじれるらしいっぽい。

うん、テスターじゃわからないけど。

きっとオシロスコープとかで見たら判るんだと思うけど。

毎日決まった時間に起動しようとしてみる

そんなわけで、毎朝4時に目が覚めて、夕方6時に眠りにつく様なDeepスリープをしようかと。

植物栽培LEDを点灯するのだっ

てな感じでESP.deepSleep関数に、マイクロ秒で値を入れてみる。

14時間という事は、60秒 x 60分 x 14時間 で?

1秒が1000ms x 1000usだからっと 50400000000 マイクロ秒。

ゴツい数字やね、、、

これはuint32_tでは収まらないのでuint64_tに。

ESP.deepSleep関数もuint64_tが引数になってる模様。

ESP8266のArduinoライブラリ:\packages\framework-arduinoespressif8266\cores\esp8266\Esp.cpp より

void EspClass::deepSleep(uint64_t time_us, WakeMode mode)
{
    system_deep_sleep_set_option(static_cast<int>(mode));
    system_deep_sleep(time_us);
    esp_suspend();
}

void EspClass::deepSleepInstant(uint64_t time_us, WakeMode mode)
{
    system_deep_sleep_set_option(static_cast<int>(mode));
    system_deep_sleep_instant(time_us);
    esp_suspend();
}

というわけでセットしてみる。

  // とりあえずDeepSleep 14時間後に起床!
  Serial.println("Begin to Sleep.");
  // 60 * 60 * 14 * 1000 * 1000
  ESP.deepSleep(50400000000, RF_DISABLED);

うん、スリープモードに入ったらしい動きはした、、、

、、、ガっ 無理ですた

なんか全然電流値が下がらないんですけお?

シリアルモニタしてみると、メインループは停止していた。

まるでDeepSleepに突入したかの様な見た目。

でも、実際には40mA電気モリモリ流れててな

ちっともお休みしておらぬ。

というわけで調べる。

色々と調べる。

AIさんにも沢山聞いてみた。

けどね、AIさんもなんか色々違う事言うんだよ( ノД`)

困るよホント。

やっぱ安物ブレッドボードでやってるので、マイコンか降圧モジュール壊しちゃったかしらん・・・?

esp8266_deepsleeptest

こんな有様ですしおすし

ちょっと不用意に動かしたら短絡するよねこれ的な

というわけでちょっと調べものモード。

続く。

続くんですたぶん。