EV3 Tutorial(8)超音波感應電子琴


EV3 主機可以發出不同頻率的聲音,可以拿來製作個電子樂器,最簡單的作法就是使用顏色感應器,偵測不同顏色來發出不同音階,或者是使用觸碰感應器搭配 EV3 主機上的按鈕來當成鍵盤輸入,這次我則是嘗試使用超音波感應器來作個電子琴外觀的樂器。

積木組裝

這次超音波感應電子琴的積木組裝,可以下載 Piano.lxf,或者是 線上觀看組裝過程,組裝完成的成品如下:

超音波感應電子琴

乍看組裝用了 182 個零件蠻嚇人的,其實按鍵的組裝方式都一樣是這個:

超音波感應電子琴

因此就看你要組幾個按鍵罷了,我這邊組的是五個按鍵,可以彈個 Do、Re、Mi、Fa、Sol 的曲子,像是瑪莉小羊之類的 … XD

判斷按下哪個鍵,就是在按鍵按下後,白色擋板會昇起反彈超音波,感應器藉此量測距離並轉換為 EV3 主要應該發出的頻率。

避免巢狀結構

感應器相關的程式,基本都是在迴圈中不斷偵測訊號,在這邊為了讓擋板昇起時發音,落下時停止,因此在每次迴圈都偵測距離變化,這還有個目的,就是讓意外反彈的音波不致於發生太多干擾,可以實際測試設個剛好的值,聲音會比較乾淨一些:

超音波感應電子琴

PlayTone 自訂 Block 的設計是這次的重點,超音波感應器不是個很精確的東西,只能量測大致的距離,因此,你每次量測到的距離可能是不一樣的,只能大致在某個範圍中,例如,這次五個鍵昇起,可能分別量到 346.79.312.1,下次可能量到 3.24.46.59.111.4 之類的,因此,你不能直接拿來當 Switch 流程積木的比對值。

當然,EV3 本身有 Range 方塊可以使用,是可以多測量幾次,記錄下每個鍵昇起後量測到的範圍,然後使用 Range 搭配 Switch 方塊,不過,嗯!程式畫面會變成可怕的巢狀結構,而且,Swtich 方塊還有個限制,不能直接將資料線從外部拉到 Switch 方塊中,因此你得使用變數方塊,簡單來說,你的程式畫面會整個亂到不行。

這時可以換個方式來設計,例如方法之一,是為每個音階定義一個自訂 Block,每個自訂 Block 中只有一個 Switch 方塊,當距離在 Range 設定的範圍中時,發出該音階的頻率,然後,每次迴圈量得距離後,分出多個流程至各個自訂 Block,只不過這個方法,音階越多流程就分出越多,整體畫面上還是不小,而且為每個音階定義一個自訂 Block 也是蠻麻煩的。

我想到的方法是,不使用 Range,只用一個 Array 方塊,Array 方塊裏的值可能像是:

3.391995
4.349228
5.349228
6.329628
7.329628
9.293666
10.29366
11.26163

嗯?這些值代表什麼意義?很簡單,3.391995 表示當偵測到距離為 3 時,要發出 391.995 Hz 的聲音(也就是 Sol),4.3492285.349228,表示偵測到距離為 45 時,都要發出 349.228 Hz 的聲音(也就是 Fa),這表示我的感應器第二個靠近它的擋板昇起時,量到的距離可能是 4.x 也可能是 5.x,類似地,6.3296287.329628,表示偵測到距離為 67 時,都要發出 329.628 Hz 的聲音(也就是 Mi),依此類推 … 實際的陣列值要以量測為主。

我會用 Round 方塊對感應器量到的距離做四捨五入,這也就是為什麼陣列元素值的整數部份代表偵測到的距離,至於小數點後只要乘上 1000 就是頻率了。

超音波感應電子琴

自訂 Block 來處理算式

當然,感應器量到的距離與陣列值得跑迴圈進行比對,比對中了就離開發出聲音並離開迴圈,比對的部份要用到算式,凡是用到算式的部份,都建議自訂 Block 處理,因為使用 Math 方塊來做簡單的運算,都可以佔據很大的畫面。

IsMatched 自訂方塊對於陣列元素值直接裁掉小數部份,對於感測到的距離進行四捨五入,然後看看結果整數是否符合:

超音波感應電子琴

FindHz 自訂方塊則計算出頻率,也就是取得陣列元素值中小數部份,然後乘上 1000

超音波感應電子琴

這麼一來,如果你要擴充按鍵,也只要增加 Array 的元素值就可以了,不用繼續建立更深的巢狀,也不用自訂更多的 Block 了 …

幹嘛這麼認真地使用圖型化語言呢?這種語言是有很多限制沒錯,我是可以不用太認真面對它,拖拖拉拉反正程式能動就好,不用考慮可讀性,也不用考慮彈性,好玩就好,不過,真的要認真面對這些限制時,倒是可以激發一些改變設計的可能性,從另一個角度來設計程式,對我來說,這也是蠻有趣的呢!