M5Stack GrayでESPHomeを使うための設定

センサーからのデータを簡単に記録に残すために、ホームオートメーションのためのオープンソースの Home Assistant を試すことにした。Home Assistant は、(センサー)デバイスからのデータ収集やそれらのデータをトリガーや条件としたアクションの制御ができる。

センサーデバイスとしては様々なものが使えるようになっているが、実験を行うには Espressif のESP32 (もしくは ESP8266)で動作する ESPHome が便利そうである。また、とりあえずの実験ではブレッドボードなどを使わず、Groveなどでセンサーをつなげてディスプレイがあるものが便利なので、ESP32を利用した M5Stack Gray (Grey) [ M5Stack Basic ]で試してみることにした ( M5Stack Core 2 は表示が正常にならなかったので、もう少し試してからまとめたい )。

ESPHomeは、YAML (Yet Another Markup Language → YAML Ain't a Markup Language )形式でデバイスの仕様を記述すると、それに基づいて PlatformIO を利用してファームウェアをビルドしてくれる。PlatformIOのダウンロードやライブラリのダウンロードも基本的に自動なので、用意されている機能をYAMLで制御すればよい程度の軽いカスタマイズをする場合には便利と思われる。

試用環境

ハードウェア

ソフトウェア

  • Windows 11 Pro 22H2 22621.1555
    • CP210x Universal Windows Driver v11.2.0 (10/21/2022)
  • Home Assistant 2023.5.2 (Supervisor 2023.04.1, Operating System 10.1, フロントエンド: 20230503.3)
    • ESPHome version: 2023.4.4

試用のまとめ

ESPHomeには ESP32のフラッシュメモリへの書き込みを無線で(Over The Air – OTA)できる機能があるが、最初だけはUSB接続でインストールする必要がある。これを ESPHome Web を利用して行ったが、うまくいかないことが多く難儀した。Platform IO (Arduino)からUSBでプログラムの書き込みをすると問題なくできるので、ESPHome Web 書き込みプログラムの問題なのであろうか。ESP32への書き込みの問題としては、ESP32のフラッシュへの書き込みエラーの時のようなキャパシタの容量不足というわけではなさそうである。

M5Stack Gray (Basic) には ディスプレイ用チップが異なる2種類があり、現在は販売されていないが、ILI9341を使用した古いものでは、カラー表示が反転されてしまう。表示以外の機能は、比較的新しい M5Stack Gray (ILI9342C使用)も、古いM5Stack Gray (ILI9341使用)も同じと思われる。

初期設定手順

M5Stack (Basic, Gray, Core 2)への初期firmware書き込み

M5StackをパソコンのUSBに接続し、Webブラウザから ESPHome Web にアクセスし、書き込みを行う。まず、ESPHome Web ではCONNECT を選択する。ポート選択画面になったら、対象のM5Stackが接続されているポートを選択する。パソコンに接続しているシリアル(UART)デバイスがM5Stackだけなら、1つしか表示されていないはずで、それを選択すればよい。M5Stack以外のシリアルデバイスが接続されいる場合には、M5Stackが CP2102 USB-to-UART Bridge Controller を利用しているので、それを選択する。

初めてM5Stack (Basic, Gray, Core 2)への書き込みを行う場合には M5Stackで利用されている USB – UART ブリッジチップ (CP2102)のドライバをインストールする必要がある。CP210x Universal Windows Driver v11.2.0 (10/21/2022) を使用した。また、Webブラウザからシリアスデバイスを利用する際には、アクセスの許可をする必要がある。

Prepare your device for first use の Install を選択して、初期ファームウェアを書き込む。

Home Assistantへの登録

Home Assistantから ESPHome を使うのが簡単そうなのでそのようにした。

Home Assistant は Windows の Hyper-V を利用してインストールした。

Home Assistant への ESPHome のインストールについては、Getting Started with ESPHome and Home Assistant などに記載がある。

Home Assistant へのESPHomeのインストール時もしくはその後に、サイドバーへの追加を行って、アクセスしやすいようにして以下の例では示している。

初期ファームウェアを書き込むと、ESPHomeで検出がされる。ESPHomeで Adopt を選択することも可能だが、以下では Home Assistant の設定を利用した例を示す。

Home Assistant で通知があり、通知をクリックすると「New devices discovered」と出る。

「Check it out」をクリックして確認する。発見されたデバイスの「設定」をクリックする。

「ESPHomeのノードが検出されました」と出る。追加するかと尋ねられるので、「送信(Submit)」をクリックする。

うまく登録されれば以下のようになる。エリアなどは適切に設定する必要があるが、ここでは必要がないのでそのままにする。

登録後は、ESPHomeからデバイスに応じた YAMLファイルを定義し、ファームウェアをビルドして、WiFi でアップロードすることになる。

M5Stack Gray (ILI9342C使用)

M5Stack Gray (ILI9342C使用)のYAML

M5Stackの機能にESPHomeでアクセスできることを確認するために以下の YAMLファイルを利用した。 YAMLのboard: に m5stack-grey とするので、YAML内ではgray ではなく、 grey を使っている。

暗号のキーやパスワードは、デバイスの登録時に自動的に設定されるのでそれを利用する必要がある。また、デバイス名などはデバイスごとに適切に設定する必要がある。

logger: の level: は必要に応じて変更する必要がある。

M5Stack Basic にはMPU6886がないので、最後の方の 6軸加速度センサー MPU6886に関する記述は、Basic では削除する必要がある。地磁気センサーBMM150はESPHome のセンサーコンポーネントがないために試していない。

substitutions:
  device_name: m5stack_grey_with_ILI9342C
  _friendly_name: "ESPHome Web c5a2d0 Grey (ILI9342C)"

esphome:
  name: esphome-web-c5a2d0
  friendly_name: $_friendly_name

esp32:
  board: m5stack-grey # M5Stack Grey
  framework:
    type: arduino

# Enable logging
logger:
  level: DEBUG # Remove this line if normal use

# Enable Home Assistant API
api:
  encryption:
    key: "sASMDEVYpJ1rRw5bTmbv0U7iB6eZfs4Ct9osYp5PFfo="

# Enable OTA (Over-The-Air)
ota: 

# WiFi Access Point
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-C5A2D0"
    password: "fPKaK7CujFeA"

# Fallback mechanism when WiFi Access Point cannot be connected to
captive_portal:

# SPI setting (needed for display)
spi: # M5Stack Grey
  clk_pin: GPIO18
  mosi_pin: GPIO23
  miso_pin: GPIO19

# Fonts (needed for text display)
font:
  - file: "gfonts://Roboto" # Google Fonts
    id: roboto48
    size: 48
  - file: "gfonts://Roboto" # Google Fonts
    id: roboto14
    size: 14

# Dimmable led (PWM) for display backlight 
output: # M5Stack Grey
  - platform: ledc
    pin: GPIO32
    id: gpio_32_backlight_pwm

# Display backlight
light:  # M5Stack Grey
  - platform: monochromatic
    output: gpio_32_backlight_pwm
    name: "Display Backlight"
    id: back_light
    restore_mode: ALWAYS_ON

# QR Code generation (used in sample display)
qr_code:
  - id: homepage_qr
    value: $device_name

# Display for M5Stack Grey (ILI9342C)
display:
  - platform: ili9xxx
    model: M5STACK # M5Stack Grey
    cs_pin: GPIO14
    dc_pin: GPIO27
    reset_pin: GPIO33
    #rotation: 0
    id: basic_display
    #
    pages:
      - id: page0
        lambda: |-
          Color COLOR_BLACK(0,0,0);
          Color COLOR_RED(255,0,0);
          Color COLOR_GREEN(0,255,0);
          Color COLOR_BLUE(0,0,255);
          Color COLOR_WHITE(255,255,255);
          auto margin = 30;
          it.fill(COLOR_GREEN);
          it.line(50, 10, it.get_height(), it.get_width(), COLOR_RED);
          it.line(0, it.get_height(), it.get_width(), 0, COLOR_WHITE);
          it.rectangle(0+margin, 0+margin, it.get_width()-2*margin, it.get_height()-2*margin, COLOR_BLUE);
          it.print(10, 10, id(roboto14), COLOR_RED, TextAlign::TOP_LEFT, "$_friendly_name");
          it.print(20, 50, id(roboto48), COLOR_WHITE, TextAlign::TOP_LEFT, "Hello World!");
      - id: page1
        lambda: |-
          // Draw the QR-code at position [x=50,y=50] with white color and a 5x scale
          it.qr_code(50, 50, id(homepage_qr), Color(255,255,255), 5);
      - id: page2
        lambda: |-
          // Draw a circle in the middle of the display
          it.filled_circle(it.get_width() / 2, it.get_height() / 2, 50);

# M5Stack Basic Buttons
binary_sensor: # M5Stack Grey
  - platform: gpio
    pin:
      number: GPIO39
      inverted: false
    name: ButtonA
    on_press:
      then:
        - display.page.show_previous: basic_display
        - light.turn_on:
            id: back_light
            brightness: 25%

  - platform: gpio
    pin:
      number: GPIO38
      inverted: false
    name: ButtonB
    on_press:
      then:
        - display.page.show: page1
        - light.turn_on:
            id: back_light
            brightness: 50%

  - platform: gpio
    pin:
      number: GPIO37
      inverted: false
    name: ButtonC
    on_press:
      then:
        - display.page.show_next: basic_display
        - light.turn_on:
            id: back_light
            brightness: 100%

# M5Stack Basic i2c (needed for mpu6886) 
i2c:
    - id: i2c_bus
      sda: GPIO21
      scl: GPIO22
      scan: True

# Sensor sample
sensor:
  - platform: wifi_signal
    name: WiFi Signal
    id: wifi_dbm
  - platform: uptime
    name: Uptime
    id: uptime_sec

  # M5Stack Grey sensors (M5Stack Basic does not have MPU6886)
  # MPU6886: 6-Axis MotionTracking Sensor
  - platform: mpu6886
    address: 0x68
    accel_x:
      name: "MPU6886 Accel X"
    accel_y:
      name: "MPU6886 Accel Y"
    accel_z:
      name: "MPU6886 Accel z"
    gyro_x:
      name: "MPU6886 Gyro X"
    gyro_y:
      name: "MPU6886 Gyro Y"
    gyro_z:
      name: "MPU6886 Gyro z"
    temperature:
      name: "MPU6886 Temperature"

ファームウェアのビルドとアップロード

ESPHomeのデバイスの一覧から対象のデバイスの「Edit」をクリックして YAMLを入力する。

YAMLの入力が終わったら「SAVE」をクリックし、次に 「INSTALL」をクリックする。

 

インストール方法の選択が求められるので、適切な方法を選択する。ここでは最も簡単なWiFi経由(OTA)での「Wirelessly」を選択する。

YAMLに応じて必要なソフトウェア(PlatformIO やライブラリ、フォントなど)がダウンロードされ、ビルドが行われる。ビルドがうまくいけば、WiFiによるアップロードが行われ、デバイスがリセットされて起動する。

その後、WiFiによってESP32での実行の際のログが取得されるようになる。

sensor は、定期的にチェックして情報が取得されるので、このYAMLの例では wifi_siginal と uptime の情報が定期的に取得されている。

Home Assistantの画面

Home Assitantのオーバービューの画面で、情報の一部をみることができる。

また、「設定」→「デバイスとサービス」→対象のM5Stackデバイスの選択→「1デバイス」として表示されているデバイスを選択することで、診断情報として、Uptime や WiFi Signal の情報を確認することができる。

実行時のM5Stack Grayの画面

YAMLで作成したファームウェア実行時の画面表示でpage0, page1, page2 は以下のようになる。左ボタンでひとつ前のpageに遷移し(たとえば、page0 が page2)、中央ボタンでpage1に遷移し、右ボタンでひとつ次のpageに遷移する (たとえば、page0 が page1)。また、バックライトの明るさをボタンを押すと変えるようにしている。左ボタンで25%、中央ボタンで50%、右ボタンで100%の brightness を設定している。

最初の方のまとめで書いたように、古い M5Stack Grey (ILI9341使用)では、カラーが反転した。ライブラリ ili9xxx はチップの違いを判別して、初期化を変えるようにはなっていない。

また、M5Stack のディスプレイのためのライブラリが2023年になって ili9xxx に変わり、2023年5月6日現在M5Stack Core 2の表示が正常にできなくなっているようで、過渡期の感じである。displayの model を M5STACKからM5CORE2 にしても正しく表示されなかった。ちなみに、ライブラリを変え、通電したままファームウェアを2種類書き込むと表示が正常になるようであり、ライブラリでのディスプレイデバイスの初期化に問題があるようだ。

その他 (ble_scanner)

M5Stack Grayで ble_scanner を以下をYAMLに追加することでBLEの動作確認しようとした。M5Stackのディスプレイやボタンなどは動作するが、WiFi経由でのデータやログ情報などが取得できない。Home AssistantでもOffline になって、データを取得することができない。M5Stack Core 2では動作しているので、PSRAMなどの量によるのかもしれない。あまり調べていない。

esp32_ble_tracker:
  
text_sensor:
  - platform: ble_scanner
    name: "BLE Devices Scanner"