CH2 開發環境介紹 最簡單的互動設計 – Arduino一試就上手 孫駿榮、吳明展、盧聰勇
程式開發流程 在做微處理器的程式開發時,最關鍵的一步就是將程式編譯成單晶片看得懂的機械語言,而這部份的工作多半是交由電腦上的相關程式來執行。 目前常用於單晶片系統的程式碼為組合語言(Assembly)、C/C++等種類,設計完系統所要的執行流程,最後再編譯成特殊格式的檔案,也就是能讓微處理器看的懂的語言,常見的檔案是副檔名為.hex。
程式開發 - 編輯 這是開發的第1個步驟:產生程式碼。 一個專屬的程式開發環境,還可以幫你管理專案內的多個程式,也可以利用顏色來區分程式碼類的內容。
程式開發 - 編譯 這個階段的工作就是將我們編輯完的文字檔轉換成為機器碼,這個步驟會幫你檢查程式上的錯誤,並提出警告。因此這個步驟完後通常會回到前一步驟將語法錯誤、邏輯錯誤的地方進行修正,直到編譯器沒有產生錯誤為止。
程式開發 - 鍊結 當我們的專案程式越來越大時,為了方便管理,通常會分功能的儲存成不同的檔案,鍊結的功能就是將程式當中所有用到的功能模組、內建函式庫找尋原始程式的位置,再與主程式結合成為一個可以執行的檔案。
程式開發 - 執行 能夠執行程式的話,恭喜你已經成功的完成前面的步驟,終於可以看到程式所跑出來的結果了,不過能執行不一定表示結果是符合預期的,還是有可能有各種不同的錯誤情形會發生。
下載開發好的程式 針對單晶片這種硬體程式開發,執行測試程式時通常會先進行燒綠的動作,也就是將程式下載到晶片中,這個動作在大部分的單晶片需要特殊的線路。 燒綠介面還有功能性的差異,最基本的就只是將編譯完的程式直接燒綠,進階版的則可以支援單步執行,這個功能可以讓開發者逐行執行程式,更容易發現問題所在,這類高階的燒綠器通常稱為JTAG(Joint Test Action Group)。
Arduino 下載程式 Arduino的核心晶片也有支援ISP(In-System Programming)的功能,所謂的ISP就是在無須改變硬體連結及硬體仍處於執行階段時,可以隨時下載新的程式碼進入晶片記憶體中,這樣的好處是在於在燒綠程式時,單晶片不需要額外拔離系統電路,節省時間與額外成本。 圖片來源:www.atmel.com
Arduino 下載程式 Arduino非常人性化的簡化的燒綠程式的流程,只要使用與電腦連結的USB線即可進行燒綠的動作,而這麼方便的優點都必須歸功於Arduino的Bootloader。
Bootloader Bootloader顧名思義就是開機後會載入的一個程式,,當單晶片重置時,第一個步驟會先跳到Bootloader來判斷接下來進入的資料是屬於程式碼還是一般資料。 Bootloader的存在,造成系統開啟時,需要等待約幾秒的時間,才會開始執行。
Bootloader 由於Bootloader的使用,讓使用者在開發Arduino的程式時,不需要擔心怎麼下載、燒綠程式,可以大大提高想要玩玩看單晶片系統的初學者的意願。 新的Arduino系列單晶片並沒有內建好Bootloader,都是需要在購買後額外燒綠,這時就必須使用額外的燒綠軟體。
Bootloader Arduino的開發環境就有燒綠Bootloader的能力,只是需要額外的燒綠器,在選單上可以看到有四種:AVR ISP、USBtinyISP等。
IDE 編輯、編譯、鍊結和執行等過程在某些單晶片系統上是需要分作不同的應用程式來完成不同的步驟,可能先經由A程式產生出燒綠檔,再透過B程式將檔案燒錄到單晶片中,這樣分段式的開發流程不甚方便,故系統商或是第三方(the third party)的軟體商會整合所有的過程,統整為單一的環境,稱為IDE(Integrated Development Environment),整合式開發環境。
Download Arduino IDE 在download的頁面中,即可找到最新版的Arduino開發環境,為了讓大家隨時能試試最新版的硬體版本,網站上會隨時更新,也為了不同作業系統的使用者,提供了Windows、MAC和Linux的跨平台版本。
Download Arduino IDE
Download Arduino IDE 下載完成後,將壓縮檔解開,可以找到一個名為Arduino的執行檔,點擊兩下後即可開啟開發環境,完全不用安裝,真是方便到家。
Arduino IDE 在Arduino的資料夾裡,除了執行檔以外還有許多資料夾,其中drivers是在第一次將Arduino插上電腦後,會需要的驅動程式都在裡面。而hardware的下一層目錄裡,可以看到前面所介紹的Bootloader的原始檔,lib的資料夾則包含了基本的函式庫,若是在網路上找到其他玩家所寫好的函式庫也可以丟進lib這個資料夾內,便可以使用相關函式功能。
Arduino IDE
Arduino IDE 注意觀察一下,會發現他預設的檔名會使用今日的日期做為預設檔名結尾,不怕忘記每個程式版本的開發日期,而預設專案的儲存位置在我的文件(以Windows為例),而專案的副檔名.pde只有這個開發程式可以開啟,等等!! 之前說的C/C++檔案呢?別擔心,在往下一層的檔案夾中,就可以看到我們辛辛苦苦寫的程式碼。
Arduino IDE Verify/Compile(編譯目前專案) New (新增檔案) 驗證程式是否撰寫無誤,之後將以寫好的程式編譯。 開啟一個空白的頁面撰寫程式碼 Open (開啟舊專案) 開啟副檔名為pde的專案檔。 Upload to I/O Board(下載程式到硬體開發板上的單晶片) 針對已經編譯過的程式下載到已連接的硬體上。 Save(儲存專案) 儲存目前的專案。
Serial Monitor 它可以觀察目前儀器模組中,蠻常見的RS232協定的輸出資料,也可藉由它輸出命令給另一端的設備。 目前只有Windows XP中有類似的軟體,叫做超級終端機。
Library Inside Arduino的程式語言式類似C/C++的語法(C/C++ like language),隨著IDE的更新,包含了許多基本常用的函式庫。
Example Inside 再也不用擔心該如何上手。 基本功能使用語介紹皆包含與此。 唯一的美中不足為註解皆為英文。
程式架構 引用函式庫 參數定義 Setup Loop
Setup setup在程式流程中只會執行一次,所以用於定義所有需要設定、初始化的參數和函式,或是腳位功能的指定,都會在這部分先定義完成。
Loop 是主要程式的執行內容,只要電源不中斷的情況下,會一直執行這函式內的程式。
新增頁面 當專案開發程式越來越長、功能越來越複雜時,我們會以函式和將專案分成數個較小的檔案方便管裡。 不同的頁面存成不同的檔案。
資料型態 float 10^-38~10^38 int -32768~32767 unsigned int 0~65535 Double 資料型別 數值範圍 float 10^-38~10^38 int -32768~32767 unsigned int 0~65535 Double 10^-308~10^308 Long -2147483648~2147483647 unsigned long 0~4294967295 char 0~255 word
選擇性敘述 - if Void loop() { if (判斷條件) if(判斷條件) //多個if判斷式 //符合多個條件後要執行之程式 }
選擇性敘述 – if else Void loop() { if (判斷條件) //符合if條件後要執行之程式 } else //不符合if條件後要執行之程式
程式撰寫小觀念 在程式趨於複雜的情況下,可能有數個以上的條件判斷式,此時最好養成良好的程式編排習慣,例如縮排等,這樣不僅方便日後維護,也可避免搞混,可以有較高的程式撰寫效率。
選擇性敘述 - switch Void loop() { Switch(判斷運算式) case 條件1: //執行的程式 Break; Default: } switch的敘述方式,會根據判斷運算的結果,在下列的case中選擇符合的並執行當中的程式碼,若都沒有符合的則執行Default中的程式。
迴圈 – while and DoWhile Void loop() { while(判斷運算式) //執行的程式 } Do }while(判斷運算式) while在第1次是先判斷再確認是否要進入迴圈執行;而do-while則是先執行一次迴圈內的程式內容再做判斷。
迴圈 – for Void loop() { for(初始數值;迴圈終止條件;每次迴圈結束時的動作) //執行的程式 } for(i=1;i>100;i++) //範例
迴圈 – for 在許多輸出或是數學運算常會用到for迴圈,它可以固定執行的次數或是針對變數做固定的變化。在迴圈括號內分成3個段落,分別表示:初始迴圈的特定數值、迴圈終止條件、每次迴圈結束執行的動作。例如範例,表示的是當迴圈執行時,先將變數i設定為1,每次執行迴圈內的任務後,變數i加1,重複動作直到變數i大於100為止。就這個例子來看,我們可以確定兩件事情:第1,程式會執行100次;第2,每次變數i都會比之前大1。
迴圈 – for for迴圈也可以當作無窮迴圈使用,像是上面的例子。 for(i=1;;i++) //沒有設定終止條件,變為無窮迴圈 { //執行的程式 } for迴圈也可以當作無窮迴圈使用,像是上面的例子。
特殊函式 除了以上的判斷、迴圈外,還是有一些特殊的語法需要詳加介紹,因為這通常是用於單晶片系統開發才會使用到的硬體設定,在使用時也需要仔細確認,避免錯誤的結果或是硬體的損毀。而在Arduino中,又提供了一些簡易的設定方式,讓使用者可以很輕易的針對硬體的功能需要來做不同的設定。
Pinmode ( pin, mode ) 用於數位腳位(Digital pin)在輸出入的時候,決定要採用哪種功能,第一個參數表示要選擇的腳位,有0至13可以選擇,而第二個參數可以選擇INPUT或是OUTPUT表示不同模式。
Input for Pinmode 當PIN腳使用為輸入的時候,它的值為0或1(True or False)完全是依靠外在的電路或是感測器所提供的電壓來決定。 若使用Arduino Digital I/O腳位做為輸入端的使用時,最重要的就是要小心電壓及電流的極限值,過大的電壓、電流都會造成微處理器的損毀,所以一定要小心處理。
Output for Pinmode 當PIN腳設定為輸出時,它的狀態完全取決於程式當中的設定,不過它能提供的電流相當的小,亮個一顆LED小燈OK,不過其他負載較大的電路就需要使用其他的方式,以免單晶片過載燒毀囉。
時間函數 在單晶片的系統中,與其他感測器之間溝通的最重要關鍵,非屬時序不可了,如果只是讀到錯誤的數值也許只是小事,令人害怕的是做出了無法挽救的控制行為,導致系統或其他設備的損害,那就太得不償失了。
millis() 回傳一個時間常數,此常數的開始時間為單晶片系統開始執行程式時,而這個數值的資料型態是unsigned long,單位為毫秒(milliseconds)。 void loop() { //取得目前系統時間 Time = millis(); //輸出取得的時間 Serial.println(time); }
micros() 回傳的時間常數單位是百萬分之一秒(microseconds),資料型態一樣是unsigned long,極限值約在70分鐘左右。 1,000 (microseconds) = 1 (millisecond) 1,000,000 (microseconds) = 1 (second) 1,000 (milliseconds) = 1 (second)
delay() 假如有需求想讓程式停留在某一個狀態一陣子後再繼續執行,則必須使用delay()這個函式,函式內填入想要停留的時間,單位是千分之一秒(milliseconds)。 digitalWrite(13, HIGH); delay(500); 括號內的參數型態為unsigned long,範例所顯示的代表程式將會在此行停留0.5秒,維持上一行程式所執行的狀態:第13隻數位腳位輸出為高電位。