牟曉東
在很多的開源硬件編程創(chuàng)客作品中都會用到“語音識別”控制功能,比如通過“小度小度”等喚醒詞來實現(xiàn)語音命令的喚醒與傳送,目前大部分的語音識別功能都離不開網(wǎng)絡(luò)支持(像百度智能云)。其實,我們還可以通過離線語音模塊(比如好好搭搭的ASR-THREE)來實現(xiàn)語音識別,優(yōu)點是響應(yīng)速度非常快,而且支持中英文甚至是方言語音命令的訓(xùn)練學(xué)習(xí)與應(yīng)用。如果想要設(shè)計制作一個Arduino“聲控門”,用戶通過發(fā)出“請開門!”、“請關(guān)門!”的語音指令來控制舵機進(jìn)行開關(guān)門的動作,如何來實現(xiàn)呢?
實驗裝置包括Arduino UNO開發(fā)板一塊,ASR-THREE離線語音模塊一個,SG90舵機一個,紅色、綠色LED燈各一支,小型面包板一個,各種顏色的杜邦線若干。
首先,通過紅色和黑色兩根杜邦線,將Arduino的5V和GND端分別連接至面包板的側(cè)邊(標(biāo)注有“+”紅色和“-”藍(lán)色長線);接著,將ASR-THREE離線語音模塊的V(電源正極)和G(接地端)連接至面包板的電源正極和負(fù)極,再將S(Signal)信號端連接至Arduino的3號引腳;然后,將SG90舵機的電源正極和接地端同樣也連接至面包板的電源正極和負(fù)極,再將信號端連接至Arduino的10號引腳;最后,將紅色和綠色LED燈的負(fù)極(“短腿”)均插入面包板的負(fù)極,正極(“長腿”)則分別通過杜邦線連接至Arduino的13號和12號引腳(如圖1)。
默認(rèn)情況下,ASR-THREE離線語音模塊提供了50多條包括“學(xué)習(xí)命令”、“喚醒詞”和“命令詞”在內(nèi)的語音指令,每條語音指令均對應(yīng)一個十進(jìn)制的ID號,比如命令詞“打開燈光”的ID號是70、“減小音量”的ID號是104等等。由于在設(shè)計制作的Arduino“聲控門”項目中需要的語音命令詞是“請開門!”和“請關(guān)門!”,因此需要進(jìn)行自定義訓(xùn)練ASR-THREE離線語音模塊進(jìn)行“學(xué)習(xí)”,方法如下:
將Arduino的數(shù)據(jù)線連接至電腦的USB接口,很快就有“歡迎使用語音識別助手!”的語音提示;接著,對著離線語音模塊的麥克風(fēng)說出任意一條喚醒詞——比如“智能管家”,離線語音模塊回答“我在呢!”;再說:“學(xué)習(xí)命令詞”,回答:“學(xué)習(xí)狀態(tài)中,保持安靜,請按提示學(xué)習(xí)命令詞,請說出第一條要學(xué)習(xí)的指令”,再說:“請開門!”,回答:“學(xué)習(xí)成功,請再說一次”;按照提示,最終完成該語音指令命令詞的訓(xùn)練學(xué)習(xí)。同樣的操作,再訓(xùn)練完成對“請關(guān)門!”語音指令的學(xué)習(xí),對應(yīng)的ID號分別是53和54(如圖2)。
為了進(jìn)行串口數(shù)據(jù)傳輸及控制舵機的操作,需要先通過“#include
在setup()函數(shù)中,先設(shè)置串口通訊的波特率為115200:“mySerial.begin(115200)”;再將兩支LED燈的工作模式設(shè)置為輸出:“pinMode(RedLED,OUTPUT)”、“pinMode(GreenLED,OUTPUT)”;最后,聲明舵機的數(shù)據(jù)線連接在Arduino的10號引腳:“myservo.attach(10)”(如圖3)。
先來編寫open_door()“開門”函數(shù):當(dāng)收到“請開門!”語音指令時,首先控制紅色LED燈亮:“digitalWrite(RedLED,HIGH)”;然后,通過一個for()循環(huán)結(jié)構(gòu)(“for(pos=0;pos<=90;pos+=1)”)來實現(xiàn)舵機的旋轉(zhuǎn)角度由0°逐漸遞增為90°:“myservo.write(pos)”,并且在每次旋轉(zhuǎn)增加1°后進(jìn)行20毫秒的延時:“delay(20)”;最后,控制紅色LED燈熄滅、綠色LED燈發(fā)光:“digitalWrite(RedLED,LOW)”、“digitalWrite(GreenLED,HIGH)”。
接著,編寫close_door()“關(guān)門”函數(shù),與open_door()函數(shù)非常類似,比如for()循環(huán)控制舵機由90°旋轉(zhuǎn)恢復(fù)至0°(“for(pos=90;pos>=0;pos-=1)”)、控制紅色和綠色LED燈的亮或滅,等等(如圖4)。
loop()主函數(shù)非常簡單,通過if()語句來判斷串口是否有新數(shù)據(jù)產(chǎn)生:“if (mySerial.available() > 0)”;如果有新數(shù)據(jù)產(chǎn)生,說明收到了某條語音指令,通過switch多分支結(jié)構(gòu)(“switch (mySerial.read())”)來對語音指令的對應(yīng)ID號進(jìn)行判斷——如果ID號是53,說明收到的語音指令是“請開門!”,則執(zhí)行open_door()函數(shù);如果ID號是54,說明收到的語音指令是“請關(guān)門!”,則執(zhí)行close_door()函數(shù)。
將程序保存為Sound_Door.ino,上傳至Arduino進(jìn)行測試。先通過“智能管家”喚醒詞進(jìn)行喚醒,再發(fā)出“請開門!”語音指令,紅色LED燈亮、舵機由0°旋轉(zhuǎn)至90°、紅色LED燈熄滅、綠色LED燈發(fā)光;接著再發(fā)出“請關(guān)門!”語音指令,綠色LED熄滅、紅色LED燈發(fā)光、舵機由90°旋轉(zhuǎn)至0°、紅色LED燈熄滅;反復(fù)測試,均能實現(xiàn)語音指令控制舵機正反轉(zhuǎn)開關(guān)門的功能(如圖5)。
啟動Mind+,首先點擊“擴展”按鈕進(jìn)行主控板中“Arduino Uno”、執(zhí)行器中“舵機模塊”和用戶庫中“離線語音識別模塊”的添加;點擊“返回”按鈕后開始圖形化的編程:
同樣也是先編寫“開門”和“關(guān)門”兩個函數(shù),包括紅色和綠色LED燈的開關(guān)及舵機的旋轉(zhuǎn)控制;然后再進(jìn)行主程序的編寫,包括語音識別的初始化和串口波特率的設(shè)置,同樣也是在循環(huán)結(jié)構(gòu)中先進(jìn)行語音識別是否有數(shù)據(jù)可讀的判斷,然后通過變量Order_ID來存儲語音識別的讀取數(shù)據(jù)并判斷其數(shù)值——如果是53,則調(diào)用執(zhí)行“開門”函數(shù);如果是54,則調(diào)用執(zhí)行“關(guān)門”函數(shù)(如圖6)。
將程序保存為Arduino“聲控門”.sb3,點擊“連接設(shè)備”后再進(jìn)行程序的上傳測試,效果與使用Arduino IDE進(jìn)行代碼編程的測試一致。