此次實作主要是建構【聲音偵測 + 電子音樂盒】的 Arduino 綜合應用案例,只要直接下載安裝相關軟體及簡單組裝硬體,就能運用麥克風模組偵測我們的拍手聲音,Arduino內部程式再根據聲音大小進而播放預先錄製的音效,也就是名副其實的【拍手音樂盒】,而且只要更動下載程式的重點註解,不用額外多寫一行程式碼,就完成建構【按鈕開關 + 電子音樂盒】的 Arduino 綜合應用案例,例如後面還會提到的【鬧鐘變音樂鐘】。當然還會介紹如何製作自己的音效,只要按部就班跟著步驟做,這一點都不難,有了自己設計的個性音效,這樣就更能適應各種應用場合和環境。此外,由於坊間書籍或網頁博文,對Arduino程式介紹幾乎千篇一律用傳統觀念設計的,這對入門者甚有幫助,然而水能載舟也能覆舟,恰恰就是這傳統程式設計觀念,像緊箍咒般牢牢困住著入門者,無法展翅、談何高飛,創新開發之路總是仰之彌高望而生嘆,沒門。因而,唯有軟硬體兩手都要夠厚,才得以涅磐重生,當然也就必須學著運用物件導向設計觀念,為此,本次所附Arduino程式完全是筆者用物件導向觀念設計的,從實作入手,相信對學習物件導向程式設計會更加有效。以下所附照片,正是本次實作的【拍手音樂盒】,雖然沒有美麗盒子當外裝,但其功能基本是足夠的。不是為物件設計而物件設計,也不為第三方程式庫而程式庫,
更不是為,
而是在解決關鍵問題的實戰中,一步一腳印淬鍊物件導向設計技術,進而水到渠成的完成了第三方程式庫。
此次實作案例將教我們怎麼運用 Arduino資源與輔助工具,做一個自己定制的音效(聲音長度小於4秒鐘)。
此實作案例運用的軟體資源均是免費的,首要感謝這些公司團體或小組無私奉獻,讓我們擁有很好的學習環境與資源,
進而激發我們更多的教學靈感與開發更多的教學案例,在這種良性循環之下,讓世界變得更加美好。
來源於麻省理工“high-low tech”小組,所有軟體均是免費。
當決定用什麼聲音的時候,我們一定要考慮 Aduino UNO 的小容量-32kb。
必要軟體在MacOS, Linux, 和Windows不同作業環境下都能適用。需要預裝的軟體有Arduino IDE以及Audacity。
PCM與8K8-bit單音效應用 This tutorial explains how to do simple playback of short (~4 second), low-bitrate (8 KHz) audio samples from Arduino using only a speaker. 國外已經有這樣做PCM手法的Arduino應用( PCMAudio),這要感謝 Michael Smith 無私的奉獻, 器材準備與組裝:拍手音樂盒主要用到下列器材:拍手音樂盒工作原理介紹:【拍手音樂盒】的運作方式,是由一個拍手有效輸入信號,來激發輸出聲音。這裡會分別談到此實作的輸出入運作情形。首先在輸入方面,我們運用Arduino具有的類比輸入功能,也就是在其pin (A0)腳位連接上麥克風模組的類比訊號輸出腳,並設定一個啟動門檻,當麥克風模組偵測我們的拍手聲音超過此門檻時,就會啟動播放預先錄製的音效。至於是如何輸出音效的呢?為了播放取樣率為 8KHz 的聲音,同時用了 Timer1 和 Timer2,Timer1 負責每秒產生 8000 次中斷(即 8KHz 的義思),也就是每隔 125μs (>即 8KHz 換算成週期的義思)輸出 PCM 採樣值,而 Timer2 則負責將音效採樣數值資料以 PWM 方式送出信號到pin 3 埠,再傳給喇叭發聲。 物件導向設計拍手音樂盒底層硬體運作概要:本次演示的 PCM 應用場景是為了播放 8KHz 的單聲道音效,音效發聲程式同時用了 Timer1 和 Timer2 兩個計時器協同運作,其中 Timer1 負責每秒產生 8000 次中斷,並於每次中斷服務裡逐次切換下一個要交給 Timer2 播放的 PCM 八位元採樣值,而 Timer2 則專門負責將Timer1 定時中斷服務遞交的 PCM 八位元取樣資料以 PWM 方式送出給喇叭發聲。這裡面的硬體運作核心之一會用到硬體 Timer1 計時器CTC模式下的定時中斷服務,有關Timer1 計時器CTC模式的運作方式有兩種做法,一種是以 ICR1 暫存器儲存TOP,當Timer1 計數器 TCNT1 數到這個 TOP 最高值時,本身會歸零,同時引發硬體中斷並將執行權交給引發ISR(TIMER1_OVF_vect),有名的 TimerOne 程式庫就是採此模式;一種是以 ORC1A 暫存器儲存 TOP 值,當Timer1 計數器 TCNT1 數到預定最高值 TOP(也就是剛剛在 OCR1A 的設定值),本身會歸零,同時引發硬體中斷並將執行權交給ISR(TIMER1_COMPA_vect)中斷服務,本人開發的CltTimer1CTC程式庫是屬於此模式,可以補充 TimerOne 程式庫的不足。至於另一個硬體運作核心,就是將Timer2設為八位元快速PWM輸出,並得以從Timer1定時呼叫中斷服務裡設定Timer2其PWM輸出的佔空比(也就是 PCM 八位元取樣資料),這樣硬體就能順利執行音效輸出。 物件導向設計總體概要:這裡暫且不談高階物件導向技術的物件塑模(Object Modeling)或設計模式(Design Pattern),先回歸基礎,談談當程式(非關系統)開發常常會重複面臨一些繁瑣指令或複雜演算, 這時傳統編程作法就是把這些重複程式用函式方式囊括在一起,等需要用時,再行呼叫就成了。例如本次實作要用的PCM技術,當Michael Smith首次將此技術應用到Arduino並發表於Arduino玩家園地裡的一篇PCMAudio文章時,原作者僅僅把 Timer1 與 Timer2 兩種繁瑣且多樣兼複雜的暫存器設定指令,緊密打包成 startPlayback() 與 stopPlayback() 兩個函式,方便供主程式叫用。由於這項技術那樣棒的好東西,真的值得推廣,很快就吸住大衛·梅利斯(David Mellis)(註:他是Arduino的核心開發團隊成員)的眼球,這位大咖看見不同,於是,捲起袖子自己幹,並重新組編程式碼還發布於GitHub的PCM專案,方便有志 Arduino 音效開發者直接下載拿來就用。然而,這位大咖並沒有運用物件導向設計概念重寫程式,原程式碼幾乎沒有更動,只是重新布置程式檔案,改以第三方程式庫面貌,方便人們下載安裝至開發環境中直接使用,高度發揮拿來主義。以這種行之數十載的傳統技術,確實提高了程式碼的重用性,也帶給程式設計師許多便利,但畢竟這是老技術,其重用性十分受限,例如那兩個函式只能用到PCM音效應用場合,其內部有關Timer1與Timer2的設立功能,其實值得獨立出來自成一格供其他地方應用,這樣就能大大提高了重用性;另外,當面臨一些特殊應用場合,這裡也現擺著一個實際應用需求,怎樣讓Timer1的中斷服務(也就是ISR)設計成讓開發者更有彈性(也就是降低偶合性)的設計成自己所要的執行內容,並且於執行階段能在中斷發生時,能回過頭來叫用(也就是Call Back)自己早先定義好的中斷服務,對於這種預埋伏筆給Timer1中斷時叫用的低耦合通用做法,傳統技術就無能為力。 Arduino應用無疆與物件技術的加持:有機會,看一下Arduino原創於TED的演講,您會驚訝於Arduino的應用已經包山包海。為何Arduino會那麼海水正藍?!一部分原因是初學者容易上手,而且有很多火紅開放資源,最重要的是許多廠商或個人為了解決問題提供了大量的第三方程式庫,開發人員只要知道哪裡下載怎麼安裝,很多細節不用開發者煩惱就搞定了。第三方程式庫為何如此強大?那是因為它們大部分是運用了物件導向設計技術,把許多執行細節都封裝在類別裡,只要開發人員懂得運用物件的點指令,就能叫用這些物件所提供的方法或屬性。由此可見,用物件導向設計所撰寫的程式,對於加速程式發展的時程有很深遠的影響。簡音單樂聽見不同、心思所書筆觸不同、沉魚落雁可以不同、科技進步跟上不同,是時候跟上時代,該學物件導向設計技術了。 化蛹為蝶變身手法的自學之道:如何才能學好物件導向設計技術呢?這方面設計理論有許多教課書在講,這裡就不多加介紹。學物件導向設計技術的門道也很多,雖條條大路通羅馬,但要尋得合適之路,著實不易呀!由於筆者是自學而成的,自創的學習法或許可供需要的人做為參考,本人稱之為化蛹為蝶的變身手法(transfigured approach),意思是如何從被傳統設計困住的蛹,怎麼一步步變身,同時把每一步變身當作切片,每個變身切片公開透明,易於檢視及模仿,同時也容易感受觀念要如何轉變,最終就成功轉化成物件導向的彩蝶,也就是形成一套高度重用的第三方程式庫。 PCM技術實戰關鍵細節介紹:就以本次開發PCM技術於Arduino的應用為例,這是個運用極少資源做到極致的點子,是個將軟體充分發揮硬體的經典之作,但是大咖們似乎忘了注入物件導向觀念(這在本章節頭一段已經介紹過),這給了筆者一個難得機會來彌補這一缺失,並運用物件觀念逐步完善其設計,最終形成了兩個有關Timer1與Timer2的第三方程式庫,並提供使用這些程式庫的範例。當我們細細品味這些變身細節,從而領略並觸動到物件設計的靈魂(郭台銘說魔鬼藏在細節裡,我倒覺得是靈魂藏在細節裡),而這些程式庫是筆者基於簡便原則(KISS)自訂的,其程式碼都很短,容易閱讀便於學習,如拿來開發一些應用,例如後續會再提到的正弦波產生器的開發,會覺得這些程式庫小巧玲瓏,用起來其樂無窮,從而發現物件設計是何等神奇與強大。 運用變身手法逐步開發出自訂 Timer1 程式庫:對於Arduino來說,PCM是個說大不大、說小不小的應用,它可以有很多種設計法,可以是軟體控制細膩活,或是大量暫存器設定的硬體活,本次演示屬於後者。本次演示的音效發聲程式同時用了 Timer1 和 Timer2 兩個計時器協同運作。發揮硬體效能雖然是件好事,但這將會有許多相關暫存器需要進行設定,這可是個繁瑣複雜且容易犯錯的苦差事,一般程式人員都怕碰這麻煩事。如果能把這些煩人事打包封裝起來,達到又要碼兒好(用),又要碼兒不苦惱,那麼程式人生從此不就幸福快樂了嗎,本範例就是朝著這個夢想邁進,開發當中活用了物件設計技術,從而開發出兩個筆者自訂的程式庫,並把程式物件技術換的變身過程逐步記錄下來,供需要者參考。首先要下載本範例所有相關壓縮檔(後續會介紹),在下載 zip 檔中所屬 CltTimer1CTC 程式庫所附範例資料夾 “examples” 資料夾內有五個演變範例程式(或點擊GitHub的五個演變範例),其中編號前四個範例是用Timer1閃耀LED燈這一主題下逐步演變的,每一步都用了物件技術變身手法,初學物件導向技術者請耐住性子慢慢來,不求快,一步一腳印,把每個變身前與變身後的來龍去脈都搞清楚,最終運用物件技術能從傳統設計轉化形成 CltTimer1CTC 程式庫,這是為了實作PCM應用設計前的熱身賽,目的就是打造屬於自己的Timer1的物件,以便後續就不用管那惱人的暫存器設定。 活用自訂 Timer1 程式庫支持 PCM 技術開發同時再用變身手法開發出自訂 Timer2 程式庫:有了前項重要法寶之後,就大膽地進入PCM應用設計主題,當然是從最開頭的傳統程式設計談起,經筆者整理網上現有相關程式與自己的補充程式,,,以下又是不錯的>四個範例,串聯起來就是物件技術轉換的變身過程,值得細細推敲,以下就是這四個範例:,,,,,,,,,,
[[軟體框架(Software framework)]]https://zh.wikipedia.org/wiki/軟體框架
模型- 視圖- 控制器
MVC 框架再優雅,底層還是運用JSP/Servlet 等這些Java EE 標準的機制。
[[波形數據陣列 -PWM輸出時序圖-時序控制器]]
Table-driven approach
然而
這裡也留下些許習作,就是
把Advanced Arduino Sound Synthesis
(中文翻譯)
裡面介紹的方波、三角波、隨機波、疊加式合成聲波,通通都轉成使用筆者自訂的這兩個程式庫,這是一種低耦合性回呼(Call Back)的物件開發技巧,如要修改中斷服務常規的話,只要在主程式裡進行即可,勿須更動所用程式庫內的源碼,因此,只要置換波形陣列表(或用程式產生它)與少許程式碼,這些都能輕鬆解決,您說,是不是用起來其樂無窮。
下載拍手音樂盒物件導向設計範例程式模組與安裝:要手動安裝拍手音樂盒程式與程式庫,首先關閉 Arduino 開發環境。然後點擊這裡提供的GitHub下載連結處:arduino-KISS-drivers-libraries-master.zip,下載成功後,接著對剛剛所下載包含相關應用程式與程式庫的 zip 檔案進行解壓縮,待解壓縮完成後,其中有兩個相關資料夾至關重要,再來就是針對這兩個資料夾進行下列安裝步驟:
主程式重要功能說明:The library only has two functions: startPlayback() and stopPlayback(). The first takes two arguments: the array of audio samples and its length. For example: startPlayback(sample, sizeof(sample)); The stopPlayback() function doesn’t take any arguments and will stop playback of the current sample. Note that the example also uses a couple of unusual Arduino constructions. First, the sample[]array is declared using the keyword PROGMEM, which causes the data to be stored in the Arduino’s program memory (Flash) instead of its RAM (which is much smaller). It also uses the sizeof() function, which returns the number of bytes used by an array.函式庫是以 zip 檔或資料夾型式來發佈的。資料夾名稱即為程式庫名稱。資料夾內通常包含 .cpp檔、.h 檔、keywords.txt 檔、範例資料夾以及其他函式庫需要的檔案。有兩個相關資料夾 Now quit the Arduino IDE and reopen it. ,需要將 DuinoParty 資料夾放入特定資料夾內。在 Windows 系統,須放入 ”My Documents\86Duino\libraries” 資料夾內。在 Mac 系統,須放入 ”Documents/86Duino/libraries” 資料夾內。在 Linux 系統,須Now you should be able to go open all the examples codes by navigating to "File>Examples>USB_Host_Shield_20" and then select the example you will like to open. 再來解壓縮包含函式庫的 zip 檔案。例如:若要安裝的程式庫稱為 “DuinoParty”,解壓縮後資料夾應該是DuinoParty,內部應包含DuinoParty.cpp以及DuinoParty.h檔。(若.cpp與 .h 檔不在資料夾內,則必須自行建立。以上面為例,此時使用者必須建立DuinoParty.cpp與DuinoParty.h。) 上傳範例並加以執行:在先前已成功安裝了下載範例情況下,首先開啟 Arduino 開發環境,然後在其主功能表上點擊【檔案】→【草稿碼簿】→【CltTimer1CTC-06PCMTinkler】,接著執行上傳動作,這要給 Arduino 一些時間,因為音效資料較大。當 Arduino 接收完畢重新啟動後,並不會發出任何聲音,當我們靠近麥克風模組拍手時,Arduino偵測到足夠大聲響後會自動播放預先錄製的音效,【拍手音樂盒】會發出很小聲的“這是鄧崇林的測試音效"。當Arduino直接推送喇叭播放聲音,第一個會遇到的問題就是 “聲音太小”。這時可使用簡單的NPN電晶體(例如BC546/BC548B)來放大電流達到加大音量的效果。從本次實作經驗來看,由於Arduino Uno其Flash Memory受到 32 KB大小的限制,當存放約三秒左右的音訊時,程式編譯之後用了25KB(77%),至於存放大約四秒左右的音訊,編譯之後用了31KB左右,這四秒音訊大概就是上限了。 遙想Arduino創立之初(摘自維基百科):Arduino創立之初其核心成員Massimo是一所義大利設計學校的老師,因學生常抱怨沒有便宜又好用的微控制器,在2005年,他跟一位西班牙的晶片工程師David Cuartielles針對這問題討論後決定自己來做這樣的板子,由Massimo的學生David Mellis設計其專用語言與軟體開發環境(還記不記得,就是先前提到那位重寫PCM技術應用的大衛·梅利斯)。這位大咖(當時是學生)只花了兩天就完成了所需程式語言與軟體開發環境(當然不是從零開始,而是借用了另一從 MIT 釋出的Processing 開放軟體開發環境),再花三天又完成了名為Arduino的電路板,其目標就是提拱給創客們的創新應用,即使開發者不懂電腦編程,也能用Arduino創造出很酷的玩意兒,比如對感測器作出閃亮回應,用LED燈秀出光的饗宴,還能控制自走車等等,這就看想像力有多大了。 用Audacity來轉換成這樣的格式,只是在這裡有兩個重要技巧:一是更改歌曲取樣頻率時(比如說從44.1kHz -> 8KHz),要改的是專案的取樣頻率而非音軌的取樣頻率,如果改了音軌的取樣頻率,音樂速度會變得更快。第二是Stereo改Mono時,功能在音軌最左方的下拉選單裡。One easy way to down-sample the audio is with iTunes. First, Import your original sample into iTunes. Then open the preferences dialog and, on the general tab, click “Import Settings…”. From there, select “Custom” from the “Setting” drop-down. Inside the custom settings, select “Stereo Bit Rate” of 16 KHz, a “Sample Rate” of 8 KHz, and Mono “Channels”. To convert the down-sampled audio file to numeric values you can paste into your Arduino program, you can use the EncodeAudio application. This is a simple Processing program (source code on GitHub) that reads an audio file and copies its audio data to the clipboard in numeric form.
遙想Arduino創立之初:在先前已成功安裝了下載範例情況下,首先開啟 Arduino 開發環境,
[19-解除註解的封印.JPG] |
Python+Arduino+硬體筆記 >