あなたの声で動く!音声認識×LEDライト制御の超入門IoT

プログラミング

はじめに

「OK! ライトON」「Bye! ライトOFF」—— たった一声でLEDライトが思い通りに光る。そんな未来的な体験を、初心者でも簡単に作れるのをご存知ですか?

今回は、Raspberry PiとUSBマイクを使って、音声認識によるLED制御システムを構築する方法を、電子工作初心者にもわかりやすく解説します。プログラミング経験がなくても大丈夫。一歩ずつ丁寧に進めていきましょう。

なぜ音声認識IoTが面白いのか?

スマートスピーカーが普及した現在、音声で家電を操作することは珍しくありません。しかし、自分の手で一から作り上げた音声制御システムは格別です。

音声認識IoTの魅力:

  • 手を使わずにデバイスを操作できる利便性
  • 自分好みのコマンド語を設定できるカスタマイズ性
  • プログラムが正確に音声を認識した時の達成感
  • スマートホーム化への第一歩として最適

必要な材料と準備

必要な部品

  • Raspberry Pi(4B推奨、3B+でも可)
  • microSDカード(32GB以上推奨)
  • USBマイク(PCゲーム用などで十分)
  • LED(5mm、好きな色)
  • 抵抗器(330Ω〜1kΩ)
  • ブレッドボード
  • ジャンパーワイヤー(オス-メス、オス-オス)

開発環境

  • Raspberry Pi OS(最新版)
  • Python 3.7以上
  • インターネット接続(ライブラリインストール用)

推奨予算

全部品合わせて約8,000円〜12,000円程度で揃えられます。Raspberry Piを既にお持ちの方なら、追加で3,000円程度で始められます。

ステップ1:Raspberry Piのセットアップ

OSのインストール

  1. Raspberry Pi Imagerを公式サイトからダウンロード
  2. microSDカードに**Raspberry Pi OS(Desktop版)**を書き込み
  3. 初回起動時にWi-Fi設定とSSH有効化を実行

基本設定

bash

# システムアップデート
sudo apt update && sudo apt upgrade -y

# 必要なパッケージのインストール
sudo apt install python3-pip git -y

オーディオ設定の確認

USBマイクを接続後、認識されているか確認:

bash

# マイクデバイスの確認
arecord -l

# テスト録音(5秒間)
arecord -D plughw:1,0 -d 5 test.wav

# 再生して確認
aplay test.wav

ステップ2:LED回路の組み立て

配線図の理解

LEDをGPIOピンに接続する際は、必ず抵抗を通して電流制限を行います。

配線手順:

  1. GPIO 18番ピン330Ω抵抗LEDの長い足(アノード)
  2. LEDの短い足(カソード)GNDピン

安全な配線のポイント

  • 配線作業時はRaspberry Piの電源を切る
  • LEDの極性(長い足がプラス)を間違えない
  • 抵抗値は330Ω〜1kΩの範囲で選択
  • 配線がしっかり差し込まれているか確認

動作テスト

python

# led_test.py
import RPi.GPIO as GPIO
import time

GPIO.setmode(GPIO.BCM)
GPIO.setup(18, GPIO.OUT)

try:
    print("LEDテスト開始...")
    for i in range(5):
        GPIO.output(18, GPIO.HIGH)  # LED ON
        print("LED ON")
        time.sleep(1)
        GPIO.output(18, GPIO.LOW)   # LED OFF
        print("LED OFF")
        time.sleep(1)
finally:
    GPIO.cleanup()
    print("テスト完了")

ステップ3:音声認識ライブラリのセットアップ

必要ライブラリのインストール

bash

# 音声認識ライブラリ
pip3 install SpeechRecognition

# PyAudioのセットアップ(少し時間がかかります)
sudo apt install portaudio19-dev python3-pyaudio -y
pip3 install pyaudio

# GPIO制御
pip3 install RPi.GPIO

インストール確認

python

# インストール確認用スクリプト
import speech_recognition as sr
import RPi.GPIO as GPIO
print("ライブラリの準備完了!")

ステップ4:音声認識プログラムの作成

基本的な音声認識テスト

まずは音声認識が正常に動作するかテストしましょう:

python

# voice_test.py
import speech_recognition as sr

def test_voice_recognition():
    r = sr.Recognizer()
    mic = sr.Microphone()
    
    print("マイクの調整中...")
    with mic as source:
        r.adjust_for_ambient_noise(source)
    print("何か話してください(5秒間)")
    
    with mic as source:
        audio = r.listen(source, timeout=5)
    
    try:
        text = r.recognize_google(audio, language='ja-JP')
        print(f"認識結果: {text}")
    except sr.UnknownValueError:
        print("音声を認識できませんでした")
    except sr.RequestError as e:
        print(f"エラー: {e}")

if __name__ == "__main__":
    test_voice_recognition()

メイン制御プログラム

いよいよ音声認識とLED制御を組み合わせたメインプログラムを作成します:

python

# voice_led_controller.py
import speech_recognition as sr
import RPi.GPIO as GPIO
import time
import threading

class VoiceLEDController:
    def __init__(self):
        # GPIO設定
        GPIO.setmode(GPIO.BCM)
        GPIO.setup(18, GPIO.OUT)
        GPIO.output(18, GPIO.LOW)  # 初期状態はOFF
        
        # 音声認識設定
        self.recognizer = sr.Recognizer()
        self.microphone = sr.Microphone()
        
        # LED状態
        self.led_state = False
        
        # マイク調整
        print("マイクを調整中...")
        with self.microphone as source:
            self.recognizer.adjust_for_ambient_noise(source, duration=2)
        print("準備完了!音声コマンドを待機中...")
    
    def process_voice_command(self, command):
        """音声コマンドを処理"""
        command = command.lower()
        
        # ライトONコマンド
        if any(keyword in command for keyword in ['ライト', 'らいと', 'light']) and \
           any(keyword in command for keyword in ['オン', 'on', 'つけて', 'つける']):
            self.turn_on_led()
            return True
            
        # ライトOFFコマンド
        elif any(keyword in command for keyword in ['ライト', 'らいと', 'light']) and \
             any(keyword in command for keyword in ['オフ', 'off', 'けして', '消す']):
            self.turn_off_led()
            return True
            
        # 特別なコマンド
        elif 'ok' in command and 'ライト' in command:
            self.turn_on_led()
            return True
            
        elif 'bye' in command or 'バイ' in command:
            self.turn_off_led()
            return True
            
        return False
    
    def turn_on_led(self):
        """LEDを点灯"""
        if not self.led_state:
            GPIO.output(18, GPIO.HIGH)
            self.led_state = True
            print("✅ LEDをONにしました!")
        else:
            print("LEDは既にONです")
    
    def turn_off_led(self):
        """LEDを消灯"""
        if self.led_state:
            GPIO.output(18, GPIO.LOW)
            self.led_state = False
            print("❌ LEDをOFFにしました!")
        else:
            print("LEDは既にOFFです")
    
    def listen_continuously(self):
        """継続的な音声認識"""
        print("音声コマンド例:")
        print("- 'OK! ライトON' : LEDを点灯")
        print("- 'Bye!' : LEDを消灯")
        print("- 'ライトつけて' : LEDを点灯")
        print("- 'ライト消して' : LEDを消灯")
        print("\nCtrl+Cで終了\n")
        
        try:
            while True:
                try:
                    with self.microphone as source:
                        # 短時間待機(1秒)
                        audio = self.recognizer.listen(source, timeout=1, phrase_time_limit=5)
                    
                    # 音声認識実行
                    command = self.recognizer.recognize_google(audio, language='ja-JP')
                    print(f"🎤 認識: {command}")
                    
                    # コマンド処理
                    if self.process_voice_command(command):
                        print("✨ コマンドを実行しました")
                    else:
                        print("❓ 対応するコマンドが見つかりませんでした")
                        
                except sr.WaitTimeoutError:
                    # タイムアウト時は何もしない(継続待機)
                    pass
                except sr.UnknownValueError:
                    # 認識できない場合も継続
                    pass
                except sr.RequestError as e:
                    print(f"音声認識サービスエラー: {e}")
                    time.sleep(1)
                    
        except KeyboardInterrupt:
            print("\n終了します...")
        finally:
            self.cleanup()
    
    def cleanup(self):
        """終了処理"""
        GPIO.output(18, GPIO.LOW)  # LED OFF
        GPIO.cleanup()
        print("システムを終了しました")

if __name__ == "__main__":
    controller = VoiceLEDController()
    controller.listen_continuously()

ステップ5:実行とトラブルシューティング

プログラムの実行

bash

python3 voice_led_controller.py

よくある問題と解決方法

マイクが認識されない場合:

bash

# USBマイクの接続確認
lsusb

# オーディオデバイス確認
cat /proc/asound/cards

音声認識精度が低い場合:

  • 静かな環境で実行する
  • マイクをRaspberry Piに近づける
  • 発音をはっきりと行う
  • adjust_for_ambient_noiseの調整時間を延ばす

LEDが点灯しない場合:

  • 配線を再確認(極性、接続不良)
  • 抵抗値を確認(大きすぎると暗くなる)
  • GPIOピン番号を確認

パフォーマンス改善のヒント

python

# 認識精度向上のための設定調整例
recognizer.energy_threshold = 4000  # ノイズ閾値調整
recognizer.dynamic_energy_threshold = True
recognizer.pause_threshold = 0.8    # 発話間の待機時間

カスタマイズとアレンジアイデア

複数LEDの制御

python

# 複数のLEDを制御する例
led_pins = [18, 19, 20, 21]
for pin in led_pins:
    GPIO.setup(pin, GPIO.OUT)

# 色別制御
def set_color_command(command):
    if '赤' in command:
        control_red_led()
    elif '青' in command:
        control_blue_led()

音声フィードバック機能

bash

# 音声合成ライブラリ
sudo apt install espeak espeak-data -y

# Python音声合成
pip3 install pyttsx3

スマートホーム連携

将来的には以下のような拡張が可能です:

  • HomeAssistantとの連携
  • MQTTを使った他デバイスとの通信
  • WebAPIによる外部からの制御
  • スマートフォンアプリとの連携

まとめ:音声制御の世界への第一歩

今回作成した音声認識LEDシステムは、IoTと音声技術の入門プロジェクトとして最適です。単純な構成でありながら、音声でモノを制御する感動を実際に体験できます。

学んだポイント:

  • Raspberry Piを使った基本的な電子回路
  • Python音声認識ライブラリの活用
  • GPIO制御によるLED操作
  • 継続的な音声認識システムの構築

このシステムをベースに、センサー追加、複数デバイス制御、ネットワーク連携など、さらなる発展が可能です。あなたも「声で動くIoT」の世界を楽しんでください!