勝手な電子工作・・

勝手なオリジナル電子工作に関する記事を書きます

音声認識モジュールLD3320(Arduino Unoで)

f:id:a-tomi:20210927203533j:plain

音声認識スマホやアレクサ等々で普及しまくりましたが、マイコンでやろうとするとあまり簡単ではありません・・と思っていました。

今回試すのはvoice recognitionではなくspeech recognitionなのですが、日本語訳だとどちらも「音声認識」になるようです(・・?

「voice recognitionとspeech recognitionは明確に違う」と、例えば次のリンク先では英語で言っいるのですが、・・

https://www.totalvoicetech.com/difference-between-voice-recognition-and-speech-recognition/

ブラウザで翻訳すると「音声認識音声認識は違います・・・」と訳されるのでワケワカメ^^;

バイオメトリクス的な応用か、言っていることを解釈するのか、という違いでしょうが、今回はスピーチ認識。

LD3320モジュールは、話し手を選ばずに語句の識別と照合をしてくれるという、都合のよい音声認識モジュールです。

f:id:a-tomi:20210927204459j:plain

LD3320という専用 ICのブレークアウトモジュールで、内蔵マイク、外部マイク端子やスピーカー端子がついているもの。海外ネットでは千円強で買え、今見たら次のような感じです。

f:id:a-tomi:20210927204956j:plain

ICには"IC route"という社名が書かれているので検索してみると、ホームページがあってこの製品のデータシートやユーザーマニュアル類だけでなく、フォーラム風の情報も満載。全て中国語ですが今やブラウザーが上手に訳してくれるので十分使えますね。

IC routeのホームページは次で、この企業は主に音声認識ICを作っている会社のようです。

http://www.icroute.com/

LD3320モジュールはマイコンとSPIで接続しますが、信号は3.3Vでなければいけません。Unoの場合は、面倒でも5V~3.3Vの信号レベルコンバータを介します。8チャネルある次のコンバーターを使いました。CSをグランドに落とすだけにして節約しても信号5本は要るので、4チャネルでは無理そうですね。

f:id:a-tomi:20210927210042j:plain

接続の様子は次の写真のとおりですが、後ろにつけるプログラムをご覧いただくと明確でわかりやすいかと思います。

f:id:a-tomi:20210927210254j:plain

テストでは、Arduino-IDEのシリアルモニターで表示をしますが、一応LED4色で単純な表示もしてみます。

解釈する音声は50種までで、プログラムの立ち上がりで装置へ与えます。中国語ベースのためPinYin(といってもアクセントや抑揚はない)で入れます。

日本語や他の言語でも近い表現を入れれば認識できるというわけです。この例では「ありがとう」をいれたらバッチリでした。発音をWebでチェックしながら恐る恐るいれてみましたが^^; 

しかし、英語を入れるのはかなり難しいですね。英語はメロディ的でリズム感を要し、日本語のように子音母音だけでは決められない点、それに子音で中国語にはない発音も多いからでしょうかね。

Web検索しても英語の使用例にはたどり着かないのはそのためかも。

今回テストをしてみると、中国語はもちろん日本語も意外によく判定します。抑揚やアクセントの設定をとくにしないのに、よくもこんなことができるものです!

youtu.be

ほぼ何でも正しく解釈されるのに驚きますが、プログラムでいれてみた中国語の「黄色」の発音だけはうまく認識せず、結局スキップして別の表現を考え中。

今回作ったArduino Unoのスケッチは次です。語彙の登録も判定も全てLD3320内部でやってくれるので、マイコン側はとても小さな処理てすみます。

/********************************************************
   Speech-recognition test with LD3320 module
        V.01  Sept.25, 2021 by Akira Tominaga
   - Modified sample sketch of ld3320 library V2.0 at
     https://www.waveshare.net/study/article-11-1.html
    - Pin connections from LD3320 to Arduino Uno:
     Gnd-Gnd, 3V3-3.3V, all signal levels to be <=3.3V*
     MO-11, MI-12, SCK-13, CS/NSS-4, RST-9, IRQ-2, WR-Gnd
   - *Remarks: Logic Level Converter is required for Uno.
          As for LD3320, refer to http://www.icroute.com/
 ********************************************************/
#include "ld3320.h"   // installed from the above URL
VoiceRecognition Vc;  // voice recognition class as Vc
// LED sequence
#define LEDr 5        // LED red
#define LEDg 6        // LED green
#define LEDy 7        // LED yellow
#define LEDb 8        // LED blue
void setup() {        // ***** Arduino setup() *****
  pinMode(LEDr, OUTPUT); pinMode(LEDg, OUTPUT);
  pinMode(LEDy, OUTPUT); pinMode(LEDb, OUTPUT);
  digitalWrite(LEDr, LOW); digitalWrite(LEDg, LOW);
  digitalWrite(LEDy, LOW); digitalWrite(LEDb, LOW);
  Serial.begin(9600);
  Serial.println(F("Say keywords.."));
  Vc.init();                          // initialize Vc
  // key word, ID# (max.50, same ID# can be shared)
  Vc.addCommand("kai deng", 0);       // 開燈lights on
  Vc.addCommand("guan deng", 1);      // 關燈lights off
  Vc.addCommand("ohl ong", 0);        // all on
  Vc.addCommand("ohl off", 1);        // all off
  Vc.addCommand("hong se", 2);        // 紅色red
  Vc.addCommand("lu se", 3);          // 緑色green
  Vc.addCommand("huang se", 4);       // 黄色yellow
  Vc.addCommand("lan se", 5);         // 藍色blue
  Vc.addCommand("xie xie", 6);        // 謝謝
  Vc.addCommand("tank yu", 6);        // thank you
  Vc.addCommand("ahligatoh", 6);      // arigatoh
  Vc.start();                         // start Vc
}
void loop() {         // ***** Arduino loop() *****
  switch (Vc.read()) {
    case 0: Serial.println(F("On"));  // all LEDs on
      digitalWrite(LEDr, HIGH); digitalWrite(LEDg, HIGH);
      digitalWrite(LEDy, HIGH); digitalWrite(LEDb, HIGH);
      break;
    case 1: Serial.println(F("Off")); // all LEDs off
      digitalWrite(LEDr, LOW); digitalWrite(LEDg, LOW);
      digitalWrite(LEDy, LOW); digitalWrite(LEDb, LOW);
      break;
    case 2: Serial.println(F("red")); // LEDr on
      digitalWrite(LEDr, HIGH); break;
    case 3: Serial.println(F("green")); // LEDg on
      digitalWrite(LEDg, HIGH); break;
    case 4: Serial.println(F("yellow")); // LEDy on
      digitalWrite(LEDg, HIGH); break;
    case 5: Serial.println(F("blue")); // LEDb on
      digitalWrite(LEDb, HIGH); break;
    case 6: Serial.println(F("thanks"));
      for (uint8_t i = LEDr; i < LEDb + 1; i++) { // blink LEDs
        digitalWrite(i, HIGH);
        delay(500);
        digitalWrite(i, LOW);
        delay(500);
      }
      break;
    default: break;
  }
} // ***** end of program *****

日本語をPinYin表示するのは、中国語の心得がある人にとっては簡単なことかもしれませんが、中国語を勉強したことがない自分にとっては結構難しい。

そこで、Google翻訳の中国語欄にローマ字で日本語をいれて、中国語として発音させ、それらしく聞こえる綴りに変えてやってみたものです^^;

こうなるとせめてPinYin表だけでも勉強するのが良いかなと考え中。それと、メーカーのHPの中の説明には次のような記述があります。英語で使おうとするのはやめた方がいいかもしれません。

f:id:a-tomi:20210927212447j:plain

 

今回はマイコンで手軽にできる音声認識でした。作業で両手がふさがっているときの簡単な入力装置にすると便利そうです。

 

以上、何らかのお役にたてば幸いです。

 

©2021 Akira Tominaga, All rights reserved.