此篇文章約5000字,看完需10分鐘。乾貨滿滿,加油讀完
先來直接看視頻↓
Pico是一個數量級單位,也即10^-12(中文叫做皮)。大家都知道我對小巧精緻的東西有著執著的追求😉以往的作品中mini、nano之類字眼的已經都使用過了,所以這次找到了Pico來作為名稱。
可真是聰明啊!
按照這個(並不)巧妙的命名套路,相信大家已經可以預見我未來作品中的詞彙量了😃。其實還有一個更合理的原因,p-i-c-o的發音清脆,音節突出,語音喚醒的成功率會更高,所以拿來做喚醒詞實在是墜吼的啦。
「你好,Pico!」
首先我們得搞清楚一件事情,我到底要做一個什麼樣的語音助手,實現那些功能呢?
等等不對😂我為什麼要做個語音助手啊,市面上不是已經有海量各種智能音箱了嘛?何必重複造輪子呢?
事情是這樣的,由於我毫無理由地相信物聯網和人工智慧結合是未來智能家居的方向,而以目前的狀況來看智能音箱很可能成為其中一個重要的入口。被亞馬遜Echo帶的頭,各大廠商紛紛跟進推出了自己的音箱產品:外有GoogleHome 、蘋果HomePod,內有天貓精靈、小愛同學…
實際上這些音箱的功能上都大同小異,無非是整合別人或自家生態鏈產品,作為一個智能設備控制中心,這很好,然後再外帶一些娛樂功能。
但是說實話本人並不看好現階段AI音箱的各種對話功能,聊天?你又不是不知道Siri有多蠢所有的產品都有工具屬性,在工具屬性之上才能延展出來娛樂屬性。而由於目前市場上大多數智能音箱背後的AI程度都還不足以讓它們真正地實現「合理對話」,因此個人認為,現階段能做好一個「工具」,就是我對一個智能音箱該有功能的全部期待了。
關於這一點,個人試用過以上幾乎所有音箱,在功能性上做的最好的我認為是依託米家生態鏈的小愛同學。
那就買買買,小愛同學入手!
但隨後殘酷的現實給了我狠狠的一jio。原本我已聽信發布會宣傳準備註冊好小米IoT平臺開發者帳號,想展現真正的技術把小愛同學改造成對我言聽計從的私人助理了(當然是指接入我自己的硬體)
結果:
好吧,看來只面向企業的,不過這也可以理解,畢竟米家走的精品路線,個人開發者水平參差不齊不利於品牌維護。造輪子去😤
實際上對於接入自定義硬體,也就是說系統開放性這一項上面,Echo相對來說是做的比較好的,Github上也有很多教你如何接入Alexa平臺的教程和開源項目。但是呢,由於某些不可抗力的網絡原因,Alexa在國內的使用並不是很順利。
以上種種原因,加上個人好奇心驅使,便有了這次製造Pico的企劃。廢話不多說,下面直接貼一張功能設計和擬用技術路線的思維導圖(點擊圖片可放大)↓
以上功能的重心是實現語音的TTS和ASR功能,並且通過識別結果回調接口配合Mqtt協議來接入並控制各種自定義的硬體。其餘功能屬於錦上添花,會在日後有空的時候慢慢完善。
概括一下,Pico主要有以下特點:
Pico的結構設計草圖↑
對於Pico的ID設計之前想過好幾種方案:
使用鋁合金CNC加工,做成類似魔方的正方體外殼樣式
使用DLP樹脂3D列印,設計成類似天貓精靈的迷你版圓柱體外殼,以光固化列印的精度也能達到不錯的質感
使用透明亞克力切割成形,設計為三明治夾層式的堆疊設計,這也是我最終採用的方案
最終選擇亞克力作為外殼結構有幾個原因:
其一是該方案的「視覺極客感」最強,由於直接使用透明蓋板將PCB電路展現出來,個人覺得顏值方面化繁為簡,符合個人審美哲學
其次是對於CNC加工和3D列印在之前的作品中都已經有所使用,而亞克力設計方式還是第一次接觸,嘗試未知技術是很重要的一個考量因素
其三是由於整體體積非常緊湊小巧,因而如果使用封閉式設計的話散熱就變成需要考量的因素了,而夾層式的開放設計則在這方面完全無需擔心
最後一個原因是,亞克力便宜
如上面草圖所示,結構主要為三層:亞克力前蓋、PCB電路板、亞克力後蓋,使用M2的滾花軸銅柱進行組合連接,其中前板採用熱彎折的方式彎折10度左右形成底座,後方走USB線。
機械結構的設計使用Rhinoceros完成,該軟體個人使用了3年多的時間,覺得還是非常順手的。
當初並沒有選用公認更專業和更常用的Solidworks和ProE等三維設計軟體來學習,純粹是因為當時用的超極本性能太渣帶不動,而看重了Rhino只有幾百兆的安裝包而已😂。但是畢竟本人也非機械專業,對於EDA工具來說只要能幫助我實現我的想法就滿足了,更何況工具只是工具,更重要的是創意和設計思想,而這些是只有多開腦洞多做項目才能有所精進的。
亞克力厚度使用的2mm, 找了個小夥伴操作工具機雕刻成型, 然後用電烙鐵加熱彎折。值得注意的是亞克力的熔點是300度左右,但100度左右的時候就會變軟了,因此這裡將烙鐵溫度設定為100度,不帶調溫功能的烙鐵是不能直接拿來操作的。
使用工具機雕刻的亞克力外殼
使用電烙鐵進行熱彎
硬體電路方面,有之前MiniPi的完整項目在前,這裡當然就直接利用起來啦。(下圖為MiniPi渲染圖,喜歡的可以拿去做壁紙😉 )
MiniPi作為核心板,運行Linux系統,mini-PCIE的金手指封裝引出了需要的IO。
這裡Pico主要使用到兩個USB接口(一個接USB音效卡,一個接無線網卡),串口(用於調試和控制臺輸出),幾個GPIO(用於驅動按鍵和LED),I2C接口(保留,後期可能會用於和板載的Arduino通信,Arduino用於驅動一些外圍交互模塊如紅外感應、手勢識別等),此外OLED也是使用I2C接口驅動的。
由於底板的功能比較簡單,主要就是作接口擴展,因此底板的PCB採用2層Layout。板載的IC主要有:
OLED12864,驅動IC為SSD1306,這個應該屬於很常用了
PCM2912A,TI出的USB接口音效卡(很貴,30多一片,價格快趕上用的CPU了),音質還是不錯的
CP2102,USB轉串口晶片,也很常用,通過USB線把Pico連接電腦之後,就可以直接用串口控制臺使用Linux了
LM4871,功放IC,用於音頻放大然後揚聲器輸出
USB-Type C母座,USB接口當然是使用我最愛的Type C啦,話說我把身邊的電子產品能再改造的都改成Type C接口了,舒服了😆
Pico底板原理圖,比較簡單
PCB的設計當然還是使用Altium Designer,AD忠實粉,軟體最近升級了18以後UI炫酷程度爆表,感受一下↓
Altium Designer 18軟體設計
底板的設計沒有太多可講的,兩層板走線很隨意,也沒有高速器件,USB那邊做好差分走線就行,最好再加上ESD(本版屬於功能驗證性質就沒加了)。音效卡方面經過試驗耦合電容的選擇對聲音效果還是有一些影響的,但是音質方面屬於玄學,個人就不深究了~
核心板的介紹在我之前文章裡有講解,感興趣的可以看這篇(如何自製一塊「樹莓派」--DIY ARM-Linux卡片電腦)
這次的Pico上用的MiniPi核心板做了微調,之前一共做過兩版:第一版由於是初次設計高速多層板,雖然功能沒問題,但是有不少小缺陷,比如電源電路BUG、沒有加板載的關機按鍵、音頻電路沒有做數字地和模擬地的隔離等等;第二版則是做了一些IO調整;第三版是比較穩定了,但是考慮到把SD卡設計在核心板上可能會在一些項目中不太方便更換(被夾在核心板和地板中間了),因而在金手指上添加了外置SD卡的接口。
話說我後來才知道原來Altium也是自帶VCS(版本控制系統)的,類似於寫軟體的時候用的Git,Altium也可以很方便地控制每個文件的版本–提交更新、恢復版本、切換分支…這麼好的特性看來後面要好好利用上了,這之前我都還在傻夫夫地用著壓縮包備份大法。
MiniPi的CPU和DDR部分的電路如下,濾波電容非常多,CPU這樣極高頻率的器件對電源的純淨度要求很高,要儘量保證每個電源腳都有一個濾波電容↓
CPU部分外圍電路
PCB投板回來之後就是藍翔技能施展階段了,主要用到的工具有:熱風槍、烙鐵、鑷子、錫漿、吸錫帶、助焊劑等。這裡科普一下貼片元件的焊接方法:與直插元件不同,貼片的器件由於焊盤太小(我用的0402阻容),器件分布太密集,是基本不可能用烙鐵一個一個去焊接的,手工焊接採用的方法主要是回流焊。
所謂回流焊,其實就是利用液體的張力,讓融化之後的液態錫把器件拉到焊盤中央完成焊接,不太理解的可以百度搜索一下「回流焊」。進行回流焊的第一步是製作鋼網,也就是器件焊盤的掩模,這個在設計好PCB之後把相關的加工文件發給廠家就可以進行雷射切割製作了,價格也不貴一般50左右。
PCB鋼網掩膜
把空PCB對準鋼網掩模之後就可以刮上錫漿了,這樣就完成了一次性對所有的焊盤上錫。然後把元件都按設計擺放上到PCB上,這一步不需要講位置擺的非常準確因為再下一步回流的時候器件會由於液態錫的張力自動歸位的。
上好錫膏的PCB板子
上一步貼片完成之後就需要用風槍進行吹焊回流了,相對於一般的器件來說BGA的吹焊難度要大很多因而將其放在最後焊接。吹焊溫度大概控制在250-300度,風槍的吹嘴去掉以增大風口便於均勻加熱,這一步對焊接經驗要求較高,只能多練習嘗試掌握技巧了。
風槍吹焊
底板的焊接相對簡單,就不多羅嗦了,焊接完畢之後首先用萬用表測電源是否短路,沒問題的話上電檢測電壓,沒有BUG的話就可以進行功能測試了。
焊接成品
硬體搞定之後就開始移植軟體啦,MiniPi核心板運行的是Debian系的Ubuntu系統,完全兼容樹莓派的各種軟體,所以可以利用上很多優秀的開源資源。軟體的實現上也參考了另外一個基於樹莓派的智能音箱項目叫做叮噹,主頁在這裡(叮噹dingdang.hahack.com)
整個軟體框架借鑑了Jasper項目。
軟體主要分為以下幾個模塊:
ASR模塊(AutomaticSpeech Recognition,語音識別),用於獲取用戶的指令,其中包括語音喚醒功能
TTS模塊(Text-To-Speech,語音合成),用於給出語音應答
NLP模塊(NaturalLanguage Processing,自然語言處理),用於理解指令的語義,以便採取相應的動作,包括對話功能
MQTT模塊,用於實現智能家居聯網控制功能
智能音箱正常工作要解決的第一個問題就是如何接收指令,這裡主要涉及兩個問題:
1. 被動喚醒(Passive Listening),即「什麼時候開始聽」。這個階段只監聽喚醒詞,當聽到喚醒詞時,進入主動聆聽。
2. 主動聆聽(Active Listening),即「什麼時候結束聽」。這個階段主動聆聽用戶的任何語音指令,然後對聽到的內容進行分析處理。
被動喚醒階段的基本策略是:以1s的時間窗口通過麥克風進行滑窗採集語音,計算每一幀的波形強度,超過設定的閾值的話就把語音送到ASR模型中判斷是否是喚醒詞(「你好Pico」),判斷為真的話,進入下一個階段進行主動聆聽。
主動聆聽的策略與被動喚醒基本相似,以1s的時間窗口通過麥克風進行滑窗採集語音,計算每一幀的波形強度,超過設定的閾值的話,就認為用戶已說完了指令。
喚醒關鍵詞的識別使用的是一個開源引擎叫snowboy(另外還有一個庫叫PocketSphinx也很好用), 這兩個引擎都是離線工作的,不需要連接雲端,識別率經測試還是比較高的,當然實際效果跟關鍵詞的選取有關。
snowboy個人使用是免費的
前端的喚醒和指令獲取工作完成之後,剩下的功能都由訊飛SDK實現,具體的API介紹和使用說明可以參考官方的Reference文檔:(在線語音合成Linux SDK 文檔www.xfyun.cn)
當然訊飛作為中文語音技術的扛把子,SDK開放的功能是非常豐富的,只要不是商業使用,很多功能基本也是免費的:
對於智能家居的控制功能,這個就很有意思了,因為我之前用Android平臺做過一個機器人項目,也實現了幾乎一樣的需求,所以智能家居控制的大部分的功能可以直接移植過來使用,包括自製的物聯網網關硬體。但是跟上面那個娛樂向的手機器人不一樣的是,這次要做的是一個正兒八經的語音助手設備,如果最後只能控制幾個LED的話顯然無法滿足我的無理要求。
所以我做出了一個大膽的決定,讓Pico向【小愛同學】伸出魔爪。
家裡正好安裝了米家全家桶,相比於自己把所有電器改造一遍,顯然這樣的騷操作更有助於增進家裡兩個語音助手直接的感情。
所以便有了視頻裡面開電視那一段的名場景。
Pico是我去年畢業之前的幾個月做的一個小玩意,算是我的個人畢業作品吧,雖然跟我的畢業論文研究方向(一點都)不相關😂。我的畢業論文是研究通信算法的。
不過俗話說得好,買賣不成仁義在 ,科研歸科研,畢業不瞎搞快樂哪裡找?
當時學生生涯迎來尾聲,我feel like急需一個炫酷的作品來安置我積壓許久無處安放的創造力😂所以這個作品,就是我品察生活、大開腦洞、傾力實踐之後,耗時5個月時間完成的一個解決個人使用智能音箱痛點的語音助手小機器人。可能還不算完美,但是有什麼關係呢,這不就又為我下次製造更成熟的項目提供了完美的藉口嗎?
整篇介紹文章從去年七月開始就拖更至今將近一年,這次終於一鼓作氣把材料都整理好了,但願大家從我的項目經歷中總結出了自己學習的方向。
達爾聞入駐分享者 稚暉系列——我是稚暉,常駐「達爾聞說」,不定期為大家分享人工智慧前沿知識。
我就關注「達爾聞說」
稚暉的往期回顧: