工業製造
産業用モノのインターネット | 工業材料 | 機器のメンテナンスと修理 | 産業プログラミング |
home  MfgRobots >> 工業製造 >  >> Manufacturing Technology >> 製造プロセス

Arduinoによる音声認識と合成

コンポーネントと消耗品

>
Arduino Due
× 1
SparkFunElectretマイクブレイクアウト
× 1
SparkFunモノラルオーディオアンプブレイクアウト
× 1
スピーカー:0.25W、8オーム
× 1
ブレッドボード(汎用)
× 1
5 mm LED:赤
× 3
抵抗330オーム
× 3
ジャンパー線(汎用)
× 1

必要なツールとマシン

>
はんだごて(汎用)

アプリとオンラインサービス

BitVoicer Server 1.0

このプロジェクトについて

以前のプロジェクトでは、ArduinoボードとBitVoicerサーバーを使用していくつかのLEDを制御する方法を示しました。このプロジェクトでは、物事をもう少し複雑にします。また、Arduino DUEデジタル-アナログコンバーター(DAC)を使用して音声を合成します。 Arduino DUEがない場合は、他のArduinoボードを使用できますが、外部DACとDACを操作するための追加コードが必要になります(BVSSpeakerライブラリはそれを支援しません)。

下のビデオでは、Arduinoに小さな曲を再生させ、LEDをピアノの鍵盤のように点滅させていることがわかります。私のピアノのスキルは申し訳ありませんが、それが私にできる最善のことです:)。 LEDは実際には実際のC、D、Eキーと同じシーケンスとタイミングで点滅するため、ピアノを持っている場合は、LEDをたどって同じ曲を再生できます。もはや存在しない古い小売業者(Mappin)のジングルです。

次の手順を実行して、音声コマンドをLEDアクティビティと合成音声に変換します。

  • 1。音声波は、Sparkfun ElectretBreakoutボードによってキャプチャおよび増幅されます。
  • 2。増幅された信号は、アナログ-デジタルコンバーター(ADC)を使用してArduinoでデジタル化およびバッファリングされます。
  • 3。オーディオサンプルは、Arduinoシリアルポートを使用してBitVoicerサーバーにストリーミングされます。
  • 4。 BitVoicerサーバーはオーディオストリームを処理し、そこに含まれる音声を認識します。
  • 5。認識された音声は、Arduinoに送り返される事前定義されたコマンドにマッピングされます。コマンドの1つが音声の合成で構成されている場合、BitVoicerサーバーはオーディオストリームを準備してArduinoに送信します;
  • 6。 Arduinoはコマンドを識別し、適切なアクションを実行します。オーディオストリームが受信されると、BVSSpeakerクラスにキューに入れられ、DUEDACとDMAを使用して再生されます。
  • 7。 SparkFunモノラルオーディオアンプはDAC信号を増幅するため、8オームのスピーカーを駆動できます。

資料リスト:

  • Arduino DUE:〜U $ 50.00
  • Sparkfun Electretマイクブレイクアウト:7.95米ドル
  • SparkFunモノラルオーディオアンプブレイクアウト:U $ 7.95
  • BitVoicer Server 1.0:U $ 9.90
  • 8オームスピーカー:〜U $ 2.00
  • ブレッドボード:〜U $ 10.00
  • 3 x LED:〜U $ 1.00
  • 3 x 330オーム抵抗器:〜U $ 0.75
  • ジャンパー線:〜U $ 0.50

ステップ1:配線

最初のステップは、下の写真に示すように、Arduinoとブレッドボードをコンポーネントで配線することです。スピーカーの下に小さなゴムを配置する必要がありました。これは、スピーカーが大きく振動し、ゴムがないとオーディオの品質に大きな影響を与えるためです。

<図> <図> <図> <図>

ここでは、以前のプロジェクトとは小さいながらも重要な違いがあります。ほとんどのArduinoボードは5Vで動作しますが、DUEは3.3Vで動作します。 3.3VでSparkfunElectret Breakoutを実行するとより良い結果が得られたため、5V Arduinoボードを使用している場合は、3.3VピンとAREFピンの間にジャンパーを追加することをお勧めします。 DUEはすでに3.3Vアナログリファレンスを使用しているため、AREFピンへのジャンパーは必要ありません。実際、DUEのAREFピンは抵抗ブリッジを介してマイクロコントローラに接続されています。 AREFピンを使用するには、抵抗BR1をPCBからはんだ除去する必要があります。

ステップ2:コードをArduinoにアップロードする

次に、以下のコードをArduinoにアップロードする必要があります。便宜上、Arduinoスケッチはこの投稿の下部にある添付ファイルセクションでも入手できます。コードをアップロードする前に、BitVoicerサーバーライブラリをArduino IDEに適切にインストールする必要があります(.zipライブラリのインポート)。

Arduinoスケッチ :BVS_Demo2.ino

このスケッチには7つの主要な部分があります:

  • ライブラリ参照と変数宣言 :最初の4行には、BVSP、BVSMic、BVSSpeaker、およびDACライブラリへの参照が含まれています。これらのライブラリはBitSophiaによって提供され、BitVoicerServerのインストールフォルダにあります。 BVSSpeakerライブラリへの参照を追加すると、DACライブラリが自動的に含まれます。他の行は、スケッチ全体で使用される定数と変数を宣言しています。 BVSPクラスはBitVoicerServerとの通信に使用され、BVSMicクラスはオーディオサンプルのキャプチャと保存に使用され、BVSSpeakerクラスはDUEDACを使用したオーディオの再生に使用されます。
  • セットアップ機能 :この関数は、次のアクションを実行します。ピンモードとその初期状態を設定します。シリアル通信を初期化します。 BVSP、BVSMic、およびBVSSpeakerクラスを初期化します。また、BVSPクラスのframeReceived、modeChanged、およびstreamReceivedイベントの「イベントハンドラー」(実際には関数ポインター)を設定します。
  • ループ機能 :この関数は、次の5つの重要なアクションを実行します。サーバーにステータス情報を要求します(keepAlive()関数)。サーバーがデータを送信したかどうかを確認し、受信したデータを処理します(receive()関数)。オーディオストリームの録音と送信を制御します(isSREAvailable()、startRecording()、stopRecording()、sendStream()関数)。 BVSSpeakerクラスにキューイングされたオーディオサンプルを再生します(play()関数)。そして、playLEDNotesコマンドを受信した後にLEDを点滅させる方法を制御するplayNextLEDNote()関数を呼び出します。
  • BVSP_frameReceived関数 :この関数は、receive()関数が1つの完全なフレームが受信されたことを識別するたびに呼び出されます。ここでは、BitVoicerサーバーから送信されたコマンドを実行します。 LEDを制御するコマンドには2バイトが含まれています。最初のバイトはピンを示し、2番目のバイトはピンの値を示します。私はanalogWrite()関数を使用して、ピンに適切な値を設定します。また、バイトタイプのplayLEDNotesコマンドを受信したかどうかも確認します。受信した場合は、playLEDNotesを true に設定します。 現在の時刻をマークします。この時間は、playNextLEDNote関数がLEDを曲と同期させるために使用されます。
  • BVSP_modeChanged関数 :この関数は、receive()関数がアウトバウンド方向のモード変更を識別するたびに呼び出されます(サーバー-> Arduino)。わお!!!それは何ですか?! BitVoicerサーバーは、フレーム化されたデータまたはオーディオストリームをArduinoに送信できます。通信があるモードから別のモードに移行する前に、BitVoicerサーバーは信号を送信します。 BVSPクラスはこのシグナルを識別し、modeChangedイベントを発生させます。 BVSP_modeChanged関数で、通信がストリームモードからフレームモードに移行していることを検出すると、オーディオが終了したことがわかり、BVSSpeakerクラスにオーディオサンプルの再生を停止するように指示できます。
  • BVSP_streamReceived関数 :この関数は、receive()関数がオーディオサンプルが受信されたことを識別するたびに呼び出されます。サンプルを取得してBVSSpeakerクラスにキューに入れるだけで、play()関数でサンプルを再現できます。
  • playNextLEDNote関数 :この関数は、BVSP_frameReceived関数がplayLEDNotesコマンドを識別する場合にのみ実行されます。 LEDを制御し、BitVoicerサーバーから送信されたオーディオと同期させます。 LEDをオーディオと同期させ、正しいタイミングを知るために、SonicVisualizerを使用しました。この無料のソフトウェアを使用すると、オーディオウェーブを確認できるため、ピアノのキーが押されたことを簡単に確認できました。また、タイムラインも表示され、この関数で使用されるミリ秒を取得した方法です。ばかげたトリックのように聞こえますが、そうです。オーディオストリームを分析して対応するLEDをオンにすることは可能だと思いますが、それは私の手の届かないところです。

ステップ3:BitVoicerサーバーソリューションオブジェクトのインポート

次に、Arduinoで動作するようにBitVoicerサーバーを設定する必要があります。 BitVoicer Serverには、ロケーション、デバイス、BinaryData、および音声スキーマの4つの主要なソリューションオブジェクトがあります。

場所は、デバイスがインストールされている物理的な場所を表します。私の場合、Homeという場所を作成しました。

デバイスはBitVoicerサーバークライアントです。混合デバイスを作成し、ArduinoDUEという名前を付けて、通信設定を入力しました。 重要 :Arduino DUEでさえ、BitVoicerサーバーがストリーミングするすべてのオーディオサンプルを保存するための少量のメモリを備えています。帯域幅を制限しない場合は、オーディオを保存するためにはるかに大きなバッファが必要になります。このため、バッファオーバーフローが発生したため、通信設定のデータレートを1秒あたり8000サンプルに制限する必要がありました。

BinaryDataは、BitVoicerサーバーがクライアントデバイスに送信できるコマンドの一種です。これらは実際には、コマンドにリンクできるバイト配列です。 BitVoicerサーバーは、そのコマンドに関連する音声を認識すると、バイト配列をターゲットデバイスに送信します。各ピン値に1つのBinaryDataオブジェクトを作成し、ArduinoDUEGreenLedOn、ArduinoDUEGreenLedOffなどの名前を付けました。ソリューションに18個のBinaryDataオブジェクトが含まれることになったので、 VoiceSchema.sof からオブジェクトをダウンロードしてインポートすることをお勧めします。 以下のファイル。

音声スキーマは、すべてが一緒になる場所です。これらは、認識される文と実行するコマンドを定義します。文ごとに、必要な数のコマンドとそれらが実行される順序を定義できます。コマンド間の遅延を定義することもできます。このようにして、ビデオに表示されている一連のアクションを実行することができました。

私の音声スキーマの文の1つは、「小さな曲を再生する」です。この文には2つのコマンドが含まれています。最初のコマンドは、次のコマンドがオーディオストリームになることを示すバイトを送信します。次に、Arduinoは、オーディオの送信中にLEDの「再生」を開始します。オーディオは、自分で録音して2番目のコマンドのオーディオソースとして設定した小さなピアノのジングルです。 BitVoicerサーバーは8ビットのモノラルPCMオーディオ(毎秒8000サンプル)のみをサポートしているため、オーディオファイルをこの形式に変換する必要がある場合は、次のオンライン変換ツールをお勧めします:http://audio.online-convert.com/convert -to-wav。

以下のファイルから、このプロジェクトで使用したすべてのソリューションオブジェクトをインポート(ソリューションオブジェクトのインポート)できます。 1つにはDUEデバイスが含まれ、もう1つには音声スキーマとそのコマンドが含まれます。

ソリューションオブジェクトファイル

  • Device.sof
  • VoiceSchema.sof

ステップ4:結論

どうぞ!すべてをオンにして、ビデオに示されているのと同じことを行うことができます。

以前のプロジェクトで行ったように、BitVoicerサーバーマネージャーでArduinoデバイスを有効にすることで音声認識を開始しました。有効になるとすぐに、Arduinoは利用可能な音声認識エンジンを識別し、BitVoicerサーバーへのオーディオのストリーミングを開始します。ただし、オーディオがBitVoicerサーバーからArduinoにストリーミングされている間、Arduino RXLEDでより多くのアクティビティが表示されるようになりました。

次のプロジェクトでは、もう少し野心的になります。 1つのArduinoにWiFi通信を追加し、他の2つのArduinoをすべて音声で制御します。私はそれらの間のある種のゲームを考えています。提案は大歓迎です!

コード

  • Arduinoスケッチ
Arduino Sketch Arduino
 #include  #include  #include  #include  //オーディオのキャプチャに使用されるArduinoピンを定義します#defineBVSM_AUDIO_INPUT 7 // LEDピンを定義します#defineRED_LED_PIN 6#define YELLOW_LED_PIN 9#define GREEN_LED_PIN 10 // BVSPにパラメーターとして渡される定数を定義します。マイクオーディオバッファのサイズを定義しますconstint MIC_BUFFER_SIZE =64; //スピーカーオーディオバッファのサイズを定義しますconstint SPEAKER_BUFFER_SIZE =128; //受信バッファのサイズを定義しますconstint RECEIVE_BUFFER_SIZE =2; //新しいグローバルインスタンスを初期化しますBVSPクラスのBVSPbvsp =BVSP(); // BVSMicクラスの新しいグローバルインスタンスを初期化しますBVSMicbvsm =BVSMic(); // BVSSpeakerクラスの新しいグローバルインスタンスを初期化しますBVSSpeakerbvss =BVSSpeaker(); //作成します記録されたサンプルを読み取るために使用されるバッファー// tからBVSMicクラスbytemicBuffer [MIC_BUFFER_SIZE]; //オーディオサンプルを書き込むために使用されるバッファーを作成します// BVSSpeakerクラスに書き込みますbytespeakerBuffer [SPEAKER_BUFFER_SIZE]; //送信されたコマンドを読み取るために使用されるバッファーを作成します// BitVoicerサーバーから。//バイト0 =ピン番号//バイト1 =ピン値バイトreceiveBuffer [RECEIVE_BUFFER_SIZE]; //これらの変数は、いつ再生するかを制御するために使用されます//「LEDノート」。これらのノートは、// BitVoicerServerからストリーミングされた曲と一緒に再生されます。boolplayLEDNotes=false; unsigned int playStartTime =0; void setup(){//ピンモードを設定しますpinMode(RED_LED_PIN、OUTPUT); pinMode(YELLOW_LED_PIN、OUTPUT); pinMode(GREEN_LED_PIN、OUTPUT); //すべてのLEDの初期状態を設定しますdigitalWrite(RED_LED_PIN、LOW); digitalWrite(YELLOW_LED_PIN、LOW); digitalWrite(GREEN_LED_PIN、LOW); // 115200 bpsでシリアル通信を開始しますSerial.begin(115200); //通信に使用されるArduinoシリアルポートを設定します。//ステータスリクエストがタイムアウトするまでにかかる時間と//ステータスリクエストをBitVoicerサーバーに送信する頻度を設定します。 bvsp.begin(Serial、STATUS_REQUEST_TIMEOUT、STATUS_REQUEST_INTERVAL); // frameReceivedを処理する関数を定義します//イベントbvsp.frameReceived =BVSP_frameReceived; // modeChangedを処理する関数を設定します//イベントbvsp.modeChanged =BVSP_modeChanged; // streamReceivedを処理する関数を設定します//イベントbvsp.streamReceived =BVSP_streamReceived; // BVSMicクラスタイマーを準備しますbvsm.begin(); // BVSSpeakerクラスで使用されるDACを設定しますbvss.begin(DAC);} void loop(){//ステータス要求間隔が経過したかどうかを確認し、経過した場合は// BitVoicerサーバーにステータス要求を送信しますbvsp.keepAlive(); //シリアルポートバッファに利用可能なデータがあるかどうかを確認し、// BitVoicerサーバープロトコルの仕様に従って//そのコンテンツを処理しますbvsp.receive(); //使用可能なSREが1つあるかどうかを確認します。ある場合は、//録音を開始します。 if(bvsp.isSREAvailable()){// BVSMicクラスが録音していない場合、オーディオ入力を設定し、//録音を開始しますif(!bvsm.isRecording){bvsm.setAudioInput(BVSM_AUDIO_INPUT、DEFAULT); bvsm.startRecording(); } // BVSMicクラスに使用可能なサンプルがあるかどうかを確認しますif(bvsm.available){//ストリームを送信する前に//インバウンドモードがSTREAM_MODEであることを確認しますif(bvsp.inboundMode ==FRAMED_MODE)bvsp.setInboundMode(STREAM_MODE); // BVSMicクラスからオーディオサンプルを読み取りますintbytesRead =bvsm.read(micBuffer、MIC_BUFFER_SIZE); //オーディオストリームをBitVoicerサーバーに送信しますbvsp.sendStream(micBuffer、bytesRead); }} else {// SREは利用できません。 BVSMicクラスが記録している場合、//それを停止します。 if(bvsm.isRecording)bvsm.stopRecording(); } // BVSSpeakerクラスで利用可能なすべてのオーディオサンプルを//内部バッファで再生します。これらのサンプルは、// BVSP_streamReceivedイベントハンドラーで書き込まれます。 //内部バッファに利用可能なサンプルがない場合、何も再生されません。 bvss.play(); // playLEDNotesがtrueに設定されている場合、//音楽と一緒に「LEDノート」を再生します。 if(playLEDNotes)playNextLEDNote();} // frameReceivedイベントを処理しますvoidBVSP_frameReceived(byte dataType、intpayloadSize){//受信したフレームにバイナリデータが含まれているかどうかを確認します// 0x07 =バイナリデータ(バイト配列)if(dataType ==DATA_TYPE_BINARY){// 2バイトを受信した場合は、コマンドを処理します。 if(bvsp.getReceivedBytes(receiveBuffer、RECEIVE_BUFFER_SIZE)==RECEIVE_BUFFER_SIZE){analogWrite(receiveBuffer [0]、receiveBuffer [1]); }} //受信したフレームにバイトデータ型が含まれているかどうかを確認します// 0x01 =バイトデータ型elseif(dataType ==DATA_TYPE_BYTE){//受信したバイト値が255の場合、playLEDNotesを設定し、//現在の時刻をマークします。 if(bvsp.getReceivedByte()==255){playLEDNotes =true; playStartTime =millis(); }}} // modeChangedイベントを処理しますvoidBVSP_modeChanged(){//アウトバウンドモード(サーバー->デバイス)が// FRAMED_MODEになっている場合、オーディオストリームは受信されないはずです。 //内部バッファが空になったときに//再生を終了するようにBVSSpeakerクラスに指示します。 if(bvsp.outboundMode ==FRAMED_MODE)bvss.finishPlaying();} // streamReceivedイベントを処理しますvoidBVSP_streamReceived(int size){// BVSPクラスから受信したストリームを取得しますintbytesRead =bvsp.getReceivedStream(speakerBuffer、SPEAKER_BUFFER_SIZE); //受信したストリームをエンキューして再生しますbvss.enqueue(speakerBuffer、bytesRead);} //時間に基づいて適切なLEDを点灯します// LEDノートの再生を開始するコマンドを受信しました//ここで使用されるタイミングは次のように同期されますmusic.void playNextLEDNote(){// playStartTimeと//現在の時刻の間の経過時間を取得します。 unsigned longlapsed =millis()-playStartTime; //すべてのLEDをオフにしますallLEDsOff(); //最後のノートが再生されました。 //最後のLEDをオフにし、LEDノートの再生を停止します。 if(経過> =11500){analogWrite(RED_LED_PIN、0); playLEDNotes =false; } else if(経過> =9900)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =9370)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =8900)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =8610)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =8230)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =7970)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =7470)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =6760)analogWrite(GREEN_LED_PIN、255); // E注else if(elapsed> =6350)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =5880)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =5560)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =5180)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =4890)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =4420)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =3810)analogWrite(GREEN_LED_PIN、255); // E注else if(elapsed> =3420)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =2930)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =2560)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =2200)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =1930)analogWrite(YELLOW_LED_PIN、255); // D注elseif(elapsed> =1470)analogWrite(RED_LED_PIN、255); // Cはelseに注意しますif(elapsed> =1000)analogWrite(GREEN_LED_PIN、255); // E注} //すべてのLEDをオフにします。voidallLEDsOff(){analogWrite(RED_LED_PIN、0); analogWrite(YELLOW_LED_PIN、0); analogWrite(GREEN_LED_PIN、0);} 

回路図


製造プロセス

  1. PythonでArduinoとRFIDを使用した出席システム
  2. LEDとピエゾスピーカーを備えたDHT11センサー
  3. NeoPixelリングでジャイロスコープを楽しむ
  4. ArduinoTemp。 3.2ディスプレイを備えたモニターとリアルタイムクロック
  5. ArduinoとAndroidデバイスでルンバロボットを制御する
  6. ArduinoとNokia5110ディスプレイを備えたDIY電圧計
  7. ArduinoとMPU6050によるサーボモーターの制御
  8. u-blox LEA-6H 02GPSモジュールとArduinoおよびPython
  9. DHT11でBlynkの温度と湿度を読み取る方法
  10. ArduinoUnoと1sheeldを備えた4x4x4LEDキューブ
  11. GPSおよびTFTディスプレイシールドを備えたGPSロケーションディスプレイ