/* 呼吸燈 說明如何使引腳9上的LED褪色使用analogWrite()函數。 analogWrite()函數使用PWM,因此如果要更改正在使用的晶片,請確保使用另一個具有PWM功能的引腳。 在大多數Arduino上,PWM引腳以“〜”號標識,例如〜3,〜5,〜6,〜9,〜10和〜11。 brightness 為設定LED亮度 dir 為設定呼吸計數時間 */
int brightness = 0; //設定LED亮度起始為"0"
int dir = 0; //設定呼吸計數時間為"0"
int led = 9; //設定引腳
void setup()
{ pinMode(led, OUTPUT); } void loop() { dir = 5; //改變計數時間 for (brightness = 0; brightness <= 255; brightness += dir) { //向上計數 0~255 analogWrite(led, brightness); //設定LED-亮 delay(30); // Wait for 30 millisecond(s) } for (brightness = 255; brightness >= 0; brightness -= dir) { //向下計數 255~0 analogWrite(led, brightness); //設定LED-暗 delay(30); // Wait for 30 millisecond(s) } }
ChatGPT 說:
你提供的這段 Arduino 程式碼,是一個非常經典的 呼吸燈(Breathing LED)效果,使用 PWM(Pulse Width Modulation)控制 LED 的亮度循環增減,就像人呼吸時的節奏一樣。
下面是程式碼中各部分的中文說明,幫助你更深入了解每一行的用途和作用:
int brightness = 0; // 設定LED亮度起始為"0"
int dir = 0; // 設定呼吸計數時間為"0",但這個變數實際上後面馬上被覆蓋
int led = 9; // 設定LED接在數位腳位9
brightness:儲存 LED 目前的亮度值,從 0(最暗)到 255(最亮)。
dir:在 loop() 中被指定為 5,是每次亮度遞增/遞減的幅度。
led:代表接上 LED 的腳位(第 9 腳),需支援 PWM(腳位有 ~ 符號)。
void setup() {
pinMode(led, OUTPUT); // 設定腳位為輸出模式
}
初始化 LED 所接的腳位為輸出,這樣才可以使用 analogWrite() 輸出 PWM 訊號。
void loop() {
dir = 5; // 每次亮度改變的幅度(快慢程度)
// LED 漸亮
for (brightness = 0; brightness <= 255; brightness += dir) {
analogWrite(led, brightness); // 設定 LED 亮度
delay(30); // 延遲 30ms,讓變化更平滑
}
// LED 漸暗
for (brightness = 255; brightness >= 0; brightness -= dir) {
analogWrite(led, brightness); // 設定 LED 亮度
delay(30); // 延遲 30ms
}
}
使用 dir 做為亮度遞增變數會更通用:
目前你只在 loop 開頭固定將 dir = 5,實際不需要變成一個變數,除非你想實現類似於「呼吸速度自動變化」的效果。
加入 Serial.print() 進行除錯:
可以觀察亮度值變化是否如預期。
Serial.begin(9600);
Serial.println(brightness);
優化 delay():
使用 millis() 可以讓你避免阻塞式的 delay(),這樣程式可以在呼吸燈的同時執行其他任務(如感測器讀取等)。
LED 在腳位 9 上會以緩慢且平滑的方式從暗 → 亮,再從亮 → 暗,如同「呼吸」。
呼吸速度由 delay(30) 和 dir = 5 控制。
如果你想讓呼吸燈的「速度」或「柔和程度」變得更可調整,也可以用 sin() 波形來模擬更自然的呼吸燈節奏。如果你有興趣,我可以提供一個使用 sin() 模擬的呼吸燈版本。需要嗎?
太好了!使用 sin() 函數來模擬呼吸燈,可以讓 LED 的亮度變化更加平滑自然,類似真實呼吸的節奏(因為人類呼吸是非線性的,而 sin() 正好可以模擬這種節奏)。
支援 PWM 的 LED 腳位(例如 Arduino Uno 上的 9、10 等腳位)
Arduino IDE
LED + 電阻接在腳位 9(或你指定的)
我們用 sin() 函數(正弦波)來生成亮度值,在每個迴圈中,依照時間變化,算出對應的亮度。
sin() 的輸出值在 -1 到 1 之間,我們會將它轉換為 0 到 255的亮度範圍。
int led = 9; // LED 接在腳位 9
float brightness = 0; // 當前亮度
float angle = 0.0; // 用來產生正弦波的角度
float speed = 0.05; // 呼吸速度(越大越快)
void setup() {
pinMode(led, OUTPUT);
}
void loop() {
// 使用 sin() 計算亮度(值域從 -1 到 1)
brightness = sin(angle) * 127.5 + 127.5; // 轉換為 0~255
analogWrite(led, int(brightness)); // 設定 PWM 輸出亮度
angle += speed; // 增加角度(控制變化速度)
if (angle > TWO_PI) { // 超過 360 度就重設
angle = 0.0;
}
delay(20); // 控制更新頻率(可調)
}
sin(angle) 的範圍是:-1 到 +1
我們希望的亮度是:0 到 255
所以:
brightness = sin(angle) * (255 / 2) + (255 / 2)
= sin(angle) * 127.5 + 127.5
這樣可以讓 LED 的亮度在 0 到 255 之間流暢變化,且符合人眼對光感知的非線性特性,效果比線性改變更柔和自然。
想加快呼吸速度?調整 speed = 0.05,改大一點(例如 0.1)
想讓呼吸變慢更柔?調成 0.03 或更小
delay(20) 可以調整平滑度(越小越平滑)