Arduino:控制多顆 LED 依序漸亮與漸熄且循環不已
Arduino 控制板:Uno
程式碼編寫語言:C 語言
功能
六顆 LED 依序輪流單顆漸亮後漸熄,如此循環不已。
電路接線圖
硬體電路如圖一所示,六顆 LED 的陽極皆接至 $+5V$,陰極分別透過六顆 $220$ $ \Omega$ 電阻接至 Uno 的 pin 11,pin 10,pin 9,pin 6,pin 5,以及 pin 3。
圖一 Arduino Uno 與 6 顆 LED 的接線圖
程式碼
int led_pin[ ]={11,10,9,6,5,3}; /* 將可作為類比輸出的 6 支接腳編號,置於陣列中 */
int Darkness = 255; /* LED 暗度初始值設為最大值 255 */
int changeAmount = -5; /* 暗度變化量初始值為 -5 */
void setup() {
for (int i = 0;i < 6;i++){
pinMode(led_pin[i], OUTPUT); /* 設定連接 6 顆 LED 的 6 支接腳為輸出接腳 */
digitalWrite(led_pin[i], HIGH); /* 令所有 LED 初始狀態為熄滅 */
}
}
void loop() {
for (int i=0; i<6; i++){ /* for 迴圈控制 6 顆 LED 依序輪流漸亮後漸熄 */
while (changeAmount < 0 && Darkness >=0){ /* 處理單顆 LED漸亮過程 */
analogWrite(led_pin[i], Darkness); /* 輸出類比電壓 */
Darkness = Darkness + changeAmount; /* 改變暗度值 */
delay(25); /* 延遲一段時間,讓 LED 亮度變化明顯 */
}
if (Darkness < 0){ /* 0 $\le$ Darkness $\le$ 255,若 Darkness < 0,須令 Darkness = 0 */
changeAmount = -changeAmount; /* 將 changeAmount 變號 */
Darkness = 0;
}
/* 處理單顆 LED漸熄過程 */
while (changeAmount > 0 && Darkness <= 255) {
analogWrite(led_pin[i], Darkness);
Darkness = Darkness + changeAmount;
delay(25);
}
if (Darkness > 255){ /* 若 Darkness > 255,須令 Darkness = 255 */
changeAmount = -changeAmount; /* 將 changeAmount 變號 */
Darkness = 255;
}
}
}
程式碼說明
int led_pin[ ]={11,10,9,6,5,3};
LED 漸亮與漸熄的效果,是由 Arduino Uno 輸出 PWM (Pulse-Width Modulation,脈波寬度調變 ) 波形產生的。PWM 是透過脈波寬度的調整來產生類比信號的一種技術〔脈波寬度愈大,則平均電壓愈大〕。注意 Arduino Uno 只有標示為 ~ 的接腳,才可指定為 PWM 輸出接腳,此類接腳包含 pin 11,pin 10,pin 9,pin 6,pin 5,以及 pin 3。由於六顆 LED 須依序漸亮與漸熄且循環不已,因此將這六顆 LED 接腳編號存放於陣列中,後面再以 for 迴圈的變數作為陣列的索引值依序取出這六顆 LED 接腳編號加以控制。
PWM 指令:analogWrite(pin, value)
- pin:指定的 PWM 輸出接腳
- value:用來設定輸出 PWM 波形的工作週期,可設定數值為 0 ~ 255。例如 value 設為 51,如圖二所示,則輸出的 PWM 波形的工作週期為 $\frac {51}{255}\times100 \%= 20\%$,亦即輸出的平均電壓為最大輸出電壓的 $0.2$ 倍
圖二 工作週期為 20% 的 PWM 波形
因麵包板上的 LED 的連接方式對數位訊號而言為低態動作,意即若連接的是數位接腳且輸出 LOW,LED 會亮;反之,數位接腳輸出 HIGH,LED 會熄。而本電路連接 LED 的類比接腳若執行類比輸出指令 analogWrite(pin, value) ,且其中的 value 參數設為 255 則輸出後 LED 會是最暗;若 value 為 0 則 LED 為最亮。此外,value 的值若介於 0~255 間,則 LED 亮度則是介於最亮與熄之間,值愈小則愈亮,值愈大則愈暗。
int Darkness = 255;
int changeAmount = -5;
int changeAmount = -5;
如圖三所示,變數 Darkness 代表暗度,且 0 $\le$ Darkness $\le$ 255,而 Darkness 初始值設為 255 則表示 LED 的初始狀態為熄滅。變數 changeAmount 代表暗度的一次變化量,其初始值設為 -5,表示一開始 LED 的暗度值會逐漸減少〔亦即逐漸變亮〕。
圖三 暗度變化圖
for (int i = 0;i < 6;i++){
pinMode(led_pin[i], OUTPUT);
digitalWrite(led_pin[i], HIGH);
}
利用執行六次的 for 迴圈,逐一執行 pinMode( led[i], OUTPUT) ,以將使用到的六個類比接腳規劃為輸出接腳,並且逐一執行 digitalWrite( led[i], HIGH) ,令連接的六顆 LED 初始狀態為全熄。因為此 for 迴圈是置於 setup() 函式內,所以只會執行一次。
I/O 接腳輸出入規劃指令:pinMode(pin, mode)
- pin:指定腳編號
- mode:指定腳的模式,可為 INPUT,OUTPUT,以及 INPUT_PULLUP
數位輸出指令:digitalWrite(pin, value)
- pin:指定腳編號
- value:可為 HIGH 或 LOW
for (int i = ; i < 6; i++){
.....
}
利用執行六次的 for 迴圈,逐一執行六顆 LED 依序輪流漸亮後漸熄的控制。因為此 for 迴圈置於 loop() 函式內,所以會執行無窮多次,亦即六顆 LED 依序輪流漸亮後漸熄的過程會循環不已,直至 Uno 電源消失或故障為止。
while (changeAmount < 0 && Darkness >=0){
analogWrite(led_pin[i], Darkness);
Darkness = Darkness + changeAmount;
delay(25);
}
while 迴圈在此處理單顆 LED 由熄滅狀態至最亮的過程。如圖三所示,要 LED 漸亮則 changeAmount $\lt 0$,Darkness $\ge 0$,以及須以 Darkness = Darkness + changeAmount 來逐一改變暗度值,LED 才會逐漸亮。delay(25) 會延遲 25ms,讓LED 亮度變化明顯。
if (Darkness < 0){
changeAmount = -changeAmount;
Darkness = 0;
}
由於 0 $\le$ Darkness $\le$ 255,因此當 Darkness 值小於 0 時,須令其為 0 (Darkness = 0),且令 changeAmount = - changeAmount 將 changeAmount 變號,原本為負值 ($-5$),經變號後成正值($+5$) 準備接下來的 Darkness 漸增過程。
while (changeAmount > 0 && Darkness <= 255) {
analogWrite(led_pin[i], Darkness);
Darkness = Darkness + changeAmount;
delay(25);
}
analogWrite(led_pin[i], Darkness);
Darkness = Darkness + changeAmount;
delay(25);
}
while 迴圈在此處理單顆 LED 由最亮狀態至最暗的過程。如圖三所示,要 LED 漸暗則 changeAmount $\gt 0$,Darkness $\le 255$,以及須以 Darkness = Darkness + changeAmount 來逐一改變暗度值,LED 才會逐漸暗。delay(25) 會延遲 25ms,讓 LED 亮度變化明顯。
if (Darkness > 255){
changeAmount = -changeAmount;
Darkness = 255;
}
由於 0 $\le$ Darkness $\le$ 255,因此當 Darkness 值大於 255 時,須令其為 255 (Darkness = 255),且令 changeAmount = - changeAmount 將 changeAmount 變號,原本為負值 ($+5$),經變號後成正值($-5$) 準備接下來的 Darkness 漸減。



留言
張貼留言