Professional Documents
Culture Documents
Arduino 的使
用
目的
認識 Arduino 微處理器,並能藉由程式設計透過微處理器偵測按鈕狀態及控制 LED 及壓電揚聲
器。
原理
負端這一側是 平的
1
普物實驗講義
電阻是必須的。請記得使用限流電阻,
如果沒有它,會造成太多的電流流過線路。
將會造成許多零件的損壞,包括 UNO、電源 圖 5 UNO 控制 LED 線路
供應裝置甚至是 LED 等都可能會燒毀。
b. 鍵入 LedOnOff.ino 程式碼至 Arduino Editor。並設定好檔名另存新檔。
2
普物實驗講義
//LedOnOff.ino
// 開啟及關 LED 燈, 0.5s; 暗 0.5s 。
閉 亮
// 組別、組 員 姓名
// 雙斜線為 解指令,編譯程式會自
註 void setup(){ 動 忽略雙斜線之後的文字 , 主要目的是幫忙理解程式碼。
// 本函數只 行一次執
Serial.begin(9600);// 設定鮑率 9600
pinMode( 13,OUTPUT); // 設定接腳 1 3 為輸出模 式
}// 程式碼最好根據不同 的 程式區塊有不同的縮排 , 可以讓程式碼容易閱讀
void loop(){
k
Serial.println("The LED connected to Pin13 is blin ing!"); 窗
字
//Serial.println() 函數是把雙引號內的 串輸出到序列埠監控視
digitalWrite(13,HIGH);
//digitalWrite( 接腳名,輸出狀態 ) 指令是設定某輸 出 接腳的輸出狀態,其中 HIGH 為輸出高電壓 (5V) delay(500);//dela
delay(500); 間 秒
出
}//loop 函數執行結束會重新執
行
c. 重新連接你的 UNO 的電源、執行程式;點選工具列序列埠監控視窗,檢查是否出現設定
字串。
d. 執行特定次數的 for 迴圈_程式前面鍵入"int counter;"並把 void loop()函數內的程式改用下
列程式取代。 會
e. 檢查是否亮暗十次後停止?完成後請助教檢查。
Serial.println("The LED connected to Pin13 is blinking!");
二、按鈕測試電路 n
//程式由 counter=0 開始執行,每執行 一 次,counter 就+1,直到 counter=10 就 停 止 執 行 , 離 開 for 迴圈,共執行 10
次 1 5V
a. 拔出 USB 連接線(即切斷 P13
for(counter=0;counter<
W H0;counter=counter+1){ //可用 counter++取代 counter=counter+1
UNO 的電源)後接妥電路圖
digital rite(13,HIG );
6。
delay(500);
P11
b. 鍵入rite(13,LOW);
digital PushbuttonControlLed
delay(500); 圖 6
程式碼至 Arduino Editor。 路
Serial.println(counter,DEC) 按鈕迴路和 LED 電
; 並設定好檔名另存新檔。
} 執
// PushbuttonControlLed.ino
// Check pushbutton
h state 0 times per second and bli nk LED when pressed.
//組別、組員姓名 1
const byte SW = 11; //定義常數 SW 代表 11
const byte LED = 13; // 義接腳 13 為 led 控制端
void setup() {
Serial.begin(9600);//定義鮑率
pinMode(S W, INPUT);//設定接腳 1 1 為輸入模式
pinMode(LED,OUTPUT);//設定接腳 13 為輸出模式
3
普物實驗講義
}
void loop() {
boolean val = digitalRead(SW); //將
S W 接腳狀態讀入後存入
資 料型態為布林變數的
val if(val){ //val 是否為 HIGH
Serial.println("SW=1");//是若輸出"SW=1"字串,並閃爍 LED
digital
W rite(LED,HIGH);
delay(50);
digital rite(LED,LOW);
delay(50);}
else{//否W 輸出"SW=0"字
串
Serial.println("SW=0");
delay(100);
} 按 的
c. 重新連接你的 UNO 的電源、執行程式;點選工具列序列埠監控視窗,檢查是否出現設定字
串及測試結果是否符合預期?完成後請助教檢查。
三、揚聲器電路 P8
a. 拔出 USB 連接線(即切斷 UNO 的電
源) 後接妥電路圖 7。
b. 鍵入 ActionTones.ino 程式碼至
Arduino Editor。並設定好檔名另存新 圖 7
壓電揚聲器回 路的電路圖
檔。
//ActionTones.ino m
//Send a tone員to the piezo speaker using the tone() co mand.
//組別、組 P姓名
const byte S
_PIN=8; int
duration;
int frequency; 模
//設定函數 S
void setup() {//接腳輸出 式的設
定
pinMode( P_PIN,OUTPUT);
Serial.begin(9600);
}
//主程式 0 void loop() {
Serial.println("Alarm...");
delay(1000); 音 止
tone(SP_PIN, 1500); delay(500); noTone(SP_PIN); delay(500);//響 1.5kHz 聲 0.5 秒,停 0.5
秒 tone(SP_PIN, 1500); delay(500); noTone(SP_PIN); delay(500);
p
tone(SP_PIN, 1500); delay(500); noTone(SP_PIN); delay(500);
tone(SP_PIN, 1500); delay(500); noTone(SP_PIN); delay(500);
Serial.println("Robot
replay..."); delay(100);
tone(SP_PIN, 2800); delay(100); noTone(SP_PIN);
tone(SP_PIN, 2400); delay(200); noTone(SP_PIN);
tone(SP_PIN, 4200); delay(140); noTone(SP_PIN);
tone(SP_PIN, 2000); delay(30); noTone(SP_PIN);
delay(500);
Serial.println("Hyperspace...")
; delay(100);
for(duration=15;duration>=1;duration--){//duration--代表 duration=duration-1
4
普物實驗講義
tone(SP_PIN,frequency);
delay(duration);
noTone(SP_PIN);
}
}
Serial.println("Done");
for(;;);
}
c. 重新連接你的 UNO 的電源、執行程式;點選工具列序列埠監控視窗,檢查是否出現設定字
串及測試結果是否符合預期?完成後請助教檢查。
四、設計_反應計時電路
假如你已經是遊戲公司的嵌入系統工程師,市場部門要你藉由電路來測試玩家使用遊戲把手的反應
時間,你的下一個工作是開發一個反應計時電路。這個實驗程序中,你要建立並且測試你的解決
方法,是這一個設定程式並解決問題的例子。
a. 拔出 USB 連接線(即切斷 UNO 的電源)後接妥電路圖。
5V
P8
P11
圖 8
反 應計時電路
5
普物實驗講義
digitalWrite(LED,HIGH);//LED 亮,計時結
束 delay(1000); //Delay 1 second.
6
普物實驗講義
設定初始
值
不同的變數形態,可以儲存不同的數字
範圍。當然,儲存的數字範圍越大,所需要的儲存記憶體空間
boolean : true or fasle 布林變數
byte : 0~255 位元組
不符合 char : 'a', 'b', 'c' 字元 int : -32768 ~ 32767 整數
設定執
脫離迴圈 long : -2147483648 ~ 2147483647 長整數
行條件
符合條件
主要程式
設定變數
變化量 圖 9 for() 流程圖
7
普物實驗講義
for()函數內有三個參數(分別以;分號隔開),第一個參數為設定變數初始值,其中變數需事先宣
告,本例中變數名稱為 counter,設定為 0 即 counter=0。第二個參數為設定執行條件,其中只要符
合條件就繼續執行 for()函數,不符合就離開 for()函數。本例中為 counter<10,只要 counter 變數小
於 10 就執行大括弧內程式。第三個變數為設定變數變化量,只要 for()函數內的程式執行完後即重
新設定變數後再依據第二個參數作判斷是否離開迴圈。本例為 counter=counter+1 代表每次將
counter 變數內的數值取出加 1 後再儲存回 counter,即 counter 變數加 1 的意思(可簡化為 counter+
+)。因此執行 for(counter=0;counter<10;counter=counter+1)告訴 UNO 要先設定 counter 的值為 0 然後根據條
件判 斷是否要執行主要程式。若符合條件將執行程式後把 counter 的值加 1,接著再檢查 counter
的值有沒有小於 10。如果沒有,它會再重複程序。當 counter 最後到達 10 時,程式會自動跳出
for()迴圈, 並且繼續執行之後的指令。流程圖如圖 9 所示。
for(counter=0;counter<10;counter=counter+1){
digitalWrite(13,HIGH);
delay(500);
digitalWrite(13,LOW);
delay(500);
Serial.println(counter,DEC);
}
在 for()函數之後的指令為
Serial.println("All done!");
for(;;);//停止執行
8
普物實驗講義
動作音效
許多玩具裝有 microcontroller 以產生動作音效,揚聲器也可以產生頻率快速改變的動作音效。
你也可以使用 tone()指令中的參數,來產生許多有趣的效果。
動作與音效的使用包含三個部份:
1. delay 2.duration 3.Frequency
在音調之間的暫停,可以使用 noTone()+delay()指令來產生停頓。frequency 則決定音調的高低,
頻率越高音調就越高,頻率越低音調則越低,這是由 tone()指令中的 frequency 參數來決定
的。duration 是指讓音調持續時間,你可以使用 tone()指令中的 duration 參數做設定。但是
duration 參數是「播放時間」的說法只是網頁的說明,實際上執行 tone()之後會緊接著執行下一個
指令。所以若 tone()之後如果沒有用 delay()設定會出現無法預期的聲音。因此,通常 duration
參數不用會比較好設計特定音調。
ActionTones.ino 如何運作
"Alarm"的這組音調聽起來應該要像是電子鬧鈴,音調固定在頻率 1.5kHz 持續 0.5 秒,音調之間
間隔 0.5 秒。很像科幻電影中機器人說話聲音的"Robot replay",這組音調使用了多種的頻率,都
非常短暫。"Hyperspace"包含多種的頻率與持續時間。藉由使用 for()廻圈快速地改變頻率與持續
時間,可以產生許多有趣的音效。當一個 for()迴圈在另一個 for()迴圈中被執行,就稱為巢狀迴
圈。以下說明巢狀的 for()迴圈如何運作。duration 變數一開始為 15,frequency 迴圈開始進行並
且傳送頻率到壓電揚聲器,從頻率 2000、2020、2040 直到 2500。當 frequency 迴圈結
束,duration 迴圈重複它接下來的 15 個程序,所以把計算 duration 的 for()迴圈之數值減少 1,然
後繼續 frequency 迴圈
9
普物實驗講義
for(duration=15;duration>=1;duration--){//duration--代表 duration=duration-1
for(frequency=2000;frequency<=2500;frequency=frequency+20){
tone(SP_PIN,frequency);
delay(duration);
noTone(SP_PIN);
}
}
ReactionTimer.ino 如何運作
因為程式必須追蹤下壓前所累積的時間,所以宣告一個 timeCounter 變數。另外也宣告一個布林
變數 val 來儲存按鈕的按壓情形。最後為了提高程式碼的可讀性,同時也分定義了三個接腳名稱。
int timeCounter=0;
int counter=0;
boolean val=0;
const byte Button =
11; const byte SP_PIN
=8; const byte LED
=13;
這些字串是序列埠監控視窗給玩家的指示
Serial.println("When the ringtone is over, press the button");//顯示提示字串
Serial.println("go as fast as you can.");
程式開始執行後,首先出現幾聲音效,模擬賽車出發前的提示,提醒玩家於最後一聲結束時,必
須按下按鈕。
tone(SP_PIN, 1500); delay(500); noTone(SP_PIN);delay(500);
tone(SP_PIN, 1500); delay(500); noTone(SP_PIN);delay(500);
tone(SP_PIN, 1500); delay(500); noTone(SP_PIN);delay(500);
tone(SP_PIN, 3000); delay(1000); noTone(SP_PIN);
裡 面 的 do_while()函數需要特別的看看。do_while()能用一個條件,決定是否跳出迴圈,繼續執
行後面的指令(見圖 11 程式流程圖)。範例中的 do_while()會重複執行,直到按鍵壓下,即
val=1。while()函數裡的括弧裡敍述為判斷的條件,true 即執行函數內的主程式;false 即跳脫函
數。本例中,若按鍵不按,則 val=0 但 val 前有一個驚嘆號(! boolean operator)布林運算子,將
val 取 not(反相,即 true 變 false;false 變 true),因此程式會在函數內,重覆執行函數內主體程
式。直到按鍵壓下後程式才會脫離 do_while()函數。
1
普物實驗講義
while()
do while()
設定 設定
迴圈 迴圈
圖 11
迴圈 while()及 do while()程式流程圖
false
兩者的差別在於 while()先檢查
判斷 離開 主體 條件再執行迴圈主體,而 do
條件 迴圈 while()則至少執行一次迴圈主
體再檢查條件。
改變
true
條件
迴圈
主體
true false
判
斷
離開
改變 條 迴圈
條件 件
離 開 do_whil()函數之後,會繼續執行之後的程式敘述。點亮 LED,提醒玩家計時結束,延遲 1
秒後再出現提示字串。
digitalWrite(LED,HIGH);//LED 亮,計時結束
delay(1000); //Delay 1 second.
序列埠監控視窗中會展現出結果
Serial.print("\n Your time was "); //Display time measurement.
Serial.print(timeCounter,DEC);
Serial.println(" ms.\n"); //"\n"為換行指令
Serial.println("To play again, press the button down again."); //Play again instructions.
結束後,有一個 while()迴圈。迴圈內程式主體只是讀取按鈕狀態。離開迴圈的條件就是按下按
鈕。目的是就等待玩家準備重啟遊戲。一旦離開迴圈會將一些變數回復預設值,關閉 LED 及延
遲 1s 後繼續往下執行程式。
val=0; //為什麼 val 要重設為 0?
while(!val){ //等待按鈕,重啟遊戲
val = digitalRead(Button);
}
timeCounter=0;
digitalWrite(LED,LOW); delay(1000);
1
普物實驗講義
long)。你可以查一下它的範圍有多大?
unsigned int timeCounter; //修正這個
除了擴大變數範圍外,另一種方式是限制最大時間。例如限制 10 秒,之後就不再計數,統一以
>10 方式呈現結果。
boolean over=0; //再宣告一個 over 變數來記錄 timeCounter 是否大於 10 的狀態。
在程式末的 timeCounter=0;之後再加上 over=0;記得每次都要先歸零,不然只有第一次正常。
在 timeCounter++;之後再加上
if(timeCounter==10000){//判斷是否計數到 10s,其中雙等號"=="是判斷是否相等的運算子
val=1; //設定將結束迴圈
over=1;//記錄已超出 10 的狀態
}
將 Serial.println(timeCounter,DEC);改為
if(over){//若超出 10s 則
Serial.print(">10000");//直接呈現>10s 結果
}
else{//否則就呈現實際結果
Serial.print(timeCounter,DEC);
}
2. 玩家很快地發現,第三聲時間是 1 秒,在玩過幾次之後,他們開始很會預測時間,所以成績不
再是準確的反應時間。
Arduino 有一個 random()指令,以下是如何使用 random( ) 指令修正程式:
a. 在程式的一開始,宣告一個新的變數 value,將它初始值設定在 0。
int timeCounter=0;
int value=0; //加入這個