StackChan Home Assistant 統合

StackChan は、M5Stack とユーザーコミュニティが共同で開発したかわいい AI デスクトップロボットです。M5Stack のフラッグシップ IoT 開発キット CoreS3 をホストとして使用し、ESP32-S3 メインコントローラー、240 MHz デュアルコアプロセッサー、16MB Flash、8MB PSRAM を搭載しています。Wi-Fi と BLE に対応し、2.0 インチ強化ガラス静電容量式タッチスクリーン、0.3 MP カメラ、近接センサー、9 軸姿勢センサー(加速度 + ジャイロ + 地磁気)、microSD カードスロット、1W スピーカー、デュアルマイク、電源 / リセットボタンなどを備えています。本チュートリアルでは、StackChan とその周辺機器を Home Assistant に統合する方法を説明します。

1. 準備

環境準備

  1. Home Assistant 公式ドキュメントを参照して Home Assistant をインストールします。
  2. ESPHome 公式ドキュメントを参照して ESPHome Device Builder アドオンをインストールします。(注:本チュートリアルは ESPHome 2026.4.4 を基準に作成されています。コンパイルエラーが発生した場合は、このバージョンに切り替えて確認してください。)

ハードウェア製品

2. オンライン書き込み

下の オンライン書き込み ボタンをクリックし、画面の指示に従ってファームウェアの書き込みと Wi-Fi 設定を完了すると、StackChan を Home Assistant にすぐに接続して試すことができます。

書き込みと設定の詳細については、ESPHome ファームウェアのオンライン書き込みと設定を参照してください。

オンライン書き込みを使用した場合、「ファームウェアのコンパイルと書き込み」の手順は不要です。4. 使い方へ進んでください。

すぐに使用できる音声アシスタントを体験する場合は、StackChan 音声アシスタントファームウェアを書き込みます。

音声アシスタントの注意事項
パフォーマンス上の制約により、音声アシスタントファームウェアには基本的な音声、ディスプレイ、タッチ、サーボ制御機能のみが含まれ、多くの周辺機器は統合されていません。ネットワーク設定後に音声アシスタントが正常に動作しない場合は、StackChan の電源を完全に切ってから再起動してください。

事前にビルドされたファームウェアを手動でダウンロードする場合は、GitHub Releaseを参照してください。

3. ファームウェアのコンパイルと書き込み

このセクションでは、二次開発、機能変更、機能追加を行うために、yaml 設定ファイルを基にプロジェクトを再コンパイルする方法を説明します。

コンパイル時間
HA でのファームウェアコンパイルは多くのリソースを消費します。初回コンパイル時は、HA サービスを実行するデバイスの性能やネットワーク品質によって、リソースのダウンロードに時間がかかる場合があります。

デバイスの作成

  1. Home Assistant で ESPHome Builder を開き、右下の NEW DEVICE ボタンをクリックして設定ファイルを作成します。
  1. ポップアップで CONTINUE をクリックします。
  1. New Device Setup を選択します。
  1. 設定ファイル名を入力します。
  1. デバイスタイプを選択します。まず Use recommended settings のチェックを外し、ESP32-S3 をクリックしてリストから M5Stack CoreS3 を選択します。
  1. API Encryption Key を控えてから、SKIP をクリックします。

設定の変更

  1. 新しく生成された設定カードの EDIT をクリックします。
  1. 設定ファイルの末尾に以下の機能パッケージを追加します。
packages:
  remote_package_files:
    url: https://github.com/m5stack/esphome-yaml
    files: [examples/kit/stackchan-bsp.factory.yaml]
    ref: main
    refresh: 0s
  1. 右上の SAVE をクリックし、続いて INSTALL をクリックして Manual Download を選択します。

ファームウェアの書き込み

  1. コンパイルが完了したら、Factory Format を選択してファームウェアをダウンロードします。
  1. USB Type-C ケーブルで StackChan をコンピューターに接続し、リセットボタンを長押しして緑色 LED が点灯したら放し、ダウンロードモードに入れます。

  2. ブラウザで ESPHome Web を開き、CONNECT をクリックして正しいデバイスポートを選択します。

  1. INSTALL をクリックし、ダウンロードしたファームウェアを選択します。
  1. 再度 INSTALL をクリックしてデバイスに書き込みます。
  1. 書き込みが完了するのを待ちます。
  1. 書き込み完了後、StackChan の RESET ボタンを押して再起動します。

4. 使い方

  1. 書き込みと再起動が完了すると、デバイスは自動的にWi-Fiに接続します。同じLAN 内のHome Assistantは新しいデバイスを検出します。Settings -> Devices & services で確認してください。

  2. デバイスが検出されたら:

  • 発見ページで Add をクリックします。
  • ダイアログが表示されたら Submit を選択します。
  • 以前にAPIキーを暗号化に使用した場合は、適切なキーを入力して検証します。未使用の場合は通常通り設定を続行します。

追加後、ESPHome 統合の下にデバイスとエンティティ、およびダッシュボードが表示されます。

5. 周辺機器の概要

このセクションでは、StackChan 上の各種コンポーネントについて説明します。主にCoreS3ホスト、Power Board、Touch BoardのICデバイスに分かれています。

ヒント
AXP2101、AW9523B、AW88298は現在外部コンポーネントのサポートが必要であり、機能には影響しません。

主なピン構成:

i2s_audio:
  id: i2s_audio_bus
  i2s_lrclk_pin: GPIO33
  i2s_bclk_pin: GPIO34
  i2s_mclk_pin:
    number: GPIO0
    ignore_strapping_warning: true

i2c:
  - id: bsp_bus
    sda: GPIO12
    scl: GPIO11
    frequency: 100kHz
    scan: true

spi:
  - id: spi_bus
    clk_pin: GPIO36
    mosi_pin: GPIO37

uart:
  tx_pin: GPIO6
  rx_pin: GPIO7
  baud_rate: 1000000

PMIC AXP2101

このコンポーネントはI2Cを必要とし、outputコンポーネントでLDOを設定します:

axp2101:
  id: axp2101_pmu
  i2c_id: bsp_bus

output:
  - platform: axp2101
    type: range
    channel: DLDO1
    id: lcd_backlight_output
    min_voltage: 2600
    max_voltage: 3300

  - platform: axp2101
    channel: ALDO1
    voltage: 1800
  ...

IOエキスパンダ AW9523B

このコンポーネントはI2Cを必要とし、Pin Schemaをサポートします。主にリセット/電源制御に使用されます。リセット信号に使用されるスイッチはすべて internal: true とマークされており、Home Assistantフロントエンドには表示されません。同時に BOOST_ENBUS_OUT_ENUSB_OTG_EN は電源方向を制御します。電源管理の例を参照してください。使用時は BOOST_EN を先に有効にし、その後に BUS_OUT_ENUSB_OTG_EN を制御します。

aw9523b:
  id: aw9523b_hub
  i2c_id: bsp_bus
  p0_drive_mode: PUSH_PULL

switch:
  - platform: gpio
    name: "AW RST P0_2"
    pin:
      aw9523b_id: aw9523b_hub
      number: 2
    internal: true
    restore_mode: RESTORE_DEFAULT_ON
    ...

Audio ADC ES7210

このコンポーネントはI2Cを必要とします。音声アシスタントを使用する場合、sample_rate16000 にする必要があります。

audio_adc:
  - platform: es7210
    id: es7210_adc
    i2c_id: bsp_bus
    bits_per_sample: 16bit
    sample_rate: 16000
    mic_gain: 36

マイク

このコンポーネントにはI2Sが必要です。マイクコンポーネントは音声アシスタントと組み合わせて使用できますが、HAフロントエンドには表示されません。

microphone:
  - platform: i2s_audio
    id: i2s_mic
    i2s_din_pin: GPIO14
    adc_type: external
    sample_rate: 16000
    bits_per_sample: 16bit
    i2s_audio_id: i2s_audio_bus

Audio Amplifier AW88298

audio_dac:
  - platform: aw88298
    id: aw88298_dac
    i2c_id: bsp_bus
    sample_rate: 48000

スピーカー / プレーヤー

このコンポーネントはI2Sを必要とします。Home Assistantフロントエンドでメディアプレーヤーを使って音楽を再生できます。

speaker:
  - platform: i2s_audio
    i2s_audio_id: i2s_audio_bus
    id: i2s_speaker
    dac_type: external
    i2s_dout_pin: GPIO13
    audio_dac: aw88298_dac

media_player:
  - platform: speaker
    name: None
    id: va_media_player
    volume_min: 0.5
    volume_max: 0.8
    announcement_pipeline:
      speaker: i2s_speaker
      format: FLAC
      sample_rate: 48000
      num_channels: 1

LCD ILI9342C

このコンポーネントはSPIを必要とし、data_rate の最大は 40MHz です。正しいRGBカラーに対応するために invert_colors: true を設定します。

display:
  - platform: mipi_spi
    model: M5CORE
    dc_pin: GPIO35
    reset_pin:
      aw9523b_id: aw9523b_hub
      number: 9
    cs_pin:
      number: GPIO3
      ignore_strapping_warning: true
    data_rate: 40MHz
    invert_colors: true
    id: m5cores3_lcd
    show_test_card: true

カメラ GC0308

このコンポーネントはI2Cを必要とします。有効にするとHome Assistantフロントエンドでライブビデオストリームが表示されます。

esp32_camera:
  name: "Camera"
  i2c_id: bsp_bus
  vsync_pin:
    number: GPIO46
    ignore_strapping_warning: true
  href_pin: GPIO38
  external_clock:
    pin: GPIO2
    frequency: 20MHz
  pixel_clock_pin:
    number: GPIO45
    ignore_strapping_warning: true
  data_pins: [GPIO39, GPIO40, GPIO41, GPIO42, GPIO15, GPIO16, GPIO48, GPIO47] # D0-D7
  max_framerate: 15.0 fps
  resolution: 320x240
  frame_buffer_count: 1
  pixel_format: RGB565
  jpeg_quality: 6
  agc_mode: manual

RTC BM8563

このコンポーネントはI2Cを必要とし、インターネットまたはHome Assistantホストと時刻同期できます。

esphome:
  ...
  on_boot: 
    then:
      # read the RTC time once when the system boots
      bm8563.read_time:

time:
  - platform: bm8563
    i2c_id: bsp_bus
    # repeated synchronization is not necessary unless the external RTC
    # is much more accurate than the internal clock
    update_interval: never
  - platform: homeassistant
    # instead try to synchronize via network repeatedly ...
    on_time_sync:
      then:
        # ... and update the RTC when the synchronization was successful
        bm8563.write_time:

上記の内容はシリアルログ内のみ表示されます。

近接センサー LTR-553ALS-WA

このコンポーネントはI2Cを必要とし、環境光と近接情報を提供します。

sensor:
  - platform: ltr_als_ps
    address: 0x23
    i2c_id: bsp_bus
    update_interval: 10s
    type: ALS_PS
    ambient_light:
      name: "Ambient light"
    glass_attenuation_factor: 2.5
    auto_mode: true
    ps_cooldown: 5 s
    ps_high_threshold: 500
    # on_ps_high_threshold:
    #   then:
    #     - .... # do something - light up the screen for example
    ps_counts: "Proximity counts"

BMI270 6 軸姿勢センサー(WIP)

BMM150 3 軸磁力計(WIP)

M5IOE1 マルチファンクションIOエキスパンダ

このコンポーネントはI2Cを必要とします。

m5ioe1:
  id: m5ioe1_hub
  i2c_id: bsp_bus
  reset: true

switch:
  - platform: gpio
    name: "M5IOE1 Pin 1"
    pin:
      m5ioe1_id: m5ioe1_hub
      number: 0
      mode:
        output: true
        pullup: true
    restore_mode: RESTORE_DEFAULT_ON
  ...

ここでの M5IOE1 Pin 1 スイッチはサーボ電源用です。M5IOE1 Pin 14 スイッチはNeoPixel 制御用アドレッサブルLEDテープ用にデフォルトで有効です。手動でオンにする必要はありません。ライトコンポーネントが自動的に制御します。

電力計 INA266

このコンポーネントはI2Cを必要とし、電源の監視(電圧、電流)を提供します。注意:AXP2101もバッテリ電圧を監視できます。

sensor:
 - platform: ina226
    i2c_id: bsp_bus
    address: 0x41
    shunt_resistance: 0.01 ohm
    max_current: 3.2A
    # adc time used for both, Bus Voltage and Shunt Voltage
    adc_time: 140us
    adc_averaging: 128
    update_interval: 60s
    current:
      name: "INA226 Current"
    power:
      name: "INA226 Power"
    bus_voltage:
      name: "INA226 Bus Voltage"
    shunt_voltage:
      name: "INA226 Shunt Voltage"

サーボ

このコンポーネントはUARTを必要とし、StackChanの左右および上下の頭部移動を提供します。

ftservo:
  - platform: scs9009
    address: 1
    id: x_servo
  - platform: scs9009
    address: 2
    id: y_servo 

number:
  - platform: ftservo
    ftservo_id: x_servo
    angle:
      id: servo_x_angle
      name: "Servo X Angle"
      min_value: -164
      max_value: 164
      use_raw_angle: false
      angle_offset: 164
      step: 5
    speed:
      id: servo_x_speed
      name: "Servo X Speed"
      min_value: 100
      max_value: 1500
      step: 100

  - platform: ftservo
    ftservo_id: y_servo
    angle:
      id: servo_y_angle
      name: "Servo Y Angle"
      min_value: 0
      max_value: 90
      use_raw_angle: false
      angle_offset: 239
      step: 5
    speed:
      id: servo_y_speed
      name: "Servo Y Speed"
      min_value: 100
      max_value: 1500
      step: 100

これらの角度はStackChanの可動範囲に合わせて調整されています。X 方向の動きは -165° から 165°、Y 方向の動きは から 90° に設定されています。ゼロは を意味します。

デフォルトステップ制御を使用する場合は、次を有効にします:

number:
  - platform: ftservo
    ftservo_id: x_servo
    position:
      id: servo_position
      name: "Servo X Position"
      min_value: 0
      max_value: 1024

デフォルトのステップ最小値は 0、最大値は 1024 です。速度スライダーを調整すると、各サーボの動作速度を steps/s 単位で制御できます。

サーボキャリブレーション

YAML 設定ファイルには 2 つの template ボタンがあります。


button:
  - platform: template
    name: "Servo Calibration"
    on_press:
      - lambda: |-
          ESP_LOGD("ftservo", "Start calibration");
          float x_zero = id(servo_x_position).state;
          float y_zero = id(servo_y_position).state;
          // assign offset
          float x_offset = x_zero / 2.844f;
          float y_offset = y_zero / 2.844f;
          // override default offset setting
          id(servo_x_angle)->set_angle_offset(static_cast<int>(x_offset));
          id(servo_y_angle)->set_angle_offset(static_cast<int>(y_offset));
          // indicating we are using calibration value
          id(use_calib_value) = true;
          id(x_servo_zero_step) = static_cast<int>(x_zero);
          id(y_servo_zero_step) = static_cast<int>(y_zero);
      - delay: 1s
      - lambda: |-
          ESP_LOGD("ftservo", "Preferences sync requested");
          global_preferences->sync(); // sync at once
          ESP_LOGD("ftservo", "Done reading and saving zero position, X zero: %d, Y zero %d", 
                  id(x_servo_zero_step), id(y_servo_zero_step));

  - platform: template
    name: "Clear Calibration"
    on_press:
      - lambda: |-
          ESP_LOGD("ftservo", "Restore to default settings");
          id(use_calib_value)   = false;
          id(x_servo_zero_step) = ${servo_x_angle_offset};
          id(y_servo_zero_step) = ${servo_y_angle_offset};
      - delay: 1s
      - lambda: |-
          ESP_LOGD("ftservo", "Preferences sync requested");
          global_preferences->sync(); // sync at once
          ESP_LOGD("ftservo", "Done clear calibration");

サーボ設定では、キャリブレーションデータを使用するためにいくつかのコンポーネントが必要です。

esphome:
    ...
    # Servo calibration data
    - priority: -100
      then:
        - lambda: |-
            if (id(use_calib_value)) {
              ESP_LOGD("boot", "Restoring calibration: X=%d, Y=%d",
                      id(x_servo_zero_step),
                      id(y_servo_zero_step));
              float x_offset = id(x_servo_zero_step) / 2.844f;
              float y_offset = id(y_servo_zero_step) / 2.844f;
              // override default offset setting
              id(servo_x_angle)->set_angle_offset(static_cast<int>(x_offset));
              id(servo_y_angle)->set_angle_offset(static_cast<int>(y_offset));
            } else {
              ESP_LOGD("boot", "No calibration data, using defaults.");
            }

  - platform: ftservo
    id: x_servo_sensor
    ftservo_id: x_servo
    position:
      id: servo_x_position
      name: "Servo X Position"
      filters:
        - delta: 3.0
      on_value:
        - lambda: |-
            if ( !id(use_calib_value) ) {
              float val = ${servo_x_position_to_angle};
              id(servo_x_angle).publish_state(roundf(val)); 
            } else {
              float x = id(servo_x_position).state;
              float zero = static_cast<float>(id(x_servo_zero_step));
              float val = (x - zero) * 0.3710f;
              id(servo_x_angle).publish_state(roundf(val));
            }


  - platform: ftservo
    id: y_servo_sensor
    ftservo_id: y_servo
    position:
      id: servo_y_position
      name: "Servo Y Position"
      filters:
        - delta: 3.0
      on_value:
        - lambda: |-
            if ( !id(use_calib_value) ) {
              float val = ${servo_y_position_to_angle};
              id(servo_y_angle).publish_state(roundf(val)); // using angle 
            } else {
              float x = id(servo_y_position).state;
              float zero = static_cast<float>(id(y_servo_zero_step));
              float val = (x - zero) * 90.0f / 260.0f;
              id(servo_y_angle).publish_state(roundf(val));
            }

StackChan を Home Assistant に接続した後、以下の手順でサーボキャリブレーションを行います。

  1. まず StackChan をゼロ位置まで動かします
  1. Servo Calibration ボタンを押します

  2. 1 秒ほど待って、データが ESP32 の NVS に書き込まれるのを待ちます(シリアルログを確認すると、NVS への書き込みに関するログメッセージが表示されます)

  1. デバイスを再起動し、Number スライダーをゆっくり動かして、キャリブレーション結果を確認します
警告
サーボを動かすときは必ず到達範囲を確認し、サーボの損傷を避けてください。

赤外線送信機

remote_transmitter:
  pin: GPIO5
  carrier_duty_percent: 50%
  non_blocking: true

赤外線コンポーネントはエアコンなどの赤外線環境制御機器の作成に使用できます。例:

climate:
  - platform: coolix
    name: "Media AC"
    visual:
      min_temperature: 18
      max_temperature: 30
      temperature_step: 1

静電容量タッチセンサー Si12T

このコンポーネントはI2Cを必要とし、StackChanの頭部をタッチすると text_sensor によって結果が取得できます。

si12t:
  id: touch_hub
  i2c_id: bsp_bus

text_sensor:
  - platform: si12t
    name: "Touch Sensor 1"
    channel: CH_1
    update_interval: 1s
  - platform: si12t
    name: "Touch Sensor 2"
    channel: CH_2    
    update_interval: 1s
  - platform: si12t
    name: "Touch Sensor 3"
    channel: CH_3
    update_interval: 1s

タッチ結果は HIGHMEDIUMLOW としてフロントエンドセンサーに報告され、それぞれ高、中、低の強度に対応します。No touch はタッチが検出されないことを意味します。

NFC ST25R3916 (WIP)

この機能はI2Cを必要とします。

RGBライトバー

この機能はM5IOE1ボード上の NeoPixel ドライバに依存しており、M5IOE1で有効にする必要があります:

light:
  - platform: m5ioe1
    id: stackchan_light_bar
    name: "StackChan Light Bar"
    icon: mdi:led-strip
    num_led: 12
    effects:
      - random:
          name: "Random"
          transition_length: 1s
          update_interval: 1s
      - addressable_rainbow:
      - addressable_rainbow:
          name: Rainbow Effect With Custom Values
          speed: 10
          width: 50
      - addressable_twinkle:
      - addressable_twinkle:
          name: Twinkle Effect With Custom Values
          twinkle_probability: 5%
          progress_interval: 4ms

また、BUSが5V 電源を供給する必要があります。BOOST ENBUS OUT EN スイッチを有効にする必要があります(これらのGPIOスイッチはAW9523B IOエキスパンダにあります):

switch:
  - platform: gpio
    name: "BOOST_EN"
    pin:
      aw9523b_id: aw9523b_hub
      number: 15
    restore_mode: RESTORE_DEFAULT_ON

  - platform: gpio
    name: "BUS_OUT_EN"
    pin:
      aw9523b_id: aw9523b_hub
      number: 1
    restore_mode: RESTORE_DEFAULT_ON

ライトエフェクトを有効にします:

赤外線受信機

remote_receiver:
  pin: GPIO10

制御対象が応答を返す場合、remote_receiver を使って受信および処理できます。

Page Tools
PDF
On This Page