Arduino Basic (5) – PWM 類比輸出

當你想用單晶片控制馬達時,最大的麻煩一定是轉速的控制。一般來說,數位電路只能會送出高態與低態兩種電壓,也就是 Arduino 的正 5V 以及 0V。而這種電壓只能控制馬達轉或不轉,並無法控制轉速。因此我們需要倚靠 PWM 來做控制。

幸運的是,Arduino 的晶片也有提供這個功能。

基本語法

Arduino 的 PWM 控制的語法也很簡單,首先要先定義腳位為輸出

pinMode(腳位, OUTPUT);    // UNO:  3, 5, 6, 9, 10, 11

然後使用這個語法來控制

// 數值:0 ~ 255
analogWrite(腳位, 數值);

呼吸燈

緩緩亮起又緩緩暗淡的 LED 燈。

硬體接線

程式碼

int led = 9;      // LED 腳位
int val = 0;      // 亮度值
int isMax = 0;    // 紀錄亮度是否為最亮

void setup()
{
    pinMode(led, OUTPUT);
}

void loop()
{
    analogWrite(led, val);

    // 如果亮度小於 254 且不是最亮
    if( val < 254 && !isMax )
        i++;
    else
        isMax = 1;

    // 如果亮度大於等於 0 且曾經為最亮        
    if( val >= 0 && isMax )
        i--;
    else
        isMax = 0;
}

流水呼吸燈

跑馬燈不夠炫,來個更酷炫的拖曳燈吧!

接線與模擬

程式碼

雖然上面的模擬器已經有了,不過我還是貼上來比較好看些。

// 設定 LED PWM 腳位
int led[6] = {3, 5, 6, 9, 10, 11};
// 計算 LED 陣列長度
int led_length = sizeof(led) / sizeof(int);
// 4個依序遞減的亮度
int bright[4] = {128, 32, 8, 0};
// 延遲
int d = 80;
// 廣域變數
int i, j;

void setup() {
  // 設定為輸出
  for(int i=0;i<led_length;i++) {
    pinMode(led[i], OUTPUT);
  }
}

void loop() {
  // 從第一個燈開始
  for (i=0;i<led_length;i++) {
    analogWrite(led[i], 255);
    // 後面的燈逐個給予不同亮度的值
    for(j=0; ((j<4) && (i-j>0)); j++) {
      analogWrite(led[i-j-1], bright[j]);
    }
    delay(d);
  }

  // 把後續的燈慢慢滅掉
  for (j=i-4; i-j > 0; j++) {
    for (int k=0; k<i-j; k++) {
      analogWrite(led[j+k], bright[3-k]);
    }
    delay(d);
  }
}

到這邊,我們就把基本的 PWM 輸出的部份講完了,然後最後這個範例不錯對吧? 可惜 UNO 上只有 6 個 PWM,不然會更好看。

題外話,關於模擬器的部份是意外找到的,它是一個有相當多功能的線上電路模擬器,而且介面操作十分簡單,相當適合當手邊沒有足夠材料但又手癢想要測試一些想法的時候用。

獨夜: