Grove Speech Recognizer を obniz とつなげたメモ

この記事は Seeed UG Advent Calendar 2020 の 17 日目の記事です。Grove Speech Recognizer を obniz とつなげたメモです。

このように動きます

Grove Speech Recognizer は、このように「Hi cell」というウエイクワード(起動する言葉)が認識されてから、Go や Next などの予約語に入っているものを解釈してくれます。

元のソース

Arduino で動かす場合は簡単です。 こちら に書いてある以下のソースコードで動きます。

#include <SoftwareSerial.h>
 
#define SOFTSERIAL_RX_PIN  2
#define SOFTSERIAL_TX_PIN  3
 
SoftwareSerial softSerial(SOFTSERIAL_RX_PIN,SOFTSERIAL_TX_PIN);
 
const char *voiceBuffer[] =
{
    "Turn on the light",
    "Turn off the light",
    "Play music",
    "Pause",
    "Next",
    "Previous",
    "Up",
    "Down",
    "Turn on the TV",
    "Turn off the TV",
    "Increase temperature",
    "Decrease temperature",
    "What's the time",
    "Open the door",
    "Close the door",
    "Left",
    "Right",
    "Stop",
    "Start",
    "Mode 1",
    "Mode 2",
    "Go",
};
 
void setup()
{
    Serial.begin(9600);
    softSerial.begin(9600);
    softSerial.listen();
}
 
void loop()
{
    char cmd;
 
    if(softSerial.available())
    {
        cmd = softSerial.read();
        Serial.println(voiceBuffer[cmd - 1]);
    }
}

そんな中、私がハマったところと言えば、Grove Base Shield の場合に URAT 接続だからって UART のポートに挿したことです。

image

コードの通りで 、写真のように D2 ポートに挿しましょう。

Grove Speech Recognizer と obniz をつなぐ

image

千石電商さんで購入した Seeed Studio 110990210 Grove 4ピンコネクタ – ジャンパーピン変換ケーブル(5本入り) を使ってつなぎます。

Grove Speech Recognizer 側は素直に差し込んで obniz は、

  • 0番ピン 黒
    • GND
  • 1番ピン 赤
    • VCC
  • 2番ピン 白
  • 3番ピン 黄

と、つなぎます。

obniz で動かしたコード

以下のように読み替えて、動かしました。

<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <link
      rel="stylesheet"
      href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
    />
    <link rel="stylesheet" href="/css/starter-sample.css" />
    <script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
    <script
      src="https://unpkg.com/obniz@3.11.0/obniz.js"
      crossorigin="anonymous"
    ></script>
  </head>
  <body>
    <div id="obniz-debug"></div>

    <div class="wrap">
      <div class="speech">
        <h3 class="text-center">Grove Speech Recognizer!</h3>
      </div>
    </div>

    <script>
      var obniz = new Obniz("Obniz_ID");

      const voiceList = [
        "Turn on the light",
        "Turn off the light",
        "Play music",
        "Pause",
        "Next",
        "Previous",
        "Up",
        "Down",
        "Turn on the TV",
        "Turn off the TV",
        "Increase temperature",
        "Decrease temperature",
        "What's the time",
        "Open the door",
        "Close the door",
        "Left",
        "Right",
        "Stop",
        "Start",
        "Mode 1",
        "Mode 2",
        "Go"
      ];

      obniz.onconnect = async function() {
        obniz.display.clear();
        obniz.display.print("Hello");
        obniz.display.print("Grove Speech");
        obniz.display.print("Recognizer!");

        let uart = obniz.getFreeUart();
        uart.start({tx: 2, rx: 3, gnd:0, baud:9600, drive:"5v", pull:null});

        uart.onreceive = function(data, text) {
          console.log("data")
          console.log(data);
          let id = Number(data) - 1;
          console.log("id",id);
          let currentVoice = voiceList[id];
          console.log("currentVoice",currentVoice);
          obniz.display.clear();
          obniz.display.print("[currentVoice]");
          obniz.display.print("(-o-)<" + currentVoice);
        }
      };
    </script>
  </body>
</html>

シリアル接続は UART 接続で記述

シリアル接続は obniz の UART 接続のドキュメント を参考に書き換えました。

        let uart = obniz.getFreeUart();
        uart.start({tx: 2, rx: 3, gnd:0, baud:9600, drive:"5v", pull:null});

ただし、

#define SOFTSERIAL_RX_PIN  2
#define SOFTSERIAL_TX_PIN  3

にあるとおり Arduino のコードと RX と TX が逆なんです。

これは、接続する側、接続される側での見え方で変わる感じがするので、これでうまくいったから、これでいこうか?というニュアンスです。

認識するリスト はそのまま配列

voiceList は配列でOK。

      const voiceList = [
        "Turn on the light",
        "Turn off the light",
        "Play music",
        "Pause",
        "Next",
        "Previous",
        "Up",
        "Down",
        "Turn on the TV",
        "Turn off the TV",
        "Increase temperature",
        "Decrease temperature",
        "What's the time",
        "Open the door",
        "Close the door",
        "Left",
        "Right",
        "Stop",
        "Start",
        "Mode 1",
        "Mode 2",
        "Go"
      ];

認識された声のIDはこのように Buffer 型できます。

image

let id = Number(data) - 1; でやれば Number 型に変えてやれば配列から呼び出せます。

正しく Hi cell を認識させるのが大変だった

最初に(たまたま)成功している動画を見せしましたが、めっちゃ失敗してます。これは私の英語の発音がイケてない模様。

image

なぜかというと、Google 翻訳 で Hi cell. とスピーカーから喋らせるとうまくいきました。

こんな感じ。

海外の試した事例でもメッチャ苦しんでます。8分くらいのところ。

ちなみに私は cell の c の発音がうまくいってなかった

Google翻訳はマイクから音声を文字化してくれるので、これで自分の発音を確認しました。

image

3回 Hi cell と言ってるんですが、hi Siri あたりがいい感じでしたが、どうも Hi cell の cell がうまく認識出来ていない模様。あとは口をちゃんと開けて Hi をいうところも。こんな短いフレーズにも注意点があるのかと驚きましたが、これも練習。

sell と cell の発音の違いがほぼなさそうなので『あいうえおフォニックス』で s の発音をめっちゃがんばりました。

image

cell の前に s が言いやすい I see も織り交ぜつつ、めっちゃ練習しているところ。こわい。

image

Google 翻訳の利用した履歴も、たくさんでこわい。

image

うまくいくと、 Hi cell で赤いランプがついて。

image

Next や Go など命令の言葉がうまくいくと青いランプがついてめっちゃうれしかったです!