Google AIY Voice Kitを利用した音声制御おもちゃ

Google AIY Voice Kit

作りかた... The Voice Controlled NeoPixels? Stripの場合

  1. Google AIY Voice Kit とRaspberry Pi 3とmicro-SD(16GB以上)を買ってきます。
  2. Kitに添付された英文のThe MagPi? AIY Projects にしたがって、Google Speaker をそのまま最後まで作ります。
    1. 箱を組み立てる必要はないのですが、動作確認のため、MagPi?に記載された通りに最後まで作ってPythonのプログラムの動作確認を行うことをお勧めします。
    2. 注意
      1. マニュアル P. 38, STEP 06, "the LED inside the arched button should both indicate the device is running." ... ボタンのLEDは点灯しません. ... https://www.raspberrypi.org/magpi/issues/essentials-aiy-v1/
    3. 参考: https://kureuetan.com/web/raspberrypi/4346/
  3. AIY Voice Kit で作った Google Speakerで、MagPi? の chapter six の step 01 から step 07 まで、および、chapter seven の step 01 の backup first, step 02 の expect phrase, step 03 の handle phrase を一つずつ理解しながら実行し、p. 55 の cloudspeech_demo.py を作成し動作確認します。部品が手に入れば、step 04, step 05, step 06を実行して、led_demo.py を作成し, 実行します。p.59 のshutdown_demo.py を作成し動作確認します.
    1. MagPi? P.65の server_demo.py は servo_demo.py の間違いです。servoモータがあれば、これもテストしておくと良いです。
  4. Arduino Nano とNeoPixels? Strip 60cm と100オームの抵抗とブレッドボードとジャンプワイヤの束を買ってきます。
    1. https://store.arduino.cc/usa/arduino-nano
      1. Arduino Nanoのバージョンに注意. 3.0だとダメです。Whats Next Purple だとちゃんと動きました。
      2. http://bizright-blog.tumblr.com/post/120520808729/arduino-nano30の落とし穴にはまったお話戸嶋
    2. https://www.adafruit.com/product/1138?length=1
  5. AIY Voice Kit のRaspberry Pi (以後 Pi)に, Arduino のIDEをインストールします。
    1. https://make.kosakalab.com/make/electronic-work/inst_arduino-ide_raspi/
      1. sudo apt-get install arduino では動かないので、注意。
  6. PiのUSBコネクタの一つとArduino Nano をUSBケーブルで接続します。
  7. PiのArduino IDEの[Tool]の[Borad]でArduino Nano を選び、[Tool]の[Port]で /dev/ttyUSB0 を選びます。
  8. Arduino Nano で IDEのsketch の例の中のBasicのBlink(Lチカ)が動作することを確認します。ここで使うLEDはNano に最初から付いているLEDです。
  9. Adafruit のNeoPixels? のページを参考にして、Arduino Nano と NeoPixels? Strip を接続し, サンプルプログラムを動かして動作確認します。
    1. https://learn.adafruit.com/adafruit-neopixel-uberguide/the-magic-of-neopixels
  10. 以下の arduino の sketch を、Raspberry Pi の arduino のIDEで作成し、arduino nano に書き込みます。
    ٤Ƴ٤Ĥ
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
     98
     99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    
     
     
     
     
     
     
     
    -
    |
    |
    |
    |
    |
    |
    |
    !
     
    -
    |
    |
    |
    !
     
     
     
     
     
     
     
     
     
    -
    |
    !
     
     
     
    -
    -
    !
    |
    |
    -
    !
    |
    |
    |
    |
    |
    |
    -
    |
    !
    !
     
    -
    -
    |
    |
    -
    |
    |
    |
    !
    -
    |
    !
    -
    |
    |
    !
    -
    |
    |
    !
    -
    |
    |
    !
    -
    |
    |
    !
    -
    |
    |
    !
    -
    |
    |
    !
    -
    |
    |
    !
    -
    -
    !
    !
    -
    |
    !
    -
    |
    !
    -
    -
    |
    !
    -
    |
    !
    !
    -
    -
    |
    !
    !
    !
    |
    !
     
    -
    -
    -
    |
    !
    -
    |
    !
    !
    !
     
    -
    -
    |
    !
    |
    |
    -
    |
    -
    |
    !
    |
    !
    -
    |
    -
    |
    !
    |
    !
    -
    |
    !
    -
    |
    !
    !
     
    -
    -
    -
    |
    |
    !
    |
    -
    |
    !
    !
     
    -
    |
    |
    -
    -
    |
    !
    |
    |
    !
    !
     
    -
    -
    -
    !
    !
    !
     
    -
    -
    |
    |
    -
    -
    |
    !
    |
    |
    !
    !
     
    -
    -
    -
    -
    -
    |
    !
    |
    |
    |
    |
    -
    |
    !
    !
    !
    !
     
    -
    -
    -
    -
    -
    |
    !
    |
    |
    |
    |
    -
    |
    !
    !
    !
    !
     
    -
    |
    -
    |
    -
    |
    !
    -
    |
    |
    !
    |
    |
    !
    
    include <Adafruit_NeoPixel.h>
    #ifdef __AVR__
    #include <avr/power.h>
    #endif
     
    #define PIN 6
     
    // Parameter 1 = number of pixels in strip
    // Parameter 2 = Arduino pin number (most are valid)
    // Parameter 3 = pixel type flags, add together as needed:
    // NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
    // NEO_KHZ400 400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
    // NEO_GRB Pixels are wired for GRB bitstream (most NeoPixel products)
    // NEO_RGB Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
    // NEO_RGBW Pixels are wired for RGBW bitstream (NeoPixel RGBW products)
    Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800);
     
    // IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
    // pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
    // and minimize distance between Arduino and first pixel. Avoid connecting
    // on a live circuit...if you must, connect GND first.
     
    byte val=0;
    int led=13;
    int np=30;
    uint32_t color=strip.Color(0,0,0); 
    int lr=0;
    uint32_t pcolor=strip.Color(0,0,0);
     
    uint32_t pattern[30];
    uint32_t originalPattern[30]
      ={0,0,1,1,1,0,0,1,1,1,
         0,0,1,1,1,0,0,1,1,1,
         0,0,1,1,1,0,0,1,1,1};
    uint32_t prePattern[30];
    int rbp=0; //rainbow position
     
    void setup() {
      // This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
      #if defined (__AVR_ATtiny85__)
        if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
      #endif
      // End of trinket special code
     
      pinMode(led,OUTPUT);
      Serial.begin(9600);
     
      strip.begin();
      strip.show(); // Initialize all pixels to 'off'
     
      for(int i=0;i<strip.numPixels();i++){
        pattern[i]=originalPattern[i];
      }
    }
     
    void loop() {
      if(Serial.available()>0){
        String str = Serial.readStringUntil(';');
        Serial.print(val); //for debug, echo back
        if(str.indexOf("original")==0){
          lr=0;
          color=strip.Color(255,0,0,0);
          setColor2pattern(color,originalPattern);
        }
        else if(str.indexOf("rainbow")==0){
          setRainbowPattern();
        }
        else if(str.indexOf("red")==0){
          color=strip.Color(255,0,0);
          setColor2pattern(color,originalPattern);
        }
        else if(str.indexOf("green")==0){
          color=strip.Color(0,255,0);
          setColor2pattern(color,originalPattern);
        }
        else if(str.indexOf("blue")==0){
          color=strip.Color(0,0,255);
          setColor2pattern(color,pattern);
        }
        else if(str.indexOf("yellow")==0){
          color=strip.Color(255,255,0);
          setColor2pattern(color,pattern);
        }
        else if(str.indexOf("magenta")==0){
          color=strip.Color(255,0,255);
          setColor2pattern(color,pattern);
        }
        else if(str.indexOf("cyan")==0){
          color=strip.Color(0,255,255);
          setColor2pattern(color,pattern);
        }
        else if(str.indexOf("white")==0){
          color=strip.Color(255,255,255);
          setColor2pattern(color,originalPattern);
        }
        else if(str.indexOf("left")==0){
          // Some example procedures showing how to display to the pixels:
          lr=-1;
        }
        else if(str.indexOf("right")==0){
          lr=1;
        }
        else if(str.indexOf("stop")==0){
          lr=0;
        }
        else if(str.indexOf("off")==0){
          for(int i=0;i<strip.numPixels();i++){
            prePattern[i]=pattern[i];
          }
          for(int i=0;i<strip.numPixels();i++){
            pattern[i]=strip.Color(0,0,0);
          }
        }
        else if(str.indexOf("on")==0){
          for(int i=0;i<strip.numPixels();i++){
            pattern[i]=prePattern[i];
          }
        }
      }
      showCurrent();
    }
     
    void setColor2pattern(uint32_t c, uint32_t op[]){
      for(int i=0;i<strip.numPixels();i++){
        if(op[i]==0){
          pattern[i]=0;
        }
        else{
          pattern[i]=c;
        }
      }
    }
     
    void showCurrent() {
      for(uint16_t i=0; i<strip.numPixels(); i++) {
        strip.setPixelColor(i, pattern[i]);
      }
      strip.show();
      delay(50);
      if(lr<0){
        uint32_t xc=pattern[0];
        for(int i=0;i<strip.numPixels()-1;i++){
          pattern[i]=pattern[i+1];
        }
        pattern[strip.numPixels()-1]=xc;
      }
      else if(lr>0){
        uint32_t xc=pattern[strip.numPixels()-1];
        for(int i=0;i<strip.numPixels()-1; i++){
          pattern[strip.numPixels()-i-1]=pattern[strip.numPixels()-i-2];
        }
        pattern[0]=xc;
      }
      if(rbp>=255){
        rbp=0;
      }
      else{
        rbp++;
      }
    }
     
    // turn off
    void turnOff(uint8_t wait){
      for(uint16_t i=0; i<strip.numPixels(); i++) {
        uint16_t c=strip.Color(0,0,0);
        strip.setPixelColor(i,c);
      }
      strip.show();
      for(uint16_t i=0; i<strip.numPixels(); i++) {
        delay(wait);
      }
    }
     
    void rainbow(uint8_t wait) {
      uint16_t i, j;
     
      for(j=0; j<256; j++) {
        for(i=0; i<strip.numPixels(); i++) {
          strip.setPixelColor(i, Wheel((i+j) & 255));
        }
        strip.show();
        delay(wait);
      }
    }
     
    void setRainbowPattern(){
      for(int i=0;i<strip.numPixels(); i++){
        // strip.setPixelColor(i,Wheel(((i*256/strip.numPixels())+rbp) & 255));
        pattern[i]=Wheel(((i*256/strip.numPixels())+rbp) & 255);
      }
    }
     
    // Slightly different, this makes the rainbow equally distributed throughout
    void rainbowCycle(uint8_t wait) {
      uint16_t i, j;
     
      for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
        for(i=0; i< strip.numPixels(); i++) {
          strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
        }
        strip.show();
        delay(wait);
      }
    }
     
    //Theatre-style crawling lights.
    void theaterChase(uint32_t c, uint8_t wait) {
      for (int j=0; j<10; j++) { //do 10 cycles of chasing
        for (int q=0; q < 3; q++) {
          for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
            strip.setPixelColor(i+q, c); //turn every third pixel on
          }
          strip.show();
     
          delay(wait);
     
          for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
            strip.setPixelColor(i+q, 0); //turn every third pixel off
          }
        }
      }
    }
     
    //Theatre-style crawling lights with rainbow effect
    void theaterChaseRainbow(uint8_t wait) {
      for (int j=0; j < 256; j++) { // cycle all 256 colors in the wheel
        for (int q=0; q < 3; q++) {
          for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
            strip.setPixelColor(i+q, Wheel( (i+j) % 255)); //turn every third pixel on
          }
          strip.show();
     
          delay(wait);
     
          for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
            strip.setPixelColor(i+q, 0); //turn every third pixel off
          }
        }
      }
    }
     
    // Input a value 0 to 255 to get a color value.
    // The colours are a transition r - g - b - back to r.
    uint32_t Wheel(byte WheelPos) {
      WheelPos = 255 - WheelPos;
      if(WheelPos < 85) {
        return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
      }
      if(WheelPos < 170) {
        WheelPos -= 85;
        return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
      }
      WheelPos -= 170;
      return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
    }
    
  11. Arduino IDE の [tool]->[serial monitor] を選んで、「シリアルモニタ」を開きます。シリアルモニタの右下の、通信速度の設定のボタンで、9600 bps を選びます。
    1. シリアルモニタは、シリアルモニタで人間が入力した文字列を1と0の羅列(ASCIIコードの列)に変換し、Arduino に伝え、Arduino 側ではその羅列を受信して文字列に戻します。また、Arduino 側から送られた文字列を、ASCIIコードの列にして、IDEのシリアルモニタに伝え、IDEで文字列に戻します。
    2. シリアルモニタについては、以下などを参考にしてください。
      http://www.vstone.co.jp/vs_wiki/main/wiki.cgi?page=Arduino+IDE%A4%CE%BB%C8%A4%A4%CA%FD%A4%F2%B3%D0%A4%A8%A4%E8%A4%A6
  12. シリアルモニタ上で、
    white;
    を入力(;を入力した後, [return]または[enter]キーを入力してください)すると、NeoPixel? Strip が飛び飛びに白く光ります。
    left;
    を入力するすると、白く光った部分が左に流れます。この他、white, left 以外にも色々コマンドが使えるので, プログラムの中に書いてあるコマンドを試してみてください。
  13. Arduino IDEのシリアルモニタで人間がコマンドを入力した代わりに、Google で音声認識した結果、得られたコマンドをシリアル通信でArduino に伝えるようにします。Raspberry Pi で以下のプログラムを作成し、保存します。
    ٤Ƴ٤Ĥ
      1
      2
      3
      4
      5
      6
      7
      8
      9
     10
     11
     12
     13
     14
     15
     16
     17
     18
     19
     20
     21
     22
     23
     24
     25
     26
     27
     28
     29
     30
     31
     32
     33
     34
     35
     36
     37
     38
     39
     40
     41
     42
     43
     44
     45
     46
     47
     48
     49
     50
     51
     52
     53
     54
     55
     56
     57
     58
     59
     60
     61
     62
     63
     64
     65
     66
     67
     68
     69
     70
     71
     72
     73
     74
     75
     76
     77
     78
     79
     80
     81
     82
     83
     84
     85
     86
     87
     88
     89
     90
     91
     92
     93
     94
     95
     96
     97
    
    -
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    |
    !
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
    
    #!/usr/bin/env python3
    # Copyright 2017 Google Inc.
    #
    # Licensed under the Apache License, Version 2.0 (the "License");
    # you may not use this file except in compliance with the License.
    # You may obtain a copy of the License at
    #
    # http://www.apache.org/licenses/LICENSE-2.0
    #
    # Unless required by applicable law or agreed to in writing, software
    # distributed under the License is distributed on an "AS IS" BASIS,
    # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    # See the License for the specific language governing permissions and
    # limitations under the License.
     
    """A demo of the Google CloudSpeech recognizer."""
     
    import aiy.audio
    import aiy.cloudspeech
    import aiy.voicehat
    import serial
    import time
     
    def main():
      recognizer = aiy.cloudspeech.get_recognizer()
      recognizer.expect_phrase('turn off the light')
      recognizer.expect_phrase('turn on the light')
      recognizer.expect_phrase('blink')
      recognizer.expect_phrase('red')
      recognizer.expect_phrase('green')
      recognizer.expect_phrase('blue')
      recognizer.expect_phrase('white')
      recognizer.expect_phrase('yellow')
      recognizer.expect_phrase('magenta')
      recognizer.expect_phrase('rainbow')
      recognizer.expect_phrase('cyan')
      recognizer.expect_phrase('left')
      recognizer.expect_phrase('right')
      recognizer.expect_phrase('stop')
      recognizer.expect_phrase('turn on the tape')
      recognizer.expect_phrase('turn off the tape')
     
      button = aiy.voicehat.get_button()
      led = aiy.voicehat.get_led()
      aiy.audio.get_recorder().start()
      ser=serial.Serial('/dev/ttyUSB0',9600)
      time.sleep(2)
      aiy.audio.say('Hello, I\'m listening.')
     
      while True:
        # print('Press the button and speak')
        # button.wait_for_press()
        print('Listening...')
        text = recognizer.recognize()
        if not text:
          print('Sorry, I did not hear you.')
          aiy.audio.say('Sorry, I did not hear you.')
        else:
          print('You said "', text, '"')
          aiy.audio.say('you said '+text+'.')
          if 'turn on the light' in text:
            led.set_state(aiy.voicehat.LED.ON)
          elif 'turn off the light' in text:
            led.set_state(aiy.voicehat.LED.OFF)
          elif 'blink' in text:
            led.set_state(aiy.voicehat.LED.BLINK)
          elif 'red' in text:
            ser.write(b"red;")
          elif 'green' in text:
            ser.write(b"green;")
          elif 'blue' in text:
            ser.write(b"blue;")
          elif 'yellow' in text:
            ser.write(b"yellow;")
          elif 'cyan' in text:
            ser.write(b"cyan;")
          elif 'magenta' in text:
            ser.write(b"magenta;")
          elif 'White' in text:
            ser.write(b"white;")
          elif 'rainbow' in text:
            ser.write(b"rainbow;")
          elif 'left' in text:
            ser.write(b"left;")
          elif 'right' in text:
            ser.write(b"right;")
          elif 'stop' in text:
            ser.write(b"stop;")
          elif 'turn on the tape' in text:
            ser.write(b"on;")
          elif 'turn off the tape' in text:
            ser.write(b"off;")
          elif 'goodbye' in text:
            break
     
    if __name__ == '__main__':
      main()
    

Counter: 1812, today: 2, yesterday: 2

添付ファイル: fileoverview.png 220件 [詳細]

トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2018-07-29 (日) 19:43:36 (783d)