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 接線圖
圖一  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 波形
圖二  工作週期為 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;

如圖三所示,變數 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 = - changeAmoun將 changeAmount 變號,原本為負值 ($-5$),經變號後成正值($+5$) 準備接下來的 Darkness 漸增過程。


while (changeAmount > 0 && Darkness <= 255) { 
      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 漸減。




留言

這個網誌中的熱門文章

三段式電子開關電路

陣列 (C++)

首數、尾數與位數

分壓偏壓 BJT 放大電路的直流分析及其近似解的條件

MOSFET 共汲極放大電路 (源極隨耦器) 小訊號分析

為什麼理想的 OPA 電壓放大器有虛短路與虛斷路現象

具有倒數計時自動回復功能的行人穿越道號誌控制電路