AIYスピーカーで電子工作~5つのLEDライトを音声認識

前回の記事では、Google AIY Voice kitの音声認識で、2つのLEDライトを点滅させてみました。

Google AIY スピーカーの音声認識で電子工作!~2つのLEDを光らせる
今回の目標は、ブレッドボードにLEDライトを2つ配置して、Google AIYスピーカーの音声認識で、ライトをコントロールするということです。

今回は、LEDライトを5つに増やしてみました、というお話です。

もともとは、AIYスピーカーでLEDライトを点滅させた以下の記事を応用させています。音声認識を行なうためには、Google Cloud Speech APIへの登録をお忘れなく。

日本語化その2.ブレッドボード&LEDライト【Google AIY Voice Kit】
今回は、ブレッドボードに接続したLEDライトでも日本語の音声コマンドでライトを付けたり、消したりできるようにします。ついでに、「さようなら」でプログラムが終了するコマンド、「チカチカ」でLEDライトが点滅するコマンドも加えました。



5つのライトを音声認識で光らせる

今回は5つのLEDライトを使用して、音声認識で特定のLEDライトを光らせたり、順番にピカピカさせます。

ベースになったのは、クジラ飛行机さんの「やさしくはじめるラズベリーパイ」の本の第3章の94ページで、LEDや抵抗の配線等はそちらを参考にしています。

また、音声認識の箇所については、MagPiの冊子のLEDを光らせるプログラム(57ページ、電子版はこちら)を参考にしています。

まずは配線

今回、使用した材料は以下の通り。

  • ブレッドボード 1つ
  • 赤色LEDライト 5つ
  • 330Ωのカーボン抵抗器 5つ
  • ジャンパワイヤ オスーオス 11つ
  • ジャンパワイヤ オスーメス 6つ

これらは以前、秋月電子通商さんで購入したものです(^-^)。

まずは、LEDライト5つと抵抗をブレッドボードに挿して、ジャンパワイヤをAIYスピーカーのVoice Hatに挿します。

今回は、5つのポートとGNDポートにワイヤを挿す必要があるので、ちょっと面倒です。特にジャンパワイヤは、ダンボール箱内に到達させるために、前回同様オス・オスのワイヤをオス・メスのワイヤで延長させています。なので、使用しているジャンパワイヤの数が異様に多くなっています。

ですが、Voice Hatの穴に挿しても、固定されていないので、ちょっとした拍子にピョンっと穴から飛び出してしまいます

せっかく5本のワイヤを挿して、あと1本…のはずなのに、最後のワイヤを挿したら、前に挿したのがいくつも飛び出してきて、ムギャーってなります。

このように、ラズパイがダンボール箱に入った状態で配線を挿していくのは、何気にストレスになります。が、気合で何とか乗り越えました。

配線されたVoice Hatはこんな状態です。

いざ、プログラム作成

写経で試す

さて、ブレッドボードへの配線が完了したら、プログラムの作成に入ります。

まずは、音声認識なしで、5つのLEDが順番にチカチカするのが成功するか確かめるために、「やさしくはじめるラズベリーパイ」の95-96ページのプログラムを写経して、そのまんま実行してみます。

うん、今度はきちんと光ってくれました(LEDが急に光らなくなったトラブル編の記事はこちら(T_T))。

音声認識に挑戦

お次は、音声認識のプログラム作成に入ります。

今回は、importの場所は、前回のLEDが2つのときと特に変わりません。

def main()のところは、今回使用する日本語のフレーズを入れておきます。

def main():
    recognizer = aiy.cloudspeech.get_recognizer()
    recognizer.expect_phrase('親指')
    recognizer.expect_phrase('人差し指')
    recognizer.expect_phrase('中指')
    recognizer.expect_phrase('薬指')
    recognizer.expect_phrase('小指')
    recognizer.expect_phrase('ピカピカ')
    recognizer.expect_phrase('さよなら')

いきなり「親指」「人差し指」…ってなんだよ、って感じですよね(^_^;)。

最初は、「1番、2番、3番…」と番号で指定して、1番、と話したら、1番目のライトが光る、という形にしたかったのですが、どうも音声認識では、短い単語(たとえば数字のみ)の認識がどうも苦手な様子。

「4番」と言ってもなかなか分かってくれなくて、何度も言いなおさなければなりませんでした。無機質なダンボール箱(AIYスピーカー)相手に、大きな声で、何度も「4番!…4番!…4番!」と話しかけるのは、ちょっと危ない人みたいに思えてきたので、もっと分かりやすい表現にしようと思ったのでした。

そして、5つのライトを判別する呼び名として、5本指を使おうと思い、「親指」と言ったら、1番目のライトが光り、「人差し指」と言ったら、2番めのライトが光る、という形にしてみました。もっとスマートな言い方があるのかもしれませんが、思いつかなくて…。ここは各自好きなように変えると良いですね。

ちなみに、ここのdef main()のrecognizer.expect_phrase()の箇所ですが、わざわざ日本語を指定しなくても、実際はプログラムは動きます。ですが、指定している場合の方が、音声認識の精度が上がる気がしました。なので、あえて全部指定しています。

次に、GPIOをBCMモードに設定した後に、ポートの指定を追加しています。

GPIO.setmode(GPIO.BCM) # BCMモードに設定
# 各ポートをOutに設定
ports = [26,6,13,5,12]
for i in ports:
    GPIO.setup(i, GPIO.OUT)

今回は、Voice Hatの左側にある6つの穴の上から5番目を全部使用しているので、対応するポート(26、6、13、5、12)を記述します。各ポート番号の対応表は冊子の72-73ページ(オンライン版はこちら)に書いてあります。

さらに、そのすぐ下に、もう一つdefを追加して、特定のポートだけ光らせるのを追加します。

                
    # 特定箇所のポートだけ光らせる
    def led_on(no):
        for i, port in enumerate(ports):
            if no == i:
                v = GPIO.HIGH
            else:
                v = GPIO.LOW
            GPIO.output(port, v)

その下の「While True:」以下は、これまでと一緒です。

そして、「else:」以降にガツガツ日本語を追加していきます。

else:
            print('あなたの言葉は "', text, '"')
            if '親指' in text:
                led_on(0)
            elif '人差し指' in text:
                led_on(1)
            elif '中指' in text:
                led_on(2)
            elif '薬指' in text:
                led_on(3)
            elif '小指' in text:
                led_on(4)
            elif 'ピカピカ' in text:
                for i in range (5):
                    for i in range(0, 5):
                        led_on(i)
                        time.sleep(0.1) # 0.1秒待つ
                    for i in range(4, -1, -1):
                        led_on(i)
                        time.sleep(0.1)
            elif 'さよなら' in text:
                GPIO.cleanup()
                sys.exit()

「親指」~「小指」の日本語の場所は、各自言いやすいコマンドを入れれば良いでしょう。

各指の後にあるled_on(3)といった数字は、最初にdefで指定したポートのリストの順番(ports = [26,6,13,5,12])に対応しています。led_on(3)だとリストの4番目になるので5番ポートにつながったライトが光る、ということです。

LEDライトが順番に光る時のコマンドは、今回は「チカチカ」ではなく「ピカピカ」にしてみました(特に理由はなし)。

「やさしくはじめるラズベリーパイ」では、while文を使って、ずっとピカピカが続き、Ctrl+Cで終了、という形だったのですが、今回は他のコマンドもあるので、for文を使用して、順番にピカピカが5往復して終了するようにしています。

また、「さよなら」と言った時にプログラムを終了させるコマンドについてですが、sys.exit()の後にGPIO.cleanup()を入れると、プログラムが終了しても電気が光ったままになってしまったので、順序を逆にして、GPIO.cleanup()の後にsys.exit()が来るようにしています。

こんな感じで、5つのLEDが順番に光ったり、音声で指示した特定のLEDが光るようになりました。

error: Content is protected !!