ESP32 および M5Stack で Google Home を自発的に喋らせる実験

M5Stack
Arduino core for the ESP32 stable 1.0.6 の場合、WiFiライブラリとボタンAの動作に不具合がありました。
ソースコードを修正しました。
@mongonta555さん、@mikasa231さんから教えて頂きました。
ありがとうございました。
m(_ _)m
(2021/07/24)

こんばんは。

今回はスゴイですよ。
といっても、かなり遅ればせながらの報告です。

M5Stack および ESP-WROOM-32 ( ESP32 ) を使って、好きな言葉をGoogle Home に「自発的に」喋らせる実験です。
自発的ということは、最初に呼び出すOK. Google」は不要ということです。

これがどんなにスゴイことかお判りでしょうか?

スポンサーリンク

このブログの読者の方はご存知だと思いますが、以前、以下の記事で ESP32 のセンサー値を Google Home に喋らせる実験をしました。

ESP32 単独で センサー値 を Google Home に喋らせる実験( Google Cloud Platform 設定編 )

ESP32 単独で センサー値 を Google Home に喋らせる実験( Dialogflow , Firebase , Actions on Google 設定編 )

これだけ苦労してクラウド環境を設定した挙句、テストバージョンの音声でしかセンサー値を Google Home に喋らせることができませんでした。
しかも、こちらから「OK. Google」と話しかけないとダメでした。
あまりにも複雑な設定のため、今でも見返すのが嫌になるくらいの記事です。

Google Home が発売された当初は、google-home-notifierというライブラリを使ってラズベリーパイを使えば自発的に喋らせることができたようです。
でも、これを ESP-WROOM-32 ( ESP32 )でやることはとっても難しかったんです。

しかし!!!

なんと、ESP32/ ESP8266 用の google-home-notifier ライブラリができていたのです!!!
これは、@hori__hiro さんが作成されたものです。
しかも、メッチャ簡単です!!!

というか、実は、Twitter で @hori__hiroさんから以前ご連絡いただいたのですが、私自身、M5Stack が発売されて以来、そのドライバ作りに時間を費やしていて、しばらく Google Home から遠ざかっていました。
ですから、長い間テストできずにいました。

そんな中、前回記事のような、BME680 のガスセンサ報知器を自作してみると、M5Stack のアラーム音よりも、日本語音声で異常を知らせてもらいたいと思うようになりました。

Twitter の M5Stack ユーザー界隈では、Aques Talk というものを使って、M5Stack 自身のスピーカーで喋らせることが流行っていますが、私のプログラミングの場合はメモリを多く消費しているので、できることなら、データをクラウドに投げて、喋るだけの専門動作は Google Home や Amazon Echo に任せたかったのです。

しかし、しかーし!!

@hori__hiro さんの esp8266-google-home-notifier を実際に試してみたら、クラウド環境など一切不要です。
あまりにも素晴らしかったので、これを使うことにしました。
これができれば、M5Stack を離れた場所に置いて、Google Home はパソコンデスクに置くということもできるので、正に IoT 報知器になります。

ということで、まずは、ESP32-DevKitC や M5Stack を使った以下の動画をご覧ください。

いかがでしょうか。

英語バージョンでも、日本語バージョンでも M5Stack のボタンスイッチで切り替えられるって凄くないですか?
しかも、「OK. Google」の呼びかけ無しです。
素晴らし過ぎますよね。

この google-home-notifier ってホントに不思議ですよね。
後述するソースコードを見てもらえれば分かるのですが、Wi-Fiアクセスポイントのパスワードと、Google Home デバイス名だけを設定すれば、自分の Google Home から音声を出せるんです。
いったい、どんな認証を行っているのか @hori__hiro さんに聞いたら、Google Home のデバイス名とローカル IP アドレスが分かれば接続できるとのこと。
私が以前、Dialogflow や Firebase でえらい苦労したのはいったい何だったのか・・・。

ラズベリーパイでは当たり前にできたことが、ついに ESP32 や M5Stack でできるようになったことは大きいです。

ということで、これの作り方をザッと説明したいと思います。
因みに、これは Arduino core for the ESP32 上で動作するものです。

使ったもの

Google Home

Google Home Mini については、私がレビューした記事がありますので参考にしてみて下さい。
Google Home Mini を使ってみた

M5Stack または ESP-WROOM-32 ( ESP32 )開発ボード

M5Stack または ESP-WROOM-32 開発ボードならば使用できます。

●M5Stack

M5Stack Basic
スイッチサイエンス
¥5,203(2021/09/09 23:54時点)

●ESP-WROOM-32 ( ESP32 )開発ボード
上記の動画では ESP32-DevKitC を使っています。

スイッチサイエンスさんの ESPr Developer 32 でも問題ありません。

ESPr Developer 32
スイッチサイエンス(Switch Science)
¥2,200(2021/09/09 23:54時点)

Wi-Fi ルーター環境

2.4GHz 帯のインターネットに接続された Wi-Fi ルーター環境が必要です。
M5Stack や ESP32 が接続できるように MAC アドレスフィルタリングやファイアウォール設定を事前に済ませておいてください。
ESP32 の MAC アドレスを調べる方法は以下の記事を参照してください。

ESP-WROOM-32 ( ESP32 ) チップ・メモリ・MACアドレス情報取得方法

その他、パソコン、USBケーブル等

Arduino core for the ESP32 のインストール

Arduino IDE は 1.8.5 で動作確認しています。

Arduino core for the ESP32 ( 以下 Arduino – ESP32 )は最新版を使って下さい。
インストール方法は以下の記事を参照してください。

Arduino core for the ESP32 のインストール方法

ESP32 / ESP8266 用 google-home-notifier インストール

google-home-notifierライブラリ正式名称は、

esp8266-google-home-notifier

となっていますが、現在は ESP32 にも対応しています。

このライブラリは、GitHub から ZIPファイルをダウンロードして Arduino IDE にインストールする方法ではなく、Arduino IDE のスケッチメニューの「ライブラリを管理」からインストールします。
詳細なインストール方法は、@hori__hiro さんの以下の記事を参照してください。

ESP8266 から Google Home に喋らせるライブラリ

その記事にも記載してあるとおり、esp8266-google-home-notifier ライブラリのインストールだけではなく、もう一つのライブラリをインストールする必要があります。
esp8266-google-tts ライブラリもインストールすることを忘れないでください

ESP32 用サンプルスケッチの入力

esp8266-google-home-notifier ライブラリのインストールが済んだら、下図の様に ESP32 用のサンプルスケッチを開きます。

このサンプルスケッチの ssid とpassword をご自分のWi-Fiルーターの環境に合わせて書き換えてください。
そして、スマホの Google Home アプリで、デバイス名を確認して、26行目あたりの

const char displayName[] = "Family Room";

Family Room のところを書き替えてください。
私の場合、漢字の場合は認証されないかも知れないと思い、
“test”
という名前にスマホ側で書き換えてしまいました。

コンパイル書き込み実行

ver 1.0.5 の場合は、以下のコンパイラの警告を「全て」にしてもコンパイルが通るようになりました。

以下は古いバージョンの場合です。
(2018/08/13)

 

コンパイルする前に、一つ注意点があります。
このままコンパイルしてもコンパイルエラーになる場合があります。

@hori__hiro さんがおっしゃっていたのですが、Arduino IDE の環境設定で、コンパイラの警告を「全て」にしているとエラーが出るようです。
その場合は下図の様に「なし」に変更してみてください。

私の場合、コンパイラの警告は「全て」にしておきたいので、ライブラリを少々修正させていただきました。
ただ、この修正方法が良いかどうか分かりませんので、GitHubのIssue に質問している最中です。
もしかしたら近々修正されるかも知れませんし、修正されないかも知れません。

ということで、設定が済んだら、コンパイル書き込み実行させてみてください。

ここで注意!!

私の場合はなぜか音声が出なくていろいろ試行錯誤していましたが、実は Google Home の音量設定がゼロになっていました。
その場合、

「OK. Google」
「音量を3にして」

というと、音量を上げてくれます。

最初に紹介した動画のように、
「Hello World」
と、Google Home から発声すればOKです。

29行目の

ghn.device(displayName, "en")

の “en” ところを、
“ja”
に替えれば日本語発音で発声してくれます。
素晴らし過ぎますね。

M5Stack のボタンで Google Home の音声を替えてみる

では、最初に紹介した動画にあるように、M5Stack のボタン操作で Google Home の音声を切り替えてみましょう。

今回は M5Stack 標準のライブラリを使ってみました。
本家 M5Stack の Arduino – ESP32 用ライブラリのインストール方法は以下の記事を参照してください。

M5Stack ライブラリインストール方法 ( Arduino IDE 用)

スケッチ入力

M5Stack ライブラリのインストールが済んだら、私の作った以下のサンプルスケッチを入力してみてください。

※Arduino core for the ESP32のバージョンがstable 1.0.6 の場合は、WiFiライブラリと、GPIO #39 に不具合があるようです。
esp8266-google-home-notifierライブラリはWiFiライブラリを使用しているので、ボタンAに不具合があります。
よって、以下のようにadc.hをインクルードして、adc_power_acquire関数を使って、ADコンバータ電源を常にONにしておく必要があるようです。
@mongonta555さん、@mikasa231さんから教えて頂きました。
ありがとうございました。
m(_ _)m
(2021/07/24時点)

 

【ソースコード】 (※無保証 ※PCの場合、ダブルクリックすればコード全体を選択できます)

#include <M5Stack.h> // 0.3.3
#include <esp8266-google-home-notifier.h> //v1.0.8
// esp8266-google-tts v1.1.0
#include <driver/adc.h> //Arduino core ESP32 stable 1.0.6

static const char* ssid = "xxxxxxxxx"; //ご自分のルーターのSSIDに書き換えてください
static const char* password = "xxxxxxxxx"; //ご自分のルーターのパスワードに書き換えてください

GoogleHomeNotifier ghn;
const char displayName[] = "test"; //スマホアプリで確認。Google Home のデバイス名

void setup(){
  M5.begin();
  adc_power_acquire(); //Arduino core ESP32 stable 1.0.6

  // Lcd display
  M5.Lcd.println("ESP32/ESP8266 google-home-notifier Test");
  M5.Lcd.println("Press the button A English.");
  M5.Lcd.println("Press the button B Japanese1.");
  M5.Lcd.println("Press the button C Japanese2.");

  Serial.println("");
  Serial.print("connecting to Wi-Fi");
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(250);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("connected.");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());  //Print the local IP
}

void loop() {
  if (M5.BtnA.wasReleased()) {
    googleHomeConnection( "en", "English. Button A pushed. Hello World" );
  } else if (M5.BtnB.wasReleased()) {
    googleHomeConnection( "ja", "日本語でーーーす。 ボタン B が押されました。Hello World" );
  } else if (M5.BtnC.wasReleased()) {
    googleHomeConnection( "ja", "ボタンCだよーーん。google home notifier、スゲーーー。" );
  }
  M5.update();
}

//****************************************
void googleHomeConnection( String lang_str1, String talk_str1 ){
  Serial.println("connecting to Google Home...");
  if (ghn.device( displayName, lang_str1.c_str() ) != true) {
    Serial.println(ghn.getLastError());
    return;
  }
  Serial.print("found Google Home(");
  Serial.print(ghn.getIPAddress());
  Serial.print(":");
  Serial.print(ghn.getPort());
  Serial.println(")");

  if (ghn.notify( talk_str1.c_str() ) != true) {
    Serial.println(ghn.getLastError());
    return;
  }
  Serial.println("Done.");
}

【ザッと解説】

●4行目:
Arduino core for the ESP32 のバージョンがstable 1.0.6 の場合、<adc.h>をインクルードして、14行目の adc_power_acquire関数を使えるようにします。

●6-7行目:
ご自分の Wi-Fi ルーターの SSID とパスワードに書き換えてください。

●14行目:
Arduino core for the ESP32 のバージョンがstable 1.0.6 の場合、WiFiライブラリとGPIO #39のボタンAが良からぬ動作するようなので、adc_power_acquire関数でADコンバータの電源を常時ONにしておくと良いようです。(@mikasa231さんによる情報)

●10行目:
ご自分の Google Home のデバイス名に書き換えてください。
日本語漢字は認識するかどうか分かりませんので、スマホの Google Home アプリのデバイス名を英語アルファベットに変更した方が良いかも知れません。

●39-43行;
“en” とすると、英語バージョン。
“ja” とすると日本語バージョン音声になります。

コンパイル書き込み実行

では、コンパイル書き込み実行させてみてください。

先に紹介した動画の様に、M5Stack のボタンを押せば、Google Home 音声が変わればOKです。
ボタンを押してから、少々時間がありますが、これくらいならば全然許容できますね。
とにかく、@hori__hiro さんに拍手を送りたいです。

すばらしい!!!

そして、ありがとうございます。
m(_ _)m

編集後記

いかがでしょうか。

再度申し上げますが、@hori__hiro さんに拍手!!!
パチパチパチ・・・!!!
感謝感謝!!!

今まで悪戦苦闘してきた自作デバイスと Google Home の連携が、グーンと楽になり、敷居が下がりました。

これはみなさん、ヤバイですよ!
改めて、良い時代が来たものです。

ということで、次回はこれを使って、BME680 の異常値を Google Home に喋らせたいと思います。

ではまた・・・。

Amazon.co.jp 当ブログのおすすめ

M5Stack Basic
スイッチサイエンス
¥5,203(2021/09/09 23:54時点)
ESPr Developer 32
スイッチサイエンス(Switch Science)
¥2,200(2021/09/09 23:54時点)
ZEROPLUS ロジックアナライザ LAP-C(16032)
ZEROPLUS
¥15,728(2021/09/09 23:54時点)
Excelでわかるディープラーニング超入門
技術評論社
¥2,068(2021/09/09 23:54時点)

コメント

  1. littlewat より:

    記事ありがとうございます!

    サンプルコードに関して一点。
    そのまま流すと私の環境では、google homeがしゃべりつづけることに…
    どうもwifiのモジュールとコンフリクトして、ButtonAが連打される現象が起きる模様です。

    なぜか下記コメントのようにdelay(10)をloopの最初に入れると解消しましたので共有いたします。

    https://github.com/m5stack/M5Stack/issues/52#issuecomment-387762337

    • mgo-tec mgo-tec より:

      littlewatさん

      記事をご覧いただき、ありがとうございます。
      この記事は随分古いもので、かなり環境が変わっていると思います。

      当方で確認した結果、同じ症状でした。
      Twitterでつぶやいてみたら、熟練の方々から有益な情報をいただきました。
      @mongonta555さん、@mikasa231さんから教えて頂きました。

      どうやら、Arduino core ESP32 stable 1.0.6 に問題ありのようです。
      WiFiライブラリとGPIO #39 のボタンAに不具合があるようです。
      よって、<driver/adc.h>をインクルードし、adc_power_acquire関数を使う必要がありました。
      それにより、メインループ内にdelay無くてもボタンは正常動作することを確認しました。

      記事内のソースコードも修正しましたので、改めて確認してみてください。
      因みに確認済みバージョンは以下です。

      Arduino core for the ESP32 stable 1.0.6
      M5Stackライブラリ 0.3.3
      esp8266-google-home-notifier v1.0.8
      esp8266-google-tts v1.1.0

タイトルとURLをコピーしました