#include <Adafruit_NeoPixel.h>
// 定義全場 5 個獨立功能腳位
#define SIDE_PIN A0 // 跑道邊界燈(30顆,左右並聯)
#define HEAD_PIN A1 // 跑道頭綠燈(19顆)
#define TAIL_PIN A2 // 跑道尾紅燈(19顆)
#define APP_PIN A3 // 跑道進場指示燈(19顆)
#define MID_PIN A4 // 中線流星燈(30顆)
#define LAND_PIN A5 // 著陸區燈(14顆)
// 定義各燈條的數量
#define SIDE_COUNT 30
#define HEAD_COUNT 19
#define TAIL_COUNT 19
#define APP_COUNT 19
#define MID_COUNT 30
#define LAND_COUNT 14
// 宣告 5 個獨立的燈條物件
Adafruit_NeoPixel sideStrip = Adafruit_NeoPixel(SIDE_COUNT, SIDE_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel headStrip = Adafruit_NeoPixel(HEAD_COUNT, HEAD_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel tailStrip = Adafruit_NeoPixel(TAIL_COUNT, TAIL_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel appStrip = Adafruit_NeoPixel(APP_COUNT, APP_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel midStrip = Adafruit_NeoPixel(MID_COUNT, MID_PIN, NEO_GRB + NEO_KHZ800);
Adafruit_NeoPixel landStrip = Adafruit_NeoPixel(LAND_COUNT, LAND_PIN, NEO_GRB + NEO_KHZ800);
// 脈衝(流星)控制專用變數
int meteorPos = 0;
unsigned long lastMeteorTime = 0;
const int meteorSpeed = 30;
void setup() {
sideStrip.begin();
headStrip.begin();
tailStrip.begin();
appStrip.begin();
midStrip.begin();
landStrip.begin();
sideStrip.show();
headStrip.show();
tailStrip.show();
appStrip.show();
midStrip.show();
landStrip.show();
}
void loop() {
// ====================================================
// 1. 跑道邊界燈邏輯 (A0) - 奇數亮,最後四顆奇數亮黃
// ====================================================
for (int i = 0; i < SIDE_COUNT; i++) {
if (i % 2 != 0) {
if (i >= 23) {
sideStrip.setPixelColor(i, sideStrip.Color(255, 255, 0));
} else {
sideStrip.setPixelColor(i, sideStrip.Color(255, 255, 255));
}
} else {
sideStrip.setPixelColor(i, sideStrip.Color(0, 0, 0));
}
}
// ====================================================
// 2. 跑道頭綠燈邏輯 (A1) - 間隔亮綠光 (奇數亮)
// ====================================================
for (int i = 0; i < HEAD_COUNT; i++) {
if (i % 2 != 0) {
headStrip.setPixelColor(i, headStrip.Color(0, 255, 0));
} else {
headStrip.setPixelColor(i, headStrip.Color(0, 0, 0));
}
}
// ====================================================
// 3. 跑道尾紅燈邏輯 (A2) - 間隔亮紅光 (奇數亮)
// ====================================================
for (int i = 0; i < TAIL_COUNT; i++) {
if (i % 2 != 0) {
tailStrip.setPixelColor(i, tailStrip.Color(255, 0, 0));
} else {
tailStrip.setPixelColor(i, tailStrip.Color(0, 0, 0));
}
}
// ====================================================
// 4. 進場指示燈邏輯 (A3) - 19顆對稱紅白配置
// ====================================================
for (int i = 0; i < APP_COUNT; i++) {
// 條件一:中心對稱點與左右鄰居亮白燈 (8, 9, 10)
if (i == 8 || i == 9 || i == 10) {
appStrip.setPixelColor(i, appStrip.Color(255, 255, 255)); // 亮白光
}
// 條件二:第一對紅燈區 (5, 6) 與 (12, 13)
else if (i == 5 || i == 6 || i == 12 || i == 13) {
appStrip.setPixelColor(i, appStrip.Color(255, 0, 0)); // 亮紅光
}
// 條件三:第二對紅燈區 (2, 3) 與 (15, 16)
else if (i == 2 || i == 3 || i == 15 || i == 16) {
appStrip.setPixelColor(i, appStrip.Color(255, 0, 0)); // 亮紅光
}
// 其餘編號 (0, 1, 4, 7, 11, 14, 17, 18) 一律不亮
else {
appStrip.setPixelColor(i, appStrip.Color(0, 0, 0)); // 熄滅
}
}
// ====================================================
// 5. 著陸區燈邏輯 (A5) - 一次亮兩個、一次暗兩個
// ====================================================
for (int i = 0; i < LAND_COUNT; i++) {
if ((i / 2) % 2 == 0) {
landStrip.setPixelColor(i, landStrip.Color(255, 255, 255));
} else {
landStrip.setPixelColor(i, landStrip.Color(0, 0, 0));
}
}
// ====================================================
// 6. 中線動態流星邏輯 (A4) - 時間觸發式
// ====================================================
for (int i = 0; i < MID_COUNT; i++) {
midStrip.setPixelColor(i, midStrip.Color(0, 0, 0));
}
midStrip.setPixelColor(meteorPos, midStrip.Color(255, 255, 255));
if (meteorPos - 1 >= 0) midStrip.setPixelColor(meteorPos - 1, midStrip.Color(100, 100, 100));
if (meteorPos - 2 >= 0) midStrip.setPixelColor(meteorPos - 2, midStrip.Color(30, 30, 30));
if (millis() - lastMeteorTime >= meteorSpeed) {
meteorPos++;
lastMeteorTime = millis();
if (meteorPos >= MID_COUNT + 2) {
meteorPos = 0;
}
}
// ====================================================
// 五大系統,同步點亮
// ====================================================
sideStrip.show();
headStrip.show();
tailStrip.show();
appStrip.show();
midStrip.show();
landStrip.show();
delay(1);
}