パソコンで音声認識を行い、認識結果を赤外線送信機に送ります。そして赤外線送信機からはテレビのリモコンと同一の赤外線コードを送信することで、リモコンロボットを音声で動作させることができるようになります。
簡易版 |
通常版と形状が異なりますが、アームを外して簡略化しただけで、基本的な回路は同じものです。
パソコンと接続し任意のコマンドを送信できるように、送信機を用意します。
※ICソケットだけとなっている部分は、本来マイコンが取り付けられます。
送信機 回路図 (CE3形式 - 回路図エディタ BSchファイル)
品名 | 個数 | |
---|---|---|
PICマイコン | PIC16F88 | 1 |
インターフェイスIC | ADM3202 (MAX232) | 1 |
セラミック発振子 | 20MHz | 1 |
3端子レギュレーター | 78L05 | 1 |
赤外線LED | TLN115A | 1 |
LED | 2 | |
トランジスタ | 2SC3751 | 1 |
カーボン抵抗 | 330Ω | 2 |
カーボン抵抗 | 200Ω | 1 |
カーボン抵抗 | 10Ω | 1 |
セラミック コンデンサ | 1.5μF | 1 |
セラミック コンデンサ | 0.1μF | 6 |
電解コンデンサ | 22μF | 1 |
#case // -------------------------------------------------------------- #include <16f88.h> #fuses HS, NOWDT, NOPROTECT, PUT, NOBROWNOUT, NOLVP, NOCPD, MCLR, CCPB3 #device *=16 #use delay( Clock = 20000000 ) #use rs232( BAUD = 115200, XMIT=PIN_B5, RCV=PIN_B2 ) #use fast_io( A ) #use fast_io( B ) typedef short bool; // マクロ定義 #define IR_LED PIN_B6 // 受信確認LED #define STATUS_LED PIN_B4 // ステータスLED #define PWM_DUTY 0x0109L // PWM Duty (13.2usec = 1/10周期) #define DATA_SIZE 5 // データサイズ[ byte ] #define STATUS_REGISTER 0x03 // STATUSレジスタ #define FSR_REGISTER 0x04 // FSR #define INDF_REGISTER 0x00 // INDF #bit INTERRUPT_FLAG_RECEIVE = 0x0C.5 // 受信 割り込みフラグ(16F88) // 変数宣言 struct BitLength { int high; int low; }; struct CodeFormat { struct BitLength startBit; struct BitLength oneBit; struct BitLength zeroBit; }; // プロトタイプ宣言 void Init(); void BlinkStatusLed( int num ); void ReceiveSendDataOfInfraredRays(); void SendCode( int bitSum, struct CodeFormat* format, int* data ); void FlashLed( struct BitLength* length ); void ShowValue( long value ); void ShiftBit( int* data, int dataLength, int numberToShift );
#include "TV_SignalSender.h" // ===================================================================== // メイン関数 void main() { // 初期化する Init(); while( 1 ) { } } // ===================================================================== // 初期化する void Init() { set_tris_a( 0b00000000 ); set_tris_b( 0b00000101 ); // ラッチをクリアする output_a( 0x00 ); output_b( 0x00 ); // A/D コンバーターを設定する setup_adc_ports( NO_ANALOGS ); setup_adc( ADC_OFF ); // PWMを設定する set_pwm1_duty( 0x0000L ); setup_timer_2( T2_DIV_BY_1, 0x83, 1 ); // PWM周期 設定( 26.4us = 37.9kHz ) setup_ccp1( CCP_PWM ); // CCP動作モード設定(PWM) // タイマ1を設定する setup_timer_0( RTCC_INTERNAL | RTCC_DIV_256 ); // 外部INTを設定する ext_int_edge( H_TO_L ); // USARTの割り込みを許可する enable_interrupts( INT_RDA ); // 受信確認LEDを消灯させる output_high( IR_LED ); // ステータスLEDを点滅させる BlinkStatusLed( 2 ); // ... ステータスLEDを点灯させる output_low( STATUS_LED ); // 割り込みを許可する enable_interrupts( GLOBAL ); } // ===================================================================== // USARTから 受信をした #int_rda void ReceiveFromUsart() { // 受信データチェック switch( getc() ) { case 0xF0: // 送信要求 { // 赤外線送信データを受信する ReceiveSendDataOfInfraredRays(); break; } case 0xF1: // 受信要求 { // 外部INT 割り込みを許可する enable_interrupts( INT_EXT ); break; } } // 多重割り込みに対処するため、受信フラグをクリアする INTERRUPT_FLAG_RECEIVE = 0; } // 信号を検出した #INT_EXT void DetectSignal() { // カウンタ値を取得する long widthOfSignal; widthOfSignal = get_timer0(); // タイマをリセットする set_timer0( 0x00 ); // 受信確認LEDを点灯させる output_low( IR_LED ); // ... 信号の幅を表示する ShowValue( widthOfSignal ); // ... 受信確認LEDを消灯させる output_high( IR_LED ); } // ===================================================================== // 赤外線送信データを受信する void ReceiveSendDataOfInfraredRays() { int i; int bitSum; struct CodeFormat format; int data[ DATA_SIZE ]; // ビット数を取得する bitSum = getchar(); // スタートビット幅を取得する format.startBit.high = getchar(); format.startBit.low = getchar(); // 1ビット幅を取得する format.oneBit.high = getchar(); format.oneBit.low = getchar(); // 0ビット幅を取得する format.zeroBit.high = getchar(); format.zeroBit.low = getchar(); for( i=0; i<DATA_SIZE; i++ ) { // データを取得する data[ i ] = getchar(); } // コードを送信する SendCode( bitSum, &format, data ); } // ===================================================================== // コードを送信する void SendCode( int bitSum, struct CodeFormat* format, int* data ) { int i; // 最初のデータまで ビットを動かす ShiftBit( data, DATA_SIZE, ( DATA_SIZE * 8 ) - bitSum ); // スタートビットを発光する FlashLed( &format->startBit ); for( i=0; i<bitSum; i++ ) { // 最上位ビットが1ならば Highを送信する if( 0x80 & *data ) { // High を発光する FlashLed( &format->oneBit ); } else { // Low を発光する FlashLed( &format->zeroBit ); } // 1ビット左シフトする ShiftBit( data, DATA_SIZE, 1 ); } // ストップビットを発光する FlashLed( &format->startBit ); } // LED発光 (38kHz) void FlashLed( struct BitLength* length ) { int i; set_pwm1_duty( PWM_DUTY ); for( i=0; i<length->high; i++ ) { // プリスケーラ 256 x 0.2usec = 51.2usec delay_us( 51 ); } // set_pwm1_duty( 0x0000L ); for( i=0; i<length->low; i++ ) { // プリスケーラ 256 x 0.2usec = 51.2usec delay_us( 51 ); } } // ===================================================================== // 数値を表示する void ShowValue( long value ) { const int countMax = 10; static int count; printf( "%2X ", value ); if(countMax <= ++count ) { printf( "\n\r" ); count = 0; } } // ===================================================================== // ステータスLEDを点滅させる void BlinkStatusLed( int num ) { // num は点滅回数のため2倍にする num <<= 1; for( ; num; num-- ) { output_bit( STATUS_LED, num & 0x01 ); delay_ms( 200 ); } } // ビットをシフトする void ShiftBit( int* data, int dataLength, int numberToShift ) { int k; int loop; int* address; address = data + ( DATA_SIZE - 1 ); for( k=0; k<numberToShift; k++ ) { loop = dataLength; // 処理速度を向上させるため、以降はインライン アセンブラ #asm // バンク0を指定する bcf STATUS_REGISTER, 7 // ... FSRレジスタに データのアドレスを設定する movf address, w movwf FSR_REGISTER // キャリーをクリアする bcf STATUS_REGISTER, 0 LOOP: // キャリーを含めて左にシフトする rlf INDF_REGISTER, f // ... アドレスを左に動かす decf FSR_REGISTER, f // 指定回数だけ 処理をくり返す decfsz loop, f goto LOOP #endasm } }
音声認識を行い、その結果を赤外線送信機に送るためのアプリケーションです。
次のリンクからダウンロードできます。ソースコードも公開していますので、興味のある方はそちらも参照してください。
ダウンロード ≫VoiceCommander
voice-commander-src.zip ソースコード (Visual Studio 2008)
音声認識には Microsoft SAPIを使用しているため、事前にSpeech SDKがインストールされている必要があります。
音声の認識に使用する語句の辞書を編集することで、任意の言葉で操作できるようになります。その辞書は、インストール先のフォルダにgrammar.xmlの名前であります。
<?xml version="1.0" encoding="UTF-8"?> <GRAMMAR> <RULE name="MOTION_NAME" toplevel="ACTIVE"> <L> <P>/前へ進め/まえへすすめ;</P> <P>/止まれ/とまれ;</P> <P>/後ろへ下がれ/うしろへさがれ;</P> <P>/左へ回れ/ひだりへまわれ;</P> <P>/右へ回れ/みぎへまわれ;</P> </L> </RULE> </GRAMMAR>
※このファイルを変更しても、VoiceCommanderの画面上の語句は変化しません。