學習目標 : 認識faya語音辨識模組的功能及使用方式
學習時間 : 45min
示範模組 : (1) faya brickNano
(2) faya 語音辨識模組
(3) faya RGB LED模組
工具 : (1) 樂高積木底板 (相容)
====================功能介紹====================
faya語音辨識模組採用了ICRoute公司所開發的語音辨識晶片(LD3320),該晶片內建語音辨識DSP和一些外部電路,包含AD/DA轉換器,麥克風和音源輸出介面等等.....這顆晶片不需要外接任何的記憶體如Flash、RAM等,最大的特點在於可以針對非特定用戶的語音做辨識,不需要事先進行錄音訓練,最多可編輯50組關鍵詞,用戶可以根據場地需要,隨時編輯和更新關鍵詞內容,方便電子產品中實現聲控、人機對話功能。
感測器如上圖所示,利用左方的麥克風收音,對外溝通的腳位包含IRQ / NSS / RST / MOSI / MISO / SCK / WR,右方用了兩排的排母強化其結構穩定,訊號埠左右兩邊是相連的,除了WR埠,其左邊的排母連接WR腳位,右邊的排母連接GND,原因是因為在進行語音辨識時,WR需要接地,因此我們用一個短跳線將其連接起來,如此可以減少一條單心線。
本晶片所提供的Arduino函式庫已經先定義好每個訊號埠所連接的腳位了,因此使用時不需要在主程式中再次定義腳位,預設腳位如下:
如果有需要重新定義腳位 (RST和NSS),請在修改函式庫內的ld3320.cpp,前幾行的地方就可以重新定義 RST 和 NSS (CS)的腳位。
使用此模組的方式非常簡單,該模組首先會將所辨識的中文語音轉成漢語拼音,然後在我們建好的關鍵詞庫內進行比對,如果結果一致,就會輸出相對應的指令。因此使用者所需要的動作就是在程式內建立漢語拼音的識別列表,做多支援50組,每組列表用標準普通話的漢語拼音(小寫),每兩個字中間要空格隔開,舉例如下 :
漢語拼音大家可以在這個網址查詢,只要輸入中文,就會列出對應的漢語拼音方式 (國音第二式):
逗號後方的編號用來代表所辨識的語音,編號可以相通,可以不連續,但是數值要小於256。以上識別列表需在setup()中完成,之後我們只要在loop()中下.read()指令,就會讀出以辨識成功的編號。
有興趣了解更多細部功能的讀者,可以參考其Datasheet。
====================原理知識====================
以下解釋提供給有需要知道背後原理的人:
faya語音辨識模組的電路圖如下,LD3320晶片裡面還有MCU的GPIO腳位、MP3錄製和撥放的等功能,但為了模組的單純避免失焦,我們只把和語音辨識模組有關的腳位拉出來。
===================範例實作(1)===================
了解模組功能(原理)後,我們用以下範例來展示模組的功能:
目標:
(1) 建立語音指令控制RGB的LED燈。
接線:
(1) 電源線連接
如下圖所示,連接的說明請看這篇文章 或簡易版
(2) 訊號線連接
RGB LED模組:
Arduino_A3 ===> RGB LED模組_A3
Arduino_A2 ===> RGB LED模組_A2
Arduino_A1 ===> RGB LED模組_A1
語音辨識模組:
Arduino_D2 ===> 語音辨識模組_IRQ
Arduino_D4 ===> 語音辨識模組_NSS
Arduino_D9 ===> 語音辨識模組_RST
Arduino_D11 ==> 語音辨識模組_MOSI
Arduino_D12 ==> 語音辨識模組_MISO
Arduino_D13 ==> 語音辨識模組_SCK
語音辨識模組_GND ==> 語音辨識模組_WR
範例程式:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 2018/10/31 | |
// Faya-Nugget 範例程式 (Voice_Recog_1.ino) | |
// 單元: 模組介紹: faya語音辨識模組 | |
// 網址: https://fayalab.blogspot.com/2018/11/voice-recog.html | |
// 目標: (1) 利用語音指令控制RGB LED燈 | |
// 接線: Arduino ==> faya模組 | |
// D2 ==> IRQ (語音辨識模組) | |
// D4 ==> NSS (語音辨識模組) | |
// D9 ==> RST (語音辨識模組) | |
// D11 ==> MOSI (語音辨識模組) | |
// D12 ==> MISO (語音辨識模組) | |
// D13 ==> SCK (語音辨識模組) | |
// GND ==> WR (語音辨識模組) | |
#include <ld3320.h> // 引入ld332語音辨識函式庫 | |
VoiceRecognition fayaVoice; //聲明語音識別對象 | |
#define R_pin A3 // R ELD 接到A3 | |
#define G_pin A2 // G ELD 接到A2 | |
#define B_pin A1 // B ELD 接到A1 | |
int command; //儲存指令 | |
void setup() | |
{ | |
pinMode(R_pin, OUTPUT); // 設定RGB_Pin為輸出腳位 | |
pinMode(G_pin, OUTPUT); | |
pinMode(B_pin, OUTPUT); | |
digitalWrite(R_pin, LOW); // 先把燈全部關閉 | |
digitalWrite(G_pin, LOW); | |
digitalWrite(B_pin, LOW); | |
Serial.begin(9600); // Arduino串列埠baudRate = 9600 | |
fayaVoice.init(); // 初始化語音辨識 | |
fayaVoice.addCommand("kai deng",0); // 添加指令 [開燈] | |
fayaVoice.addCommand("liang hung deng",1); // 添加指令 [亮紅燈] | |
fayaVoice.addCommand("da kai hung se deng",1); // 添加指令 [打開紅色燈] | |
fayaVoice.addCommand("bian liu se ",2); // 添加指令 [變綠色] | |
fayaVoice.addCommand("lan deng",3); // 添加指令 [藍燈] | |
fayaVoice.addCommand("huang se de deng",4); // 添加指令 [黃色的燈] | |
fayaVoice.addCommand("guan deng",5); // 添加指令 [關燈] | |
fayaVoice.start(); //開始識別 | |
} | |
void loop() { | |
check_b2(); //檢查資料接收是否穩定 | |
command = fayaVoice.read(); //指令儲存至command變數 | |
switch(command) //執行指令 | |
{ | |
case 0: //指令0 =“開燈” | |
Serial.println("TURN ON"); | |
digitalWrite(R_pin, HIGH); | |
digitalWrite(G_pin, HIGH); | |
digitalWrite(B_pin, HIGH); | |
break; | |
case 1: //指令1 =“亮紅燈”/ "打開紅色燈" | |
Serial.println("RED ON"); | |
digitalWrite(R_pin, HIGH); | |
digitalWrite(G_pin, LOW); | |
digitalWrite(B_pin, LOW); | |
break; | |
case 2: //指令2 =“綠色燈" | |
Serial.println("GREEN ON"); | |
digitalWrite(R_pin, LOW); | |
digitalWrite(G_pin, HIGH); | |
digitalWrite(B_pin, LOW); | |
break; | |
case 3: //指令3 =“藍燈” | |
Serial.println("BLUE ON"); | |
digitalWrite(R_pin, LOW); | |
digitalWrite(G_pin, LOW); | |
digitalWrite(B_pin, HIGH); | |
break; | |
case 4: //指令4 =“黃色的燈” | |
Serial.println("Yellow ON"); | |
digitalWrite(R_pin, HIGH); | |
digitalWrite(G_pin, HIGH); | |
digitalWrite(B_pin, LOW | |
); | |
break; | |
case 5: //指令5 =“關燈” | |
Serial.println("TURN OFF"); | |
digitalWrite(R_pin, LOW); | |
digitalWrite(G_pin, LOW); | |
digitalWrite(B_pin, LOW); | |
break; | |
} | |
} |
備註:
-L32~38 : 在setup區塊內,先建立識別列表,可以到羅馬拼音查詢系統網站查詢漢語拼音。注意到我刻意把語音命令從兩個字測試到五個字,並且讓[亮紅燈]和[打開紅色燈]的語音指向同一命令。
-L43: check_b2函式用來檢查暫存器B2的狀態 (DSP是否忙碌),datasheet有提到,當電路的地流出現不穩定或較大波動時,有小機率會出現內部晶片出錯,因此需要用此函示確認是否正常運作,如出錯時,則重置晶片。
-L44 : 利用fayaVoice.Read()讀取比對到的語音命令
-L45~88 : 利用switch指令執行所比對到的語音命令,透過Arduino的RGB的腳位點亮相關的LED。三原色的配置圖如下給各位參考。
範例結果:
討論:
- 本範例的語音辨識模組無時不刻的都在收音辨識,因此很容易地把背景音也辨識進去,我們建議多增加一個實體開關和一段小程式,用來當作啟動語音辨識的功能,也就是當壓著開關的時候,才進行語音辨識,如此一來,平常時刻就不會把不想要的聲音收音辨識了。
- 經過我們的測試,由於此晶片不需要事先經過錄音訓練,因此辨識的能力如果發音太接近時,還是會有誤判的可能,因此設定辨識列表前,儘量把發音相似的語詞避開,例如[紅燈]和[黃燈]兩詞遇到誤判的機會大很多,因此可以把語音設成[紅色燈] / [點亮黃燈] 來區別。
歡迎大家在底下留言或到我們的粉絲團留言喔!
====================================
不錯, 你作的很好, 全部都參考你的, 謝謝
回覆刪除