← 回實作專案回商城

Arduino Uno R3 8 顆 LED 跑馬燈入門實作

Arduino Uno R3 8 顆 LED 跑馬燈入門實作
這是一個適合 Arduino 初學者的第一個電子實作專案。使用 Arduino Uno R3、8 顆 LED、麵包板及公對公杜邦線,學習如何控制多顆 LED 依序亮起、熄滅,製作出跑馬燈、流水燈及左右來回閃爍等顯示效果。

難度:初學|預估 60 分鐘|材料 2 種

範例程式下載

以下程式檔案對應本實作專案,可直接下載使用。

功能設計:

ARDUINO UNO R3連接二個按鍵可以加速和減速,動作的流程是全亮全滅各5次每次1秒,然後變成跑馬燈,預設也是1秒變化一次來回循環5次之後再回到全亮全滅如此循環

程式說明:
直接使用 Arduino UNO R3 + 8 顆 LED + 2 個按鍵,不需要額外 Library。
程式會一直重複以下流程:
1. 8 顆 LED 全亮 1 秒 → 全滅 1 秒,重複 5 次 
2. 進入跑馬燈: 
LED1 → LED2 → … → LED8 
再 LED7 → LED6 → … → LED1 
這樣算 來回 1 次 
共來回 5 次 
3. 再回到「全亮、全滅 5 次」 
4. 永久循環 
5. 兩顆按鍵可隨時: 
加速 
減速 
6. 預設速度為 1000 ms(1 秒) 
7. 每按一次調整 100 ms 
8. 最快 100 ms,最慢 3000 ms

使用材料

Arduino Uno R3 相容板 1 片
USB 傳輸線 1 條
麵包板 1 個
LED 8 顆
220Ω 或 330Ω 電阻 8 顆
公對公杜邦線 10~15 條
按鈕開關 2 個

接線表

8 顆 LED
每顆 LED 都要串聯一顆 220Ω~330Ω 電阻。
LED        Arduino UNO 接法
LED1 D2 D2 → 電阻 → LED 正極
LED2 D3 D3 → 電阻 → LED 正極
LED3 D4 D4 → 電阻 → LED 正極
LED4 D5 D5 → 電阻 → LED 正極
LED5 D6 D6 → 電阻 → LED 正極
LED6 D7 D7 → 電阻 → LED 正極
LED7 D8 D8 → 電阻 → LED 正極
LED8 D9 D9 → 電阻 → LED 正極
所有 LED 的短腳(負極)接到 GND。
兩顆按鍵
使用 Arduino 的 INPUT_PULLUP,所以不需要另外接 10KΩ 電阻:
按鍵 Arduino 接法
加速鍵 D10 D10 ↔ 按鍵 ↔ GND
減速鍵 D11 D11 ↔ 按鍵 ↔ GND
按下時讀到 LOW。

完整 Arduino UNO 程式
/*
  Arduino UNO R3
  8 LED 跑馬燈 + 加速/減速按鍵

  LED:
    LED1 -> D2
    LED2 -> D3
    LED3 -> D4
    LED4 -> D5
    LED5 -> D6
    LED6 -> D7
    LED7 -> D8
    LED8 -> D9

  按鍵:
    加速 -> D10 -> 按鍵 -> GND
    減速 -> D11 -> 按鍵 -> GND

  動作流程:
    1. 全亮 1 秒
    2. 全滅 1 秒
    3. 重複 5 次

    4. 跑馬燈 LED1 -> LED8 -> LED1
    5. 來回共 5 次

    6. 回到全亮/全滅
    7. 永久循環

  速度:
    預設 1000 ms
    每按一次改變 100 ms
    最快 100 ms
    最慢 3000 ms
*/

// =========================
// LED 接腳
// =========================
const byte ledPins[8] = {
  2, 3, 4, 5, 6, 7, 8, 9
};

// =========================
// 按鍵接腳
// =========================
const byte SPEED_UP_BUTTON   = 10;
const byte SPEED_DOWN_BUTTON = 11;

// =========================
// 速度設定
// =========================
unsigned long ledDelay = 1000;   // 預設 1 秒

const unsigned long MIN_DELAY = 100;    // 最快 0.1 秒
const unsigned long MAX_DELAY = 3000;   // 最慢 3 秒
const unsigned long STEP_DELAY = 100;   // 每次調整 0.1 秒

// 按鍵前一次狀態
bool lastSpeedUpState = HIGH;
bool lastSpeedDownState = HIGH;

// ======================================================
// 初始化
// ======================================================
void setup()
{
  Serial.begin(9600);

  // LED 設成輸出
  for (byte i = 0; i < 8; i++)
  {
    pinMode(ledPins[i], OUTPUT);
    digitalWrite(ledPins[i], LOW);
  }

  // 按鍵使用內部上拉
  pinMode(SPEED_UP_BUTTON, INPUT_PULLUP);
  pinMode(SPEED_DOWN_BUTTON, INPUT_PULLUP);

  Serial.println("8 LED Running Light");
  Serial.println("Default speed = 1000 ms");
}

// ======================================================
// 主程式
// ======================================================
void loop()
{
  // --------------------------------
  // 第一階段:
  // 全亮、全滅,共 5 次
  // --------------------------------
  for (byte count = 0; count < 5; count++)
  {
    allLEDOn();
    waitWithButton(ledDelay);

    allLEDOff();
    waitWithButton(ledDelay);
  }

  // --------------------------------
  // 第二階段:
  // 跑馬燈來回,共 5 次
  // --------------------------------
  for (byte cycle = 0; cycle < 5; cycle++)
  {
    // LED1 -> LED8
    for (byte i = 0; i < 8; i++)
    {
      showOnlyLED(i);
      waitWithButton(ledDelay);
    }

    // LED7 -> LED1
    //
    // LED8 不再重複一次,
    // 所以從 LED7 開始往回。
    for (int i = 6; i >= 0; i--)
    {
      showOnlyLED(i);
      waitWithButton(ledDelay);
    }
  }

  // 跑馬燈結束後全部關掉
  allLEDOff();

  // loop() 會自動重新開始
}

// ======================================================
// 全部 LED 亮
// ======================================================
void allLEDOn()
{
  for (byte i = 0; i < 8; i++)
  {
    digitalWrite(ledPins[i], HIGH);
  }
}

// ======================================================
// 全部 LED 滅
// ======================================================
void allLEDOff()
{
  for (byte i = 0; i < 8; i++)
  {
    digitalWrite(ledPins[i], LOW);
  }
}

// ======================================================
// 只點亮指定的一顆 LED
//
// index:
// 0 = LED1
// 1 = LED2
// ...
// 7 = LED8
// ======================================================
void showOnlyLED(byte index)
{
  for (byte i = 0; i < 8; i++)
  {
    if (i == index)
    {
      digitalWrite(ledPins[i], HIGH);
    }
    else
    {
      digitalWrite(ledPins[i], LOW);
    }
  }
}

// ======================================================
// 等待時間
//
// 不直接使用 delay(ledDelay),
// 因為 delay() 期間無法立即處理按鍵。
//
// 此函式等待時會持續檢查兩顆按鍵。
// ======================================================
void waitWithButton(unsigned long waitTime)
{
  unsigned long startTime = millis();

  while (millis() - startTime < waitTime)
  {
    checkButtons();

    delay(10);
  }
}

// ======================================================
// 檢查加速 / 減速按鍵
// ======================================================
void checkButtons()
{
  bool speedUpState =
    digitalRead(SPEED_UP_BUTTON);

  bool speedDownState =
    digitalRead(SPEED_DOWN_BUTTON);

  // =========================
  // 加速鍵
  // =========================
  if (speedUpState == LOW &&
      lastSpeedUpState == HIGH)
  {
    // 簡單消除彈跳
    delay(20);

    if (digitalRead(SPEED_UP_BUTTON) == LOW)
    {
      if (ledDelay > MIN_DELAY)
      {
        if (ledDelay >= MIN_DELAY + STEP_DELAY)
        {
          ledDelay -= STEP_DELAY;
        }
        else
        {
          ledDelay = MIN_DELAY;
        }
      }

      Serial.print("Speed UP : ");
      Serial.print(ledDelay);
      Serial.println(" ms");
    }
  }

  // =========================
  // 減速鍵
  // =========================
  if (speedDownState == LOW &&
      lastSpeedDownState == HIGH)
  {
    // 簡單消除彈跳
    delay(20);

    if (digitalRead(SPEED_DOWN_BUTTON) == LOW)
    {
      if (ledDelay < MAX_DELAY)
      {
        ledDelay += STEP_DELAY;

        if (ledDelay > MAX_DELAY)
        {
          ledDelay = MAX_DELAY;
        }
      }

      Serial.print("Speed DOWN : ");
      Serial.print(ledDelay);
      Serial.println(" ms");
    }
  }

  // 記錄目前按鍵狀態
  lastSpeedUpState = speedUpState;
  lastSpeedDownState = speedDownState;
}

常見問題排除

1.在進行此實作前,需先完成 Arduino IDE 安裝在電腦上且完成基本測試
2.將下載下來的程式解包並放在 Arduino 的專案目錄中,開啓並選擇 Arduino UNO 板及選擇 Port
3.若以上過程中均無法順利完成,請同學或老師協助將問題解決
4.要特別注意麵包板和杜邦線的接觸是否良好
5.上載到 Arduino UNO R3 過程中若有問題,請再檢查 1~2項,若執行過程中沒有按照流程,請檢查程式
6.若有些燈沒有亮滅,請依 4 項檢查排除
準備開始實作?

文章與採購清單分開顯示。查看材料清單後,可以把目前有庫存的材料一次加入購物車。