Google Home と M5Stack と スマホ で双方向リアルタイム日本語通信する実験

M5Stack

M5Stack 用スケッチ(プログラム)を入力する

では M5Stack に以下のスケッチ(プログラム)を入力してみてください。

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

//ESP32_mgo_tec library beta ver 1.0.65
#define MGO_TEC_BV1_M5STACK_SD_SKETCH
#define MGO_TEC_ESP32_BV1_FIREBASERD_FONT_MAX 3
#include <mgo_tec_m5stack_firebase_sd.h>
#include <esp8266-google-home-notifier.h>

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

const char* utf8sjis_file = "/font/Utf8Sjis.tbl"; //UTF8 Shift_JIS 変換テーブルファイル名を記載しておく
const char* shino_full_font_file = "/font/shnmk16.bdf"; //オリジナル東雲全角フォントファイル
const char* shino_half_font_file = "/font/shnm8x16.bdf"; //半角フォントファイル名を定義

const char* host = "xxxxxxxx.firebaseio.com"; //自分のRealtime database URL
const char* firebase_auth = "xxxxxxxxxxxxxxxxxxxx"; //従来のデータベースシークレット
String user_path = F("test_user2"); //Realtime database のユーザー名

const uint8_t array_max = MGO_TEC_ESP32_BV1_FIREBASERD_FONT_MAX;

//-----NTP時刻文字表示系 引数初期化-----
int timezone = 9; //Tokyo
const char *ntp_server_name = "time.windows.com";
//-----WiFi 関連変数初期化-------------
uint32_t wifi_connect_last_time = 0;
boolean isConnected_wifi = false;
//-----Firebase 関連変数初期化-------------
boolean isEvent_scrolle[ array_max ] = {};
boolean isRequest_sse = false;
boolean isRequest_patch = false;
String field_message_str[ array_max ] = { "message0","message1","message2" };
String field_color_str[ array_max ] = { "color0","color1","color2" };
String field_speed_str[ array_max ] = { "speed0","speed1","speed2" };
String scrolle_message_str[ array_max ];
String color_str[ array_max ];
String speed_str[ array_max ];
//-----Google Home Notifier 関連変数初期化------
GoogleHomeNotifier ghn;
const char displayName[] = "test"; //スマホのGoogle Homeアプリのデバイス名
int googlehome_status = 0;

//***********セットアップ****************************
void setup() {
  delay(1000);
  Serial.begin(115200);

  mM5.init( utf8sjis_file, shino_half_font_file, shino_full_font_file );
  LCD.brightness( 255 ); //LCD LED Full brightness

  mM5.firebase.init( host, firebase_auth );
  mM5.firebase.font[0].y0 = 96;
  mM5.firebase.font[0].Xsize = 2, mM5.firebase.font[0].Ysize = 3;
  mM5.firebase.scl_set[0].interval = 0;
  mM5.firebase.font[0].htmlColorCode( "#00FFFF" );
  mM5.firebase.disp_fnt[0].initScrolle( mM5.firebase.font[0], mM5.firebase.scl_set[0] );

  mM5.firebase.font[1].y0 = 144;
  mM5.firebase.font[1].Xsize = 2, mM5.firebase.font[1].Ysize = 3;
  mM5.firebase.scl_set[1].interval = 0;
  mM5.firebase.font[1].htmlColorCode( "#FFFFFF" );
  mM5.firebase.disp_fnt[1].initScrolle( mM5.firebase.font[1], mM5.firebase.scl_set[1] );

  mM5.firebase.font[2].y0 = 192;
  mM5.firebase.font[2].Xsize = 2, mM5.firebase.font[2].Ysize = 3;
  mM5.firebase.scl_set[2].interval = 0;
  mM5.firebase.font[2].htmlColorCode( "#FFFFFF" );
  mM5.firebase.disp_fnt[2].initScrolle( mM5.firebase.font[2], mM5.firebase.scl_set[2] );
  mM5.msg.dispMsgWindow( 0, "WiFi Connecting..." );

  uint16_t x0 = 0, y0 = 40; //時計表示左端の座標
  uint8_t x_size = 3, y_size = 3;
  mM5.watch.colon1_font.htmlColorCode( "#00FF00" );
  mM5.watch.colon2_font.htmlColorCode( "#FF00FF" );
  mM5.watch.initNormal( x0, y0, x_size, y_size );

  WiFi_AP_Connect( 0 ); //初回 WiFi 接続時はゼロにする
  mM5.watch.getNTPserverSel( timezone, ntp_server_name, 18000 );
  mM5.msg.clearMsgWindow( 0 );
  setupMessageWindow();

  TaskHandle_t th; //マルチタスクハンドル定義
  xTaskCreatePinnedToCore(Task1, "Task1", 8192, NULL, 5, &th, 0); //マルチタスク起動
}
//***********メインループ****************************
void loop(){
  mM5.wifi_msg.dispWifiStatusMsgShort(); //WiFiステータス表示
  mM5.watch.ntp_msg.dispWebGetStatusMsgShort( mM5.watch.ntp_msg_status, "NTP" );
  mM5.firebase.sse_msg.dispWebGetStatusMsgShort( mM5.firebase.sse_status, "SSE" );
  mM5.firebase.patch_msg.dispWebGetStatusMsgShort( mM5.firebase.patch_status, "PATCH" );
  mM5.msg.dispWebGetStatusMsgShort( googlehome_status, "Ghome" );
  mM5.watch.dispNormalWatchCl(); //時計表示(コロン表示入り)
  //-------文字列スクロール表示---------------------
  for( int i = 0; i < array_max; i++ ){ //文字列を東雲フォントに変換
    if( isEvent_scrolle[ i ] == true ){
      mM5.firebase.disp_fnt[ i ].newSetText( mM5.firebase.scl_set[ i ], scrolle_message_str[ i ] );
      isEvent_scrolle[ i ] = false;
    }
  }
  mM5.firebase.disp_fnt[0].scrolleText( mM5.firebase.font[0], mM5.firebase.scl_set[0] );
  mM5.firebase.disp_fnt[1].scrolleText( mM5.firebase.font[1], mM5.firebase.scl_set[1] );
  mM5.firebase.disp_fnt[2].scrolleText( mM5.firebase.font[2], mM5.firebase.scl_set[2] );
}
//************ マルチタスクループ ******************
void Task1( void *pvParameters ) {
  while(1){
    int i;
    WiFi_AP_Connect( 180000 ); //3分毎に WiFi アクセスポイントチェック
    mM5.watch.getNTPserverSel( timezone, ntp_server_name, 300000 ); //5分毎にNTPサーバー時刻補正
    if( mM5.wifi_msg.WifiStatus == mM5.wifi_msg.WifiFailed ){
      for( i = 0; i < array_max; i++ ){
        scrolle_message_str[ i ] = "WiFi Access point not found.  ";
        isEvent_scrolle[ i ] = true;
        continue;
      }
    }
    if( isRequest_sse == true ){ //Firebaseへ Server-Sent Events(SSE) GETリクエスト
      mM5.firebase.sendGetRequestSSE( user_path );
      isRequest_sse = false;
    }
    String sse_str;
    String googlehome_str[ array_max ];
    boolean isEvent[ array_max ] = {}; //Firebase の各nodeのイベントが発生したかどうかのフラグ
    boolean isGooglehome_event[ array_max ] = {}; //Google Home notifier にメッセージを送るかどうかのフラグ
    boolean isDelete_event[ array_max ] = {}; //メッセージに消去と指令があったかどうかのフラグ

    //Firebase Realtime Database の変更があった場合、データ受信
    if( mM5.firebase.receiveSSEdataAll( sse_str ) == true ){
      for( i = 0; i < array_max; i++ ){
        isEvent[ i ] = mM5.firebase.pickUpStrToTargetStr( sse_str, field_message_str[ i ], scrolle_message_str[ i ] );
        //scrolle_message_str[ i ].replace( " ", "" ); //半角スペースを消去
        if( scrolle_message_str[ i ] == "消去" ) isDelete_event[ i ] = true;
        if( scrolle_message_str[ i ].length() == 0 ) isGooglehome_event[ i ] = false;
        else isGooglehome_event[ i ] = isEvent[ i ];
        scrolle_message_str[ i ] = scrolle_message_str[ i ] + " "; //文字スクロールを見やすくするため、全角スペースを追加。
        isEvent_scrolle[ i ] = isEvent[ i ]; //この位置でisEvent_scrolleをtrueにしないと意図した動作にならない。
      }
      //-------Color文字列抽出および変更-----------
      for( i = 0; i < array_max; i++ ){
        if( mM5.firebase.pickUpStrToTargetStr( sse_str, field_color_str[ i ], color_str[ i ] ) == true ){
          mM5.firebase.font[ i ].htmlColorCode( changeColorStr( color_str[ i ] ) );
          LCD.scrolleFontColorSet( mM5.firebase.font[ i ] );
        }
      }
      //-------Speed文字列抽出および変更-----------
      for( i = 0; i < array_max; i++ ){
        if( mM5.firebase.pickUpStrToTargetStr( sse_str, field_speed_str[ i ], speed_str[ i ] ) == true ){
          mM5.firebase.scl_set[ i ].interval = changeSpeed( speed_str[ i ] );
        }
      }
      //Google Home Notifier は送信に時間がかかるため、ディスプレイ表示させた後送信する
      if( isRequest_patch == false ){
        //Patchリクエストすると、全データのSSEが返って来てしまう。Google Home へ送信は避ける。
        for( i = 0; i < array_max; i++ ){
          if( isGooglehome_event[ i ] == true ){
            googlehome_str[ i ] = field_message_str[ i ] + "番、" + scrolle_message_str[ i ];
            googleHomeConnect( googlehome_str[ i ] );
            isGooglehome_event[ i ] = false;
          }
        }
      }else{
        isRequest_patch = false;
      }
      //Google Home送信の後に消去指令でmessageを消去
      for( i = 0; i < array_max; i++ ){
        if( isDelete_event[ i ] == true ){
          mM5.firebase.patchHTTPrequest( user_path, field_message_str[ i ], "" );
          isRequest_patch = true;
        }
      }
    }
    button_action();
    delay(1); //マルチタスクの場合、これ絶対必要!
  }
}
//*****スクロール速度変換**************************
int changeSpeed( String sp_str ){
  sp_str.replace( " ", "" ); //半角スペースを消去
  sp_str.replace( "%", "" ); //"%"を消去
  sp_str.replace( "パーセント", "" ); //"%"を消去
  sp_str.replace( "を", "" ); //"%"を消去
  if( sp_str == "アップ" || sp_str == "フル" || sp_str == "ファースト" ){
    return 0;
  }else if( sp_str == "ダウン" || sp_str == "スロー" ){
    return 30;
  }else{
    int int_speed = strtol( sp_str.c_str(), NULL, 10 ); //String文字列を数値に変換
    if( int_speed > 100 ) int_speed = 100;
    else if( int_speed < 0 ) int_speed = 0;
    return 100 - int_speed;
  }
}
//*****Color 文字変換**************************
String changeColorStr( String before_str ){
  String after_str;
  if( before_str == "白" ) after_str = "white";
  else if( before_str == "ホワイト" ) after_str = "white";
  else if( before_str == "赤" ) after_str = "red";
  else if( before_str == "レッド" ) after_str = "red";
  else if( before_str == "緑" ) after_str = "green";
  else if( before_str == "グリーン" ) after_str = "green";
  else if( before_str == "青" ) after_str = "blue";
  else if( before_str == "ブルー" ) after_str = "blue";
  else if( before_str == "黄色" ) after_str = "yellow";
  else if( before_str == "イエロー" ) after_str = "yellow";
  else if( before_str == "シアン" ) after_str = "cyan";
  else if( before_str == "水色" ) after_str = "cyan";
  else if( before_str == "スカイ ブルー" ) after_str = "cyan";
  else if( before_str == "マゼンタ" ) after_str = "magenta";
  else if( before_str == "紫" ) after_str = "magenta";
  else return before_str;
  return after_str;
}
//*****メッセージアイコン表示設定**************************
void setupMessageWindow(){
  //mM5.wifi_msg.m_size = 2; //pixel単位
  mM5.wifi_msg.m_x0 = 0;
  mM5.wifi_msg.m_txt_length = 6; //文字表示数(半角相当)
  mM5.watch.ntp_msg.m_x0 = 64;
  mM5.watch.ntp_msg.m_txt_length = 5; //文字表示数(半角相当)
  mM5.firebase.sse_msg.m_x0 = 120;
  mM5.firebase.sse_msg.m_txt_length = 5; //文字表示数(半角相当)
  mM5.firebase.patch_msg.m_x0 = 176;
  mM5.firebase.patch_msg.m_txt_length = 7; //文字表示数(半角相当)
  //google-home-notifier status用
  mM5.msg.m_x0 = 248;
  mM5.msg.m_txt_length = 7; //文字表示数(半角相当)
}
//***** google-home-notifier メッセージ送信**********
void googleHomeConnect( String talk_str ){
  googlehome_status = mM5.msg.Connecting;
  Serial.println("connecting to Google Home...");
  if (ghn.device(displayName, "ja") != true) {
    Serial.println(ghn.getLastError());
    googlehome_status = mM5.msg.ConnectFailed;
    return;
  }
  Serial.print("found Google Home(");
  Serial.print(ghn.getIPAddress());
  Serial.print(":");
  Serial.print(ghn.getPort());
  Serial.println(")");

  if ( ghn.notify( talk_str.c_str() ) != true ) {
    Serial.println(ghn.getLastError());
    googlehome_status = mM5.msg.ConnectFailed;
    return;
  }
  Serial.println("Done.");
  googlehome_status = mM5.msg.ConnectOK;
}
//*******WiFiアクセスポイント接続*************
void WiFi_AP_Connect( uint32_t reconnect_time ){
  if( millis() - wifi_connect_last_time > reconnect_time ){
    //WiFiアクセスポイントチェック用
    wifi_connect_last_time = millis();
    Serial.printf( "\r\nWiFi.status = %d\r\n", WiFi.status() );
    if( WiFi.status() != WL_CONNECTED ) isConnected_wifi = false;
    if( isConnected_wifi == true ) return;
  }else return;

  uint32_t time_out = millis();
  if( isConnected_wifi == false ){
    mM5.wifi_msg.WifiStatus = mM5.wifi_msg.WifiConnecting; //WiFiメッセージウィンドウ設定
    Serial.println( F("\r\nConnecting Wifi...") );
    Serial.println( ssid );
    Serial.printf( "\r\nWiFi.status = %d\r\n", WiFi.status() );
    //WiFiが急に接続できなくなった場合の応急処置
    WiFi.disconnect( true, true ); //WiFi OFF = true, eraseAP = true
    delay(1000);
    WiFi.begin( ssid, password ); //常時 WiFi ON の場合、ここをコメントアウト
    while ( WiFi.status() != WL_CONNECTED ) {
      delay(500);
      Serial.print(".");
      if( millis() - time_out > 30000 ) break; //Time OUT
    }
    //マルチタスクでメッセージウィンドウを正しく表示させるための処置
    if( millis() - time_out < 1000 ) delay(2000);
  }

  Serial.printf( "\r\nWiFi.status = %d\r\n", WiFi.status() );
  if( WiFi.status() == WL_CONNECTED ){
    Serial.println("");
    Serial.println( "WiFi connected" );
    Serial.println( "IP address: " );
    Serial.println( WiFi.localIP() );
    mM5.wifi_msg.WifiStatus = mM5.wifi_msg.WifiConnected; //WiFiメッセージアイコン設定
    isConnected_wifi = true;
    isRequest_sse = true;
    mM5.watch.m_isNtp_first_get = true;
  }else{
    mM5.wifi_msg.WifiStatus = mM5.wifi_msg.WifiFailed; //WiFiメッセージアイコン設定
    Serial.println( F("WiFi AP Not Found") );
    isConnected_wifi = false;
  }
  wifi_connect_last_time = millis();
}
//****************************************
void button_action(){
  mM5.btnA.buttonAction();
  switch( mM5.btnA.ButtonStatus ){
    case mM5.btnA.MomentPress:
      Serial.println("Button A Moment Press");
      mM5.firebase.patchHTTPrequest( user_path, field_message_str[ 0 ], "OK !" );
      googleHomeConnect( "メッセージ 0番 OK !" );
      isRequest_patch = true;
      break;
    case mM5.btnA.ContPress:
      Serial.println("-------------Button A Cont Press");
      mM5.firebase.patchHTTPrequest( user_path, field_message_str[ 0 ], "消去" );
      googleHomeConnect( "メッセージ 0番 消去しました" );
      isRequest_patch = true;
      break;
    default:
      break;
  }

  mM5.btnB.buttonAction();
  switch( mM5.btnB.ButtonStatus ){
    case mM5.btnB.MomentPress:
      Serial.println("Button B Moment Press");
      mM5.firebase.patchHTTPrequest( user_path, field_message_str[ 1 ], "やだね!" );
      googleHomeConnect( "メッセージ 1番 やだね!" );
      isRequest_patch = true;
      break;
    case mM5.btnB.ContPress:
      Serial.println("-------------Button B Cont Press");
      mM5.firebase.patchHTTPrequest( user_path, field_message_str[ 1 ], "消去" );
      googleHomeConnect( "メッセージ 1番 消去しました" );
      isRequest_patch = true;
      break;
    default:
      break;
  }

  mM5.btnC.buttonAction();
  switch( mM5.btnC.ButtonStatus ){
    case mM5.btnC.MomentPress:
      Serial.println("Button C Moment Press");
      mM5.firebase.patchHTTPrequest( user_path, field_message_str[ 2 ], "わかったよ~ん!" );
      googleHomeConnect( "メッセージ 2番 わかったよ~ん!" );
      isRequest_patch = true;
      break;
    case mM5.btnC.ContPress:
      Serial.println("-------------Button C Cont Press");
      mM5.firebase.patchHTTPrequest( user_path, field_message_str[ 2 ], "消去" );
      googleHomeConnect( "メッセージ 2番 消去しました" );
      isRequest_patch = true;
      break;
    default:
      break;
  }
}

【簡単な解説】

以前のこちらの記事以降、ライブラリをかなり修正し、HTML カラーコードも関数に直に入力できるようになり、Firebase 関連のスケッチ(プログラミング)はかなり簡単に構成できるようになったと思います。

●2行:
MGO_TEC_BV1_M5STACK_SD_SKETCH という定義は必ず入れてください。

●3行:
MGO_TEC_ESP32_BV1_FIREBASERD_FONT_MAX に数値を定義すると、プリプロセッサで以下のクラスオブジェクトの配列要素数を決めることができます。
mM5.firebase.font
mM5.firebase.scl_set
mM5.firebase.disp_fnt
mM5.firebase.msg
何とかして、クラス内に定義した別クラスのオブジェクト要素数をスケッチソースコード内で定義して簡単にできないかと、いろいろ試行錯誤した結果、私なりにたどり着いた方法です。
これが最適かどうかは分かりません。

●7-8行:
ここで、ご自分のルーターの SSID とパスワードに書き換えてください。

●11行:
時計表示をカスタムフォントにしたい場合は、ここでご自分のフォントファイル名に変更してください。

●14-16行:
ご自分の Firebase Realtime database のURLやデータベースシークレット、ユーザー階層名に書き換えてください。
※UIDと間違えないように気を付けてください

●18行:
ここは、ただ単に配列要素名が長いので、短い変数名に置き換えただけです。

●38行:
ここで、スマホの Google Home アプリで設定した、ご自分の Google Home のデバイス名に書き換えてください

●73行:
時計表示をスクロール時計ではなく、標準の時計表示にする場合、この関数で初期化します。
スクロール時計は Firebase 文字列スクロールが多いのでその為に表示が崩れてしまう為に使えません。

●84-101行:
ESP32 マルチタスクの CPU core 1 メインループです。
M5Stack の LCD 表示関連は、同じ core 1 の setup 関数内で初期化したので、同じ core のこのメインループにまとめています。

●103-173行:
ESP32 マルチタスクの CPU core 0 のタスクループです。
ここでは、Web とのコネクション関連のタスクをまとめています。
これによって、文字列スクロールを止めずに Web にアクセスできます。
Firebase Realtime database にアクセスして、返って来る文字列を抽出したりしています。
また、今回のボタン操作は、Web コネクションに限定されているので、170行のボタン操作関数もここに置いています。

●251-295行:
WiFi ルーターおよびアクセスポイントの接続や、アクセスポイントが無くなった場合、定期的に再接続する関数です。
今回は、私なりに試行錯誤して、途中でルーターを切ったりしても、ガッツリ再接続できるように改良しました。
ちょっとハマったのは、アクセスポイントが復活したら、WiFi.beginしていなくても
WiFi.status() = WL_CONNECTED
となってしまうところです。
UDP の NTP サーバーとも接続してしまうのは、謎でした。
でも、それが分かってしまえば、それ用の対処をするだけです。
これで、しばらくは WiFi アクセスポイントの再接続に困らないと思っています。
ただ、Arduino – ESP32 が更新されてしまったらどうなるか分かりません。

コンパイル書き込み実行

では、Arduino IDE でコンパイル書き込み実行してみてください。
最初に紹介した動画のように動作すればOKです。

M5Stack のボタンスイッチを瞬時押しすると reply(返事)メッセージを送ります。

長押しすると、メッセージを消去します。

では、次ではスマホのブラウザで表示させる HTML および JavaScript のプログラミングを紹介します。

コメント

  1. juchang より:

    mgo-tec 様

    「凄い!」の一言では済まされない私の何十倍もご苦労をされた事と思います。
    どうにか動作確認させていただきました。
    初心者のトラブルであまり参考になりませんが成功までの経緯を報告させていただきます。
    1. コンパイルエラー
     ESP8266-google-tts ライブラリーのインストール忘れによりコンパイルエラーとなる。
    2. 15行目、データベースシークレットの入力ミス
     auth.uid と勘違いして入力したためデータ転送ができない。
    3. 38行目、const char displayName = ” デバイス名 ” を見落とし
     Google Home との接続ができない。
    後は、テキスト通りの入力で動作OKです。
    これからも素晴らしい作品の発表をお待ちしております。

    • mgo-tec mgo-tec より:

      juchangさん

      いつも動作させていただき、本当に感謝しております。

      そうなんです!
      これは、パッと見た目は地味ですが、実は凄いんです!!!
      凄いんですけど、Twitter での評判はイマイチでした。
      これの凄さは、実際に自分で動作させてみて分かるんです。
      その点、juchangさんに試していただいて、ホントに嬉しいですね。
      (^^)
      これを応用すれば、とんでもないことができそうですよね!

      ところで、コンパイルエラーやデータベースシークレット、Google Home のデバイス名などは、スルーしてしまう人がいると思います。
      記事を修正して、強調表示しておきたいと思います。

      ご指摘ありがとうございました。
      今後とも、よろしくお願いいたします。
      m(_ _)m

      • mgo-tec mgo-tec より:

        juchangさん

        写真を投稿いただき、ありがとうございます。
        バッチリですね。
        ケースがコンパクトになっていて Good ! です。
        これなら、M5Stack 要らずですね。
        こんな風に作っていただけるとは、メチャメチャ光栄です。
        皆さんに見て頂くために、このコメント欄に貼らせていただきますね!
        (^^)
        jcg_googlehome_firebase_m5stack01.jpg

        • juchang より:

          mgo-tec 様

          早速掲載いただきありがとうございます。

          「 よく解りません 」「 お役に立てそうにありません 」
          我が家の Google Home はなかなか相手にしてくれません。
          メッセージ1番が一番繋がるように感じるのですが気のせいでしょうか。
          「 サンキューベリマッチ 」と発声すると、アルファベットが表示され、「 サンクスベリマッチ 」と応えてくれます。
          秋の夜長、なかなか寝付けそうにありません。

          • mgo-tec mgo-tec より:

            juchangさん

            こちらこそ、いろいろありがとうございます。

            Google Home は IFTTT を使うと認識率が下がります。
            ご存知だと思いますが、Dialogflow を使うと格段に認識し易くなりますが、設定がとても面倒で、テストモードでしかできません。
            IFTTT は設定が「簡単」ですから、結局は「IFTTT でいいや」っていう感じですね。
            IFTTT の使い方のポイントは、IFTTT が認識し易いようなフレーズにご自分で設定するしかありません。
            例えば、
            「M5Stack メッセージ1スピード50」
            という設定にしても認識してくれません。
            最初の単語フレーズに、世間的によく使われる単語にするところがポイントです。
            Dialogflow では M5Stack は認識してくれますが、IFTTT はダメでした。
            また、最初に「メッセージ」が入ると、カラーなのかスピードなのかを認識する時間がかかって、認識できなくなるようです。
            ですから、
            「スピード1番50パーセント」
            というように工夫して IFTTT が認識してくれるように設定しなければなりません。
            ご自分が Google Home に喋る「喋り方」もいろいろ工夫しなければならないところが、ちょっと面倒です。

            そして、IFTTT の欠点として、Applet を修正すると、5~10分は反映されませんので、気長に待つことです。
            待てなければ、Applet を削除して、新たに作り直すと時間が短縮されます。

            また、私も「メッセージ1番」が一番よく繋がりますが、カラーが認識しない場合、「色」というフレーズ Applet も作って置くと良いかもしれません。
            いずれにしても、IFTTT は簡単ですが認識悪いということで割り切るしかありませんね。

  2. マッキー より:

    お世話になります。
    動作はほぼ動作してるのですが、2,3うまくいきません。
    1 color1番 赤と言うとメッセージ1番に「赤」と入り、redと変換して  くれない。メッセージとスピードは所望の動作しております。
    2 9841でそっくりさんを作ったのですがボタンABCが押されたままとなります。もちろん
    const uint8_t buttonA_GPIO = 35;
    const uint8_t buttonB_GPIO = 34;
    const uint8_t buttonC_GPIO = 25;
    宣言してもダメです。ソースコードでは記述がないのでたぶんM5stackの
    ライブラリーでやっておられると思いますが、9841で動作できる改善方法を教えてください。

    • mgo-tec mgo-tec より:

      マッキーさん

      いつもブログご覧いただき、そして試していただき、ありがとうございます。
      ところで、9841 とはいったいどのボードでしょうか?
      おそらく、ILI9341 ボードのことだろうと思いますので、それでお話を進めさせていただきます。

      まず、1番の回答:
      記事の文章でも注意事項として書いてありますが、IFTTT の Applets を入力する時に、自動的に半角スペースが入力されてしまう場合があるので、Applets の Body 部分に半角スペースが入っていないか再度確認してみてください。
      そして、シリアルモニタをみて、しゃべった単語が以下のように、半角スペースが一切無く変換されているか確認してみてください。

      data: {"path":"/","data":{"color1":"赤"}}
      

      私の場合は、赤の前に半角スペースがあって、検知してくれないことがありました。
      その場合は、たいてい、IFTTT の Applets の Body に半角スペースが入っています。
      あとは、color と 1 の間にスペースが入っていて、color1 フィールドにメッセージが入らないことが考えられます。

      その他、Google 192-211行で、Firebase に入力された単語とif文で条件分けする単語が合っているか、再確認してください。
      半角スペースが入っている場合はそれを含めて見直してみて下さい。
      Google Home からは、単語ごとに半角スペースが入って来ますので、そこも注目しておくと良いと思います。
      Firebase の「赤」が入っているのに、[red]と変換してくれないのは、半角スペースが原因の可能性があります。

      2番の回答:
      申し訳ございませんが、ここの記事では M5Stack で使うこと限定で書いています。
      別途 ILI9341 ボードを使う方用にはプログラムを組んでおりません。
      ライブラリも M5Stack 用です。
      ですから、ILI9341 ボードで組みたい場合は、以下の記事
      https://www.mgo-tec.com/blog-entry-select-box-news-m5stack-esp32.html/5#title11-4
      のサンプルスケッチを参考にして組んでください。
      当記事のサンプルスケッチにこの記事の4-16行を追加し、46-47行をこの記事の60-69行(65行は不要)に挿し替えれば動くかもしれません。
      そして、ボタンが押されているということは、GPIO入力が常時 GND レベルになっているということですので、回路に問題があるかもしれません。
      テスターで測りながら、ボタンが押されていない時の GPIO 入力は 3.3V。
      ボタンが押されたときのGPIO入力が 0V になっているか確認してみてください。
      それぞれのボタンが独立して電圧レベルが変化していることが重要です。
      どこかのボタンが押されたら、他のボタンの GPIO 入力が変わってしまう場合は、回路が間違えているということです。

      とりあえず、これでもう一度ご確認ください。

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