Google Home と ESP32 で、音声をテキスト表示させた WiFi 電光掲示板を作ってみた

ESP32 ( ESP-WROOM-32 )

Arduino – ESP32 の設定、および SPIFFSプラグインのインストール等

Arduino core for ESP32 は最新版をインストールしておいてください。

※2018/01/18頃更新された、GitHub の Arduino core for ESP32 のインストールはしない方が賢明です。
SPIFFSファイルシステムが上手く動作してくれません。
2017/12/19 バージョンは正常動作しています。

Arduino IDE は 1.8.5 で動作確認しています。
インストール方法は以下の記事を参照してください。

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

また、ESP-WROOM-32 の SPIFFS ファイルシステムを使用しますので、以下の設定を事前に済ませておいてください。

●SPIFFSアップローダープラグインのインストール
ESP-WROOM-32 ( ESP32 ) SPIFFS アップローダープラグインの使い方

●SPIFFS メモリサイズアップする
ESP-WROOM-32 ( ESP32 ) SPIFFS メモリサイズを大きくする方法

フォントファイル等を SPIFFS フラッシュへアップロードしておく

16×16 pixel フリーの日本語東雲フォントと、UTF8→Shift_JIS コード変換テーブルファイルが必要です。
それを SPIFFS アップローダープラグインを使用して、ESP-WROOM-32 のフラッシュへアップロードしておいてください。
ただし、要注意点があります。
今回は前回の記事と同様に、/font/フォルダ下でアップロードしてください
最後の方の Arduino IDE スケッチのファイル指定でそうしています。
ルート下にアップロードしても良いのですが、今後は当ブログでも/font/フォルダ下に統一していこうと思っています。

東雲フォントをアップロードするためには、SPIFFSメモリサイズアップ方法を参照して、サイズを大きくしておく必要があります。

東雲フォントについては当ブログで何度も紹介しています。
以下の記事を参照してください。
ダウンロード先も以下の記事にあります。

ESP32 で 日本語漢字フォント をカラー OLED に表示させ、4行同時スクロール

必要なファイルは以下の3つです。
これをパソコンで /font/フォルダを作成して、その中に以下の3つのファイルを入れてアップロードします。

●Utf8Sjis.tbl
●shnmk16.bdf
●shnm8x16.bdf (※ファイル名の最後の ”r” を削除したもの)

自作ライブラリのインストール

私が自作した、Arduino – ESP32 用ライブラリを使います。
以前の記事でも紹介したものを使いますが、今回は少々修正したので、最新版をインストールしておいてください。
このライブラリについては、以下の記事も合わせて参照してみてください。

ESP32 で I2C OLED SSD1306 に東雲フォントを4倍角で表示させてみた

バージョンアップしていますので、古いライブラリは必ずフォルダごと削除してからインストールしてください

GitHubからダウンロードした ZIPファイルを Arduino IDE に直接インストールする方法は以下の記事を参照してください。

GitHubにある ZIP形式ライブラリ のインストール方法 ( Arduino IDE )

ライブラリは以下のリンクにあります。

ESP32_I2C_SSD1306 ライブラリ

今回バージョンアップして、Beta 1.10 になっています。
以前の記事のバージョンに加えて、文字サイズを縦と横で別々に設定できるようにしました。
とても読みやすくできると思います。

https://github.com/mgo-tec/ESP32_I2C_SSD1306

ESP32_SPIFFS_ShinonomeFNT ライブラリ

今回またバージョンアップして、Beta 1.32 になっています。
軽微な修正をしました。

https://github.com/mgo-tec/ESP32_SPIFFS_ShinonomeFNT

ESP32_SPIFFS_UTF8toSJIS

これは前回の記事と同じバージョンで、Beta 1.2 です。

https://github.com/mgo-tec/ESP32_SPIFFS_UTF8toSJIS

Google Cloud Platform , Dialogflow , Firebase , Actions on Google を使えるようにしておく

要するに、Google Home の開発環境です。
テストバージョンでしか開発が出来ませんが、私的にはテストバージョンで十分です。

初めの方には、これの設定が一番大変!
敷居が高いかも知れません。
でも、最初の設定だけが大変で、一度設定しておけばそれほど面倒な作業も無く進めることができます。
以下の記事を参照して、事前に開発ができる状態にしておいてください。

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

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

Firebase のユーザーを追加して UID を発行して、アクセスルールを設定しておく

これは無くても良いのですが、セキュリティを高めるためと、今後の拡張用として、予め設定しておきます。
設定方法は以下の記事の最後の方に新たに追記しておいたので、参照してみてください。
以下の記事の29番と30番を実行して、UID発行と、アクセスルールを設定しておいてください。

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

これを設定しておくと、少しだけセキュリティを少しだけ高めることができます。
ただし、後で説明する index.js では admin アクセスで書いているので、UID の効果は薄いです。
Firebase の index.js の Authorization は、私はまだ良く分からないので勉強中です。

Google Cloud Functions の index.js の作成

Google Cloud Shell のコードエディタで作成した Cloud Functions の index.js は以下の通りです。
因みに無保証ですのでご了承ください。

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

'use strict';

process.env.DEBUG = 'actions-on-google:*';
const App = require('actions-on-google').DialogflowApp;
const functions = require('firebase-functions');
const admin = require('firebase-admin');

admin.initializeApp(functions.config().firebase);

var db = admin.database();

const user_id = "xxxxxxxxxxxxxxxxxx"; //Your User ID ( UID )
var ref1 = db.ref("/" + user_id);

const MESSAGE_ACTION = 'message_intent';

//*******Realtime Database HTTP GET request ****************
exports.FirebaseGetRequest = functions.https.onRequest((req, res) => {
  const Uid = req.query.UUID;
  const Req_message = req.query.Request;

  if(Uid === user_id){
    if(Req_message === "message1"){
      ref1.on("value", function(snapshot) {
        var newPost1 = snapshot.val();
        var header = {"Access-Control-Allow-Origin":"*",
                      "Pragma": "no-cache",
                      "Cache-Control" : "no-cache"};

        res.writeHead(200, header);
        res.write(newPost1.message1);
        res.end();
      }, function (errorObject) {
        console.log("The read failed: " + errorObject.code);
        res.redirect(404, 'The read failed:');
      });
    }
  }else{
   console.log('user_id Error!');
   res.redirect(404, 'error');
  }
});

//*******Dialogflow Request & Response****************
exports.GoogleHome_Dialogflow_Action = functions.https.onRequest((request, response) => {
  const app = new App({request, response});

  console.log('Request headers: ' + JSON.stringify(request.headers));
  console.log('Request body: ' + JSON.stringify(request.body));

  function messageAction (){
    let reqBody = JSON.stringify(request.body.result.parameters.any);

    ref1.set({
      message1: reqBody
    });
    console.log('Database Set Succesful!' + reqBody);
    response.end();
  }

  let actionMap = new Map();
  actionMap.set(MESSAGE_ACTION, messageAction);
  app.handleRequest(actionMap);
});

【解説】

●6-8行目:
ここで、Firebase へのアクセスは Admin と設定してしまっているので、このコード内で記述している Cloud Functions 関数にはだれでもアクセスできてしまいます。
そこで、UID で簡易的にアクセス制限をかけてしまおうというわけです。
それは後述します。

●12行目:
ここで、先ほど設定したUID に書き換えてください。

●15行目:
ここでは、Dialogflow の Intent の Action 欄と同じ名前にしてください。

●18-42行:
これは、ESP32 から GETリクエストされた場合に処理する関数です。
FirebaseGetRequest が ESP32 から呼ぶ Cloud関数です。
ここはご自分の好きな名前にしてください。
19行および20行で、ESP32 からリクエストされた文字列を抽出します。
そして、22行で UID を判別するので、ここでアクセス制限がかけられます。
あくまで簡易的な制限です。
今後、ちゃんとした Authorization方法が分かったら、このブログで紹介していきたいと思います。
そして、23行目では、ESP32 からリクエストされてきた”message1”という文字列を判別しています。

●24-36行:
ref1.on関数の snapshot で、Firebase Realtime Detabase を参照しています。
Firebase へは Dialogflow によって、このように記録されています。

30行でHTTPレスポンスヘッダを ESP32へ返し、31行で参照したデータベーステキストを ESP32 に送信しています。

●45-64行:
Dialogflow から送信されてきたメッセージを抽出して、Firebase へ格納します。
45行の GoogleHome_Dialogflow_Action という名前が Cloud 関数で、Dialogflow の Fulfillment の URL に入力するアドレスと同じ名前です。
Google Home から「メッセージをどうぞ」と言われた後、こちらが喋った言葉が全てテキスト変換されて格納されます。
そこから必要な文字列を抽出するのが 52行です。
そして、Firebase に書き込むのが 54-56行です。

次のページでは、Deploy や Dialogflow を説明します。

コメント

  1. juchang より:

    mgo-tec 様

    大変お世話になっております。
    「センサー値を Google Home に喋らせる実験」を何とかクリアさせて頂き、早速、「音声をテキスト表示させた WiFi 電光掲示板を作ってみた」に挑戦をしております。
    今回テキストには、index.js のみ記載されていますが、package.json はどのように入力したらよろしいでしょうか。
    又、Firebase Realtime Detabase の設定について、もう少し詳しくご説明いただけると幸いです。
    よろしくお願い致します。

  2. juchang より:

    mgo-tec 様

    またまた単純ミスを犯してしまいました。
    Dialogflow の Fulfiliment の URL 欄で、GoogleHome_Dialogflow_Action と入力するのを忘れていました。
    それを修正するとテキスト表示が出るようになりました。
    Database の表示はできていませんが、いろいろ調べながら解決していきたいと思います。
    毎度お騒がせしまして申し訳ありません。
    今後ともご指導の程よろしくお願い致します。

    • mgo-tec mgo-tec より:

      juchangさん

      これからは出来るだけご自分のコードを見直してからご質問していただくようお願いいたします。
      でも、動いて良かったです。

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