Google AIY スピーカーの音声認識で電子工作!~2つのLEDを光らせる

さて、地味に続けているラズベリーパイの電子工作。電子工作を学びながら、それをGoogle AIYスピーカーの音声認識に応用しています。

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



普通にLEDを交互に光らせる

まずは、音声認識なしでLEDを交互に光らせることを実行してみます。

ここの部分は、私の電子工作の教科書となっているクジラ飛行机さんの「やさしくはじめるラズベリー・パイ」の第3-5(p.92-)を参考にします。この本は本当に分かりやすいのでオススメです。

ブレッドボードに必要なものを配置

今回使用するのは、Google AIY Voice Kitのラズパイです。

AIYスピーカーのラズパイのGPIOにジャンパワイヤを刺す際には、本体の上にVoice Hatが乗っかっているので、GPIOのポートの配置が変わってきます。GPIOの対応表は、AIYスピーカーを購入時に付属していた冊子の72-73ページ(オンラインPDFだとこちら)に載っています。

さて、まずは、ブレッドボードにジャンパワイヤやらLED電球やら抵抗(330Ω)を刺し、そのあと、電源を抜いたAIYスピーカーのVoice Hatの基盤にジャンパワイヤを刺していきます。

今回使用した材料は以下のとおりでした。

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

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

ジャンパワイヤの数が異様に多くなっているわけですが、これはどういうことかというと、GPIOのピンに直に刺すのと異なり、Voice Hatの基盤上の穴に刺していくので、基本的にオスーオスのジャンパワイヤ(5本)しか必要がなくなるわけです。ですが、手元にあるオスーオスのワイヤがとっても短い。

どう頑張っても、ダンボール箱内のVoice Hatに到達しない…というわけで、Voice Hatへ刺す分については、オスーメスのワイヤ(3本)を使用して、オス-オスのワイヤにオスーメスのメスを刺して(分かりにくい…)、つなげて延長することで解決しました。

写真中のカラフルなワイヤ(赤と青)がオスーオスのジャンパワイヤ、ダンボールの方に向かって伸びてる黒いのがオスーメスのジャンパワイヤです。

さて、マイナスとプラス、抵抗と電球の場所に注意しながら、さくさく刺していきます。ブレッドボード上の各部品の配置は、「やさしくはじめるラズベリー・パイ」の92ページのまんまです。

一方で、Voice Hat上で刺す場所については、今回は、付属冊子の72-73ページで言うServosの一番上と二番めを利用しました。

つまり使用するポートはServo0(GPIO 26)と、Servo1(GPIO 6)の2つです。GNDはServo0にあるものを利用しました。

この写真では分かりづらいかしら、黒いケーブルがVoice Hatの3つの穴に刺さっています。

プラスに向かう2つのケーブルが左の2つの穴に、マイナス(GND)が右側の穴1つに刺さっています。

それが完了したら、AIY ProjectsのOSに入ってるThonnyを使って、パイソンのプログラムを書いていきます、というか、「やさしくはじめるラズベリー・パイ」の96ページのプログラムを写経して、実行します。

この「Thonny Python IDE」というアプリですが、何気に便利です。

プログラムを作って「Run」ボタンを押すとその場で実行できます。わざわざターミナルを開かなくて良いので、とっても楽です。エラーがある時は、実行前に指摘してくれます。

写経が完了したら、プログラムを実行…できるかな?

人生、そう上手くはいきません。いつものようにエラーが出てきますよ。今回はどんなミスをしてるでしょうか。

今回は、1箇所、コンマがピリオドになっていた。2箇所がスペルミス(HIGHがHIGHTに、InterruptがInterrruptに)、というエラーでした。

これを修正して再度トライすると、上手くいきました。

音声認識と組み合わせてみる

上手くいきましたので、次は、音声認識を使ってやってみます。

前回作ったLEDのプログラムを少し変更してみます。もう直接、日本語で言葉も書いていきます。ベースは、AIYスピーカー付属の冊子の57ページのプログラムです。

まずはImportのところでは大きな変更はないのですが、前回のimport os の代わりに今回は、sysを使おうと思います(5行目に追加)。

import aiy.audio
import aiy.cloudspeech
import aiy.voicehat
import RPi.GPIO as GPIO
import time, sys               # Sleepとsysを利用する
aiy.i18n.set_language_code('ja-JP')

今回のプログラムでは、「電気をつけて」と言ったら電気が2つ付き、「電気を消して」といったら両方の電気が消え、「右」と言ったら右の電気が付き、「左」と言ったら左の電気が付き、「チカチカ」と言ったら、左右の電気が交互に光り、「さよなら」と言ったら、プログラムが終わる、という形にしたいと思います。

先に試した「やさしくはじめるラズベリー・パイ」の93ページのプログラムでは2つのLEDが交互に点滅するのみでしたが、せっかくの音声コマンドなので、右と言ったら右のライトが、左なら左のライトが点灯するようにしてみます。

ちなみに「さようなら」より「さよなら」の方が音声認識されやすかったので、「さよなら」にしています。

というわけで、def mainの場所はこんな感じで追加しました。「電気をつけて」の「つけて」は漢字ではなく平仮名で。

def main():
 recognizer = aiy.cloudspeech.get_recognizer()
 recognizer.expect_phrase('電気をつけて')
 recognizer.expect_phrase('電気を消して')
 recognizer.expect_phrase('右')
 recognizer.expect_phrase('左')
 recognizer.expect_phrase('チカチカ')

さらに、GPIO.setupに26と6番ポートを使います。前回は26番のみを使用していたので、その下に6番を追加します。ポート番号のまま利用していっても良いのですが、クジラ飛行机さんのプログラムで、PORT_LとPORT_Rに定義されてたので、真似してそれを使ってみます。今回は、ポート6がL(左)、ポート26がR(右)にします。

PORT_L=6
PORT_R=26
GPIO.setup(PORT_L, GPIO.OUT)
GPIO.setup(PORT_R, GPIO.OUT)

その後は、基本、一緒で、if…の部分まで下がってきたら、どんどん直していきます。

 if '電気をつけて' in text:
     GPIO.output(PORT_L, GPIO.HIGH)
     GPIO.output(PORT_R, GPIO.HIGH) 
 elif '電気を消して' in text:
     GPIO.output(PORT_L, GPIO.LOW)
     GPIO.output(PORT_R, GPIO.LOW) 
 elif '右' in text:
     GPIO.output(PORT_R, GPIO.HIGH)
     GPIO.output(PORT_L, GPIO.LOW)
 elif '左' in text:
     GPIO.output(PORT_R, GPIO.LOW)
     GPIO.output(PORT_L, GPIO.HIGH)
 elif 'チカチカ' in text:
     for i in range(5):
         print("i=", i)
         GPIO.output(PORT_L, GPIO.HIGH)
         GPIO.output(PORT_R, GPIO.LOW)
         time.sleep(0.3)
         GPIO.output(PORT_L, GPIO.LOW)
         GPIO.output(PORT_R, GPIO.HIGH)
         time.sleep(0.3) 
 elif 'さよなら' in text:
     sys.exit()

「やさしくはじめるラズベリー・パイ」のp96のプログラムでは、チカチカの部分はWhile文を使って、Ctrl+Cでチカチカが終わるようになっていたのですが、他のコマンドもあるので、ここでは、前回のチカチカ同様、For文で5回点滅にしておきました(10回だと長く感じられたので)。この辺は各自お好みで回数や間隔を変えてしまえば良いと思います。

さよならでプログラムが終わるところは、osの代わりに、「sys.exit()」を使っています。というか、osとsysの違いがイマイチ良く分かっていないのです(T_T)。ただし、osでやったら、プログラムが固まってしまったのが、sysだと上手く終わったので、これでいいんじゃないかと思います(適当でスミマセン)。

というわけで、試行錯誤をしながらも、何とか、音声認識で、2つのLEDを光らせることができました。

error: Content is protected !!