2018年8月11日土曜日

ESP32-DevKitCでWiFiとDeepSleep

ESP32-DevKitCでWiFiとDeep Sleepを試しました。

セットアップ


今回はArduino core for the ESP32(arduino-esp32)を使用しました。

以下のサイトを参考にしました。←だいぶ前に環境を作ったので詳細は覚えていません(^q^;

ESP-WROOM-32」の「セットアップ-ソフトウェア
Arduino core for the ESP32」の「Installation Instructions

Arduino IDEで「BLEがない云々」という警告が出るので、ESP-BLE-Arduinoを入手し、解凍、<Arduinoのインストール先>\hardware\espressif\esp32\libraries\BLEにコピーしました(Windows10)。

配線


ESP32-DevKitCも幅が広いのでブレッドボードを連結して使用しました。

動作確認用のLEDは1kΩのRを介してIO4に接続しています。

電源はUSBから取るとWiFi接続に失敗するなど動作が不安定なので5Vの安定化電源から取っています。(こちらもエネループを使っていて残量が少ないと動作が怪しくなります)

念の為100uFのOSコンでデカップリングしました。

ESP32-DevKitCの回路図(USB/電源周り)

USBからの5V電源「VBUS」と外部5V電源「EXT_5V」の間にはショットキーバリアダイオードのD3(1N5819)が入っていますが、ショットキーなので漏れ電流(やなんやかや)が心配です。EXT_5VとUSBのVBUSの同時使用を常用するのは避けたほうが無難だと思います。

スケッチ


int型のカウンターをインクリメントしてAmbientに送るスケッチをDeep Sleepあり/なしで書いて電源電流を比較しました。

Sleepなし <Ambient_ESP32_CountUp.ino>


#include "Ambient.h"

#define LED 4
#define PERIOD 10

const char* ssid = "WiFi APのssid";
const char* password = "WiFi APのpassword";

unsigned int channelId = <AmbientChannelId>;
const char* writeKey = "Ambientのpassword";

WiFiClient client;
Ambient ambient;

void setup()
{
  Serial.begin(115200);
  delay(20);

  Serial.println("Start");
  pinMode(LED, OUTPUT);

  WiFi.begin(ssid, password);

  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);

    digitalWrite(LED, i++ % 2);
    Serial.print(".");
  }

  digitalWrite(LED, LOW);
  Serial.print("WiFi connected\r\n");
  Serial.print("IP address: ");
  Serial.print(WiFi.localIP());
  Serial.print("\r\n");

  ambient.begin(channelId, writeKey, &client);
}

int cnt = 0;

void loop()
{
  Serial.print("cnt: ");
  Serial.print(cnt);
  Serial.print("\r\n");

  ambient.set(1, cnt);

  digitalWrite(LED, HIGH);

  ambient.send();

  digitalWrite(LED, LOW);

  delay(PERIOD * 1000);

  cnt++;
}

DeepSleepあり <Ambient_ESP32_DeepSleep_CountUp.ino>


/*
 * Ambient ESP32 DeepSleep CountUp
 *
 * 2018.08.11
 *
 */
#include "Ambient.h"

#define TITLE_STR1  ("Ambient ESP32 DeepSleep CountUp")
#define TITLE_STR2  ("2018.08.11")


#define uS_TO_S_FACTOR 1000000  /* Conversion factor for micro seconds to seconds */
#define TIME_TO_SLEEP  10        /* Time ESP32 will go to sleep (in seconds) */

#define LED (4)

const char* ssid = "WiFi APのssid";
const char* password = "WiFi APのpassword";

unsigned int channelId = <AmbientchannelId>;
const char* writeKey = "AmbientのwriteKey";

WiFiClient client;
Ambient ambient;

RTC_DATA_ATTR int bootCount = 0;

void setup()
{
  Serial.begin(115200);
  delay(20);

  Serial.println();
  Serial.println();
  Serial.println(TITLE_STR1);
  Serial.println(TITLE_STR2);

  Serial.println("Start");
  pinMode(LED, OUTPUT);
  
  bootCount++;
  Serial.println("Boot number: " + String(bootCount));

  WiFi.begin(ssid, password);

  int i = 0;
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);

    digitalWrite(LED, i++ % 2);
    Serial.print(".");
  }

  Serial.print("WiFi connected\r\n");
  Serial.print("IP address: ");
  Serial.print(WiFi.localIP());
  Serial.print("\r\n");

  ambient.begin(channelId, writeKey, &client);
  
  ambient.set(1, bootCount);
  ambient.send();

  esp_sleep_enable_timer_wakeup(TIME_TO_SLEEP * uS_TO_S_FACTOR);
  Serial.println("Setup ESP32 to sleep for every " + String(TIME_TO_SLEEP) + " Seconds");

  Serial.println("Going to sleep now");
  esp_deep_sleep_start();
  delay(1000);
}

void loop()
{
}

電源電流


OWON B35でロギングしました。サンプリング周期1s

Sleepなし

Avg 13.98116667 mV
Min 12.81 mV
Max 20.06 mV

DeepSleep

Avg 5.052566667 mV
Min 0.34 mV
Max 18.35 mV

Sleepなしだと常時140mA程度です。DeepSleepをかけるとWakeUp時は130mA~180mA、Sleep時は3.4mA程度で推移しています。Sleep時の電流はUSB-UART変換チップやLEDが結構消費してるんじゃないかな~と思います。

1秒周期のサンプリングなので、細かく見るともっとトゲトゲしく電源電流が変化している可能性が高いと思います。

ESP8266と比べると消費電流が多く、WakeUp時の概算で70mA vs 140mAで2倍程度です。

メモ:


ESP32のSleepモード(Modem Sleep、Light Sleep)については、「ESP-IDE Programming Guide」の「Sleep Mode」と「Power Management」にありますが、ネイティブ環境の「ESP-IDF」用なのでそのうち試したいと思います。

ESP-IDFはI2Sも使えるようで(参考「じわじわ進む」さんの「ESP32でI2Sから音を出す」)、ESP-IDFを少し触った感じではNucleoのネイティブ環境の「STM32Cube/CubeMX」よりとっつきやすそうです。

WiFi APのssidやpasswordを生書きしているのでミスってBlogにあげてしまわないかヒヤヒヤです。ソース管理もつらい(@@;