Arduino Blink 闪烁灯完全指南
1. 基础版本
1.1 最简单的Blink程序
// 最简单的Blink程序 - 使用板载LED
void setup() {// 初始化引脚模式 - D13引脚连接到板载LEDpinMode(LED_BUILTIN, OUTPUT);
}void loop() {digitalWrite(LED_BUILTIN, HIGH); // LED亮delay(1000); // 等待1秒digitalWrite(LED_BUILTIN, LOW); // LED灭delay(1000); // 等待1秒
}
1.2 使用自定义引脚
// 使用外部LED连接到特定引脚
const int LED_PIN = 13; // 可以改为任何数字引脚void setup() {pinMode(LED_PIN, OUTPUT); // 将引脚设置为输出模式Serial.begin(9600); // 初始化串口用于调试Serial.println("Blink Program Started!");
}void loop() {digitalWrite(LED_PIN, HIGH);Serial.println("LED ON"); // 串口输出状态delay(1000); // 亮1秒digitalWrite(LED_PIN, LOW);Serial.println("LED OFF"); // 串口输出状态delay(1000); // 灭1秒
}
2. 变体版本
2.1 不对称闪烁
const int LED_PIN = 13;void setup() {pinMode(LED_PIN, OUTPUT);Serial.begin(9600);
}void loop() {// 亮的时间短,灭的时间长 - 心跳效果digitalWrite(LED_PIN, HIGH);delay(200); // 亮0.2秒digitalWrite(LED_PIN, LOW);delay(800); // 灭0.8秒// Morse码SOS: ... --- ...// S: 短亮3次for(int i = 0; i < 3; i++) {digitalWrite(LED_PIN, HIGH);delay(200); // 短点digitalWrite(LED_PIN, LOW);delay(200); // 字符内间隔}delay(400); // 字符间间隔// O: 长亮3次for(int i = 0; i < 3; i++) {digitalWrite(LED_PIN, HIGH);delay(600); // 长划digitalWrite(LED_PIN, LOW);delay(200); // 字符内间隔}delay(400); // 字符间间隔// S: 短亮3次for(int i = 0; i < 3; i++) {digitalWrite(LED_PIN, HIGH);delay(200); // 短点digitalWrite(LED_PIN, LOW);delay(200); // 字符内间隔}delay(2000); // 单词间长间隔
}
2.2 呼吸灯效果
// 使用PWM实现呼吸灯效果
const int LED_PIN = 9; // 必须是支持PWM的引脚(3,5,6,9,10,11)void setup() {pinMode(LED_PIN, OUTPUT);Serial.begin(9600);
}void loop() {// 亮度逐渐增加for(int brightness = 0; brightness <= 255; brightness++) {analogWrite(LED_PIN, brightness); // PWM输出,0-255delay(5); // 控制变化速度}// 亮度逐渐减少for(int brightness = 255; brightness >= 0; brightness--) {analogWrite(LED_PIN, brightness);delay(5);}delay(1000); // 呼吸完成后暂停1秒
}
3. 多LED控制
3.1 多个LED流水灯
// 控制多个LED实现流水灯效果
const int NUM_LEDS = 4;
int ledPins[NUM_LEDS] = {8, 9, 10, 11}; // 4个LED连接的引脚void setup() {// 初始化所有LED引脚for(int i = 0; i < NUM_LEDS; i++) {pinMode(ledPins[i], OUTPUT);}Serial.begin(9600);Serial.println("Running LED Chaser...");
}void loop() {// 正向流动for(int i = 0; i < NUM_LEDS; i++) {digitalWrite(ledPins[i], HIGH); // 点亮当前LEDdelay(200); // 保持200毫秒digitalWrite(ledPins[i], LOW); // 熄灭当前LED}// 反向流动for(int i = NUM_LEDS - 1; i >= 0; i--) {digitalWrite(ledPins[i], HIGH);delay(200);digitalWrite(ledPins[i], LOW);}// 同时闪烁效果for(int i = 0; i < 3; i++) {// 全部点亮for(int j = 0; j < NUM_LEDS; j++) {digitalWrite(ledPins[j], HIGH);}delay(200);// 全部熄灭for(int j = 0; j < NUM_LEDS; j++) {digitalWrite(ledPins[j], LOW);}delay(200);}
}
3.2 RGB LED控制
// 控制RGB LED显示不同颜色
const int RED_PIN = 9;
const int GREEN_PIN = 10;
const int BLUE_PIN = 11;void setup() {pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);Serial.begin(9600);Serial.println("RGB LED Controller Ready");
}void loop() {// 红色setColor(255, 0, 0);Serial.println("Red");delay(1000);// 绿色setColor(0, 255, 0);Serial.println("Green");delay(1000);// 蓝色setColor(0, 0, 255);Serial.println("Blue");delay(1000);// 黄色setColor(255, 255, 0);Serial.println("Yellow");delay(1000);// 紫色setColor(255, 0, 255);Serial.println("Purple");delay(1000);// 青色setColor(0, 255, 255);Serial.println("Cyan");delay(1000);// 白色setColor(255, 255, 255);Serial.println("White");delay(1000);// 彩虹渐变rainbowEffect();
}void setColor(int red, int green, int blue) {analogWrite(RED_PIN, red);analogWrite(GREEN_PIN, green);analogWrite(BLUE_PIN, blue);
}void rainbowEffect() {Serial.println("Rainbow Effect");// 红色到绿色for(int i = 0; i <= 255; i++) {setColor(255 - i, i, 0);delay(10);}// 绿色到蓝色for(int i = 0; i <= 255; i++) {setColor(0, 255 - i, i);delay(10);}// 蓝色到红色for(int i = 0; i <= 255; i++) {setColor(i, 0, 255 - i);delay(10);}
}
4. 带交互的Blink
4.1 按钮控制LED
// 按钮控制LED开关
const int LED_PIN = 13;
const int BUTTON_PIN = 2;int buttonState = 0; // 存储按钮状态void setup() {pinMode(LED_PIN, OUTPUT);pinMode(BUTTON_PIN, INPUT_PULLUP); // 使用内部上拉电阻Serial.begin(9600);Serial.println("Button-controlled Blink");
}void loop() {// 读取按钮状态buttonState = digitalRead(BUTTON_PIN);// 注意:使用上拉电阻时,按下为LOW,释放为HIGHif (buttonState == LOW) {digitalWrite(LED_PIN, HIGH); // 按下时LED亮Serial.println("Button pressed - LED ON");} else {digitalWrite(LED_PIN, LOW); // 释放时LED灭Serial.println("Button released - LED OFF");}delay(50); // 防抖动延迟
}
4.2 双击检测
// 检测按钮双击控制LED
const int LED_PIN = 13;
const int BUTTON_PIN = 2;unsigned long lastPressTime = 0;
bool ledState = false;
int clickCount = 0;void setup() {pinMode(LED_PIN, OUTPUT);pinMode(BUTTON_PIN, INPUT_PULLUP);Serial.begin(9600);Serial.println("Double Click Detector");
}void loop() {int buttonState = digitalRead(BUTTON_PIN);if (buttonState == LOW) { // 按钮按下delay(50); // 防抖动if (digitalRead(BUTTON_PIN) == LOW) { // 确认按下unsigned long currentTime = millis();// 检查是否是双击(500ms内两次按下)if (currentTime - lastPressTime < 500) {clickCount++;if (clickCount == 2) { // 双击ledState = !ledState; // 切换LED状态digitalWrite(LED_PIN, ledState);if (ledState) {Serial.println("Double click - LED ON");} else {Serial.println("Double click - LED OFF");}clickCount = 0; // 重置计数}} else {clickCount = 1; // 第一次点击}lastPressTime = currentTime;// 等待按钮释放while (digitalRead(BUTTON_PIN) == LOW) {delay(10);}}}// 超时重置if (millis() - lastPressTime > 1000) {clickCount = 0;}
}
5. 高级效果
5.1 使用中断的Blink
// 使用定时器中断实现精确闪烁
#include <TimerOne.h>const int LED_PIN = 13;
bool ledState = false;void setup() {pinMode(LED_PIN, OUTPUT);Serial.begin(9600);// 初始化Timer1,设置中断间隔500000微秒(0.5秒)Timer1.initialize(500000);// 绑定中断处理函数Timer1.attachInterrupt(blinkISR);Serial.println("Timer Interrupt Blink Started");
}void loop() {// 主循环可以执行其他任务// LED闪烁由中断自动处理// 示例:每秒打印一次状态static unsigned long lastPrint = 0;if (millis() - lastPrint >= 1000) {Serial.print("Running... Uptime: ");Serial.print(millis() / 1000);Serial.println("s");lastPrint = millis();}
}// 中断服务程序 - 必须简短
void blinkISR() {ledState = !ledState;digitalWrite(LED_PIN, ledState);
}
5.2 非阻塞闪烁
// 不使用delay()的非阻塞闪烁
const int LED_PIN = 13;// 时间变量
unsigned long previousMillis = 0;
const long interval = 1000; // 闪烁间隔(毫秒)bool ledState = false; // LED当前状态void setup() {pinMode(LED_PIN, OUTPUT);Serial.begin(9600);Serial.println("Non-blocking Blink Started");
}void loop() {// 获取当前时间unsigned long currentMillis = millis();// 检查是否到达切换时间if (currentMillis - previousMillis >= interval) {// 保存上次切换时间previousMillis = currentMillis;// 切换LED状态ledState = !ledState;digitalWrite(LED_PIN, ledState);// 输出状态if (ledState) {Serial.println("LED ON");} else {Serial.println("LED OFF");}}// 这里可以添加其他非阻塞任务// 例如:读取传感器、处理串口数据等checkSerial();
}void checkSerial() {if (Serial.available()) {char command = Serial.read();switch(command) {case 'f': // 快速闪烁interval = 200;Serial.println("Fast blink mode");break;case 's': // 慢速闪烁interval = 2000;Serial.println("Slow blink mode");break;case 'n': // 正常闪烁interval = 1000;Serial.println("Normal blink mode");break;}}
}
6. 模式切换系统
6.1 多种闪烁模式
// 多模式LED控制器
const int LED_PIN = 13;
const int BUTTON_PIN = 2;int mode = 0; // 当前模式
const int MODE_COUNT = 4; // 模式数量void setup() {pinMode(LED_PIN, OUTPUT);pinMode(BUTTON_PIN, INPUT_PULLUP);Serial.begin(9600);Serial.println("Multi-mode LED Controller");Serial.println("Press button to change mode");
}void loop() {// 检查按钮切换模式if (digitalRead(BUTTON_PIN) == LOW) {delay(50); // 防抖动if (digitalRead(BUTTON_PIN) == LOW) {mode = (mode + 1) % MODE_COUNT;Serial.print("Mode changed to: ");Serial.println(mode);// 等待按钮释放while(digitalRead(BUTTON_PIN) == LOW) {delay(10);}}}// 根据模式执行不同的闪烁效果switch(mode) {case 0:mode0Blink(); // 正常闪烁break;case 1:mode1Blink(); // 快速闪烁break;case 2:mode2Blink(); // 心跳效果break;case 3:mode3Blink(); // SOS信号break;}
}// 模式0: 正常闪烁 (1Hz)
void mode0Blink() {digitalWrite(LED_PIN, HIGH);delay(500);digitalWrite(LED_PIN, LOW);delay(500);
}// 模式1: 快速闪烁 (5Hz)
void mode1Blink() {digitalWrite(LED_PIN, HIGH);delay(100);digitalWrite(LED_PIN, LOW);delay(100);
}// 模式2: 心跳效果
void mode2Blink() {digitalWrite(LED_PIN, HIGH);delay(200);digitalWrite(LED_PIN, LOW);delay(200);digitalWrite(LED_PIN, HIGH);delay(200);digitalWrite(LED_PIN, LOW);delay(600);
}// 模式3: SOS摩尔斯电码
void mode3Blink() {// S: ... (短点3次)for(int i = 0; i < 3; i++) {digitalWrite(LED_PIN, HIGH);delay(200);digitalWrite(LED_PIN, LOW);delay(200);}delay(400);// O: --- (长划3次)for(int i = 0; i < 3; i++) {digitalWrite(LED_PIN, HIGH);delay(600);digitalWrite(LED_PIN, LOW);delay(200);}delay(400);// S: ... (短点3次)for(int i = 0; i < 3; i++) {digitalWrite(LED_PIN, HIGH);delay(200);digitalWrite(LED_PIN, LOW);delay(200);}delay(1000);
}
6.2 串口控制模式
// 通过串口命令控制LED模式
const int LED_PIN = 13;enum BlinkMode {MODE_OFF,MODE_SLOW,MODE_NORMAL,MODE_FAST,MODE_BREATH,MODE_RAINBOW
};BlinkMode currentMode = MODE_OFF;void setup() {pinMode(LED_PIN, OUTPUT);Serial.begin(115200);Serial.println("=== LED Control System ===");Serial.println("Commands:");Serial.println(" off - Turn LED off");Serial.println(" slow - Slow blink (2Hz)");Serial.println(" normal - Normal blink (1Hz)");Serial.println(" fast - Fast blink (5Hz)");Serial.println(" breath - Breathing effect");Serial.println(" rainbow - RGB rainbow effect");
}void loop() {// 处理串口命令if (Serial.available()) {String command = Serial.readStringUntil('\n');command.trim();if (command == "off") {currentMode = MODE_OFF;digitalWrite(LED_PIN, LOW);Serial.println("LED off");}else if (command == "slow") {currentMode = MODE_SLOW;Serial.println("Slow blink mode");}else if (command == "normal") {currentMode = MODE_NORMAL;Serial.println("Normal blink mode");}else if (command == "fast") {currentMode = MODE_FAST;Serial.println("Fast blink mode");}else if (command == "breath") {currentMode = MODE_BREATH;Serial.println("Breathing effect mode");}else if (command == "rainbow") {currentMode = MODE_RAINBOW;Serial.println("Rainbow effect mode");}else {Serial.println("Unknown command");}}// 根据当前模式执行switch(currentMode) {case MODE_SLOW:digitalWrite(LED_PIN, HIGH);delay(1000);digitalWrite(LED_PIN, LOW);delay(1000);break;case MODE_NORMAL:digitalWrite(LED_PIN, HIGH);delay(500);digitalWrite(LED_PIN, LOW);delay(500);break;case MODE_FAST:digitalWrite(LED_PIN, HIGH);delay(100);digitalWrite(LED_PIN, LOW);delay(100);break;case MODE_BREATH:for(int i = 0; i <= 255; i++) {analogWrite(LED_PIN, i);delay(5);}for(int i = 255; i >= 0; i--) {analogWrite(LED_PIN, i);delay(5);}break;case MODE_OFF:default:// 什么都不做break;}
}
7. 带传感器的Blink
7.1 光控LED
// 根据环境光线控制LED
const int LED_PIN = 13;
const int LDR_PIN = A0; // 光敏电阻void setup() {pinMode(LED_PIN, OUTPUT);pinMode(LDR_PIN, INPUT);Serial.begin(9600);Serial.println("Light-controlled LED");
}void loop() {// 读取光敏电阻值(0-1023)int lightLevel = analogRead(LDR_PIN);Serial.print("Light level: ");Serial.println(lightLevel);// 根据光线强度控制LEDif (lightLevel < 500) { // 光线较暗digitalWrite(LED_PIN, HIGH);Serial.println("Dark - LED ON");} else { // 光线较亮digitalWrite(LED_PIN, LOW);Serial.println("Bright - LED OFF");}delay(500); // 每0.5秒检测一次
}
7.2 温度控制闪烁频率
// 根据温度改变LED闪烁频率
#include <DHT.h>#define DHTPIN 2
#define DHTTYPE DHT11const int LED_PIN = 13;DHT dht(DHTPIN, DHTTYPE);void setup() {pinMode(LED_PIN, OUTPUT);dht.begin();Serial.begin(9600);Serial.println("Temperature-controlled Blink");
}void loop() {// 读取温度float temperature = dht.readTemperature();if (isnan(temperature)) {Serial.println("Failed to read temperature!");return;}Serial.print("Temperature: ");Serial.print(temperature);Serial.println("°C");// 根据温度计算闪烁间隔// 温度越高,闪烁越快int blinkInterval = map(temperature, 20, 35, 1000, 100);blinkInterval = constrain(blinkInterval, 100, 1000);Serial.print("Blink interval: ");Serial.print(blinkInterval);Serial.println("ms");// 闪烁一次digitalWrite(LED_PIN, HIGH);delay(blinkInterval / 2); // 亮半周期digitalWrite(LED_PIN, LOW);delay(blinkInterval / 2); // 灭半周期
}
8. 综合项目:智能状态指示灯
/*
智能状态指示灯系统
功能:
1. 正常模式:缓慢呼吸灯
2. 警告模式:黄色快速闪烁
3. 错误模式:红色常亮
4. 网络模式:蓝色心跳
5. 串口命令控制模式切换
*/// 如果是RGB LED,使用以下引脚定义
const int RED_PIN = 9;
const int GREEN_PIN = 10;
const int BLUE_PIN = 11;// 如果是单色LED,使用这个引脚
const int LED_PIN = 13;enum SystemState {STATE_NORMAL,STATE_WARNING,STATE_ERROR,STATE_NETWORK,STATE_CUSTOM
};SystemState currentState = STATE_NORMAL;void setup() {// 初始化引脚pinMode(RED_PIN, OUTPUT);pinMode(GREEN_PIN, OUTPUT);pinMode(BLUE_PIN, OUTPUT);// 初始化串口Serial.begin(115200);Serial.println("=== Smart Status Indicator ===");Serial.println("Available commands:");Serial.println(" normal - Normal operation (green breathing)");Serial.println(" warning - Warning state (yellow fast blink)");Serial.println(" error - Error state (red solid)");Serial.println(" network - Network activity (blue heartbeat)");Serial.println(" custom - Custom pattern");
}void loop() {// 处理串口命令handleSerialCommands();// 根据当前状态执行对应的LED模式switch(currentState) {case STATE_NORMAL:normalMode();break;case STATE_WARNING:warningMode();break;case STATE_ERROR:errorMode();break;case STATE_NETWORK:networkMode();break;case STATE_CUSTOM:customMode();break;}
}void handleSerialCommands() {if (Serial.available()) {String command = Serial.readStringUntil('\n');command.trim();if (command == "normal") {currentState = STATE_NORMAL;Serial.println("Switched to NORMAL mode");}else if (command == "warning") {currentState = STATE_WARNING;Serial.println("Switched to WARNING mode");}else if (command == "error") {currentState = STATE_ERROR;Serial.println("Switched to ERROR mode");}else if (command == "network") {currentState = STATE_NETWORK;Serial.println("Switched to NETWORK mode");}else if (command == "custom") {currentState = STATE_CUSTOM;Serial.println("Switched to CUSTOM mode");}}
}void normalMode() {// 绿色呼吸灯效果for(int brightness = 0; brightness <= 255; brightness++) {setColor(0, brightness, 0);delay(5);checkSerial(); // 非阻塞检查串口}for(int brightness = 255; brightness >= 0; brightness--) {setColor(0, brightness, 0);delay(5);checkSerial(); // 非阻塞检查串口}
}void warningMode() {// 黄色快速闪烁(红+绿)setColor(255, 255, 0); // 黄色delay(200);setColor(0, 0, 0); // 熄灭delay(200);
}void errorMode() {// 红色常亮setColor(255, 0, 0);
}void networkMode() {// 蓝色心跳效果setColor(0, 0, 255); // 亮delay(150);setColor(0, 0, 64); // 暗delay(150);setColor(0, 0, 255); // 亮delay(150);setColor(0, 0, 0); // 灭delay(600);
}void customMode() {// 自定义模式:彩虹渐变rainbowEffect();
}void setColor(int red, int green, int blue) {analogWrite(RED_PIN, red);analogWrite(GREEN_PIN, green);analogWrite(BLUE_PIN, blue);
}void rainbowEffect() {// 红->绿for(int i = 0; i <= 255; i++) {setColor(255 - i, i, 0);delay(10);checkSerial();}// 绿->蓝for(int i = 0; i <= 255; i++) {setColor(0, 255 - i, i);delay(10);checkSerial();}// 蓝->红for(int i = 0; i <= 255; i++) {setColor(i, 0, 255 - i);delay(10);checkSerial();}
}void checkSerial() {if (Serial.available()) {String command = Serial.readString();command.trim();if (command == "normal" || command == "warning" || command == "error" || command == "network") {// 切换模式时跳出当前循环return;}}
}
9. 电路连接示例
9.1 单LED连接
电路连接:
Arduino UNO LED
─────── ──────
GND ────────────┤ ├─── 负极(短脚)
D13 ──────220Ω──┤ ├─── 正极(长脚)注意:
1. LED长脚为正极,短脚为负极
2. 必须串联220Ω电阻限流
3. 电阻可以连接在正极或负极一侧
9.2 RGB LED连接
共阳RGB LED连接:
Arduino UNO RGB LED
─────── ──────
5V ──────────── 公共阳极(长脚)
GND ──────220Ω── R(红色)
D9 ──────220Ω── G(绿色)
D10 ──────220Ω── B(蓝色)共阴RGB LED连接:
Arduino UNO RGB LED
─────── ──────
GND ──────────── 公共阴极(长脚)
D9 ──────220Ω── R(红色)
D10 ──────220Ω── G(绿色)
D11 ──────220Ω── B(蓝色)注意:
1. 确认LED是共阳还是共阴
2. 每路都必须串联限流电阻
3. PWM引脚控制亮度
10. 常见问题与调试
10.1 LED不亮的检查步骤
// 调试代码:测试LED和引脚
const int TEST_PIN = 13;void setup() {Serial.begin(9600);pinMode(TEST_PIN, OUTPUT);Serial.println("LED Test Program");Serial.println("Testing pin " + String(TEST_PIN));
}void loop() {// 测试1:直接控制Serial.println("Test 1: Direct control");digitalWrite(TEST_PIN, HIGH);Serial.println("LED should be ON");delay(2000);digitalWrite(TEST_PIN, LOW);Serial.println("LED should be OFF");delay(2000);// 测试2:快速闪烁Serial.println("Test 2: Fast blink");for(int i = 0; i < 10; i++) {digitalWrite(TEST_PIN, HIGH);delay(100);digitalWrite(TEST_PIN, LOW);delay(100);}// 测试3:模拟呼吸效果Serial.println("Test 3: Breathing effect (PWM)");for(int i = 0; i <= 255; i++) {analogWrite(TEST_PIN, i);delay(10);}for(int i = 255; i >= 0; i--) {analogWrite(TEST_PIN, i);delay(10);}delay(2000);
}
10.2 故障排除清单
问题1:LED完全不亮
✅ 检查USB线是否连接
✅ 检查开发板电源灯是否亮
✅ 检查LED正负极是否接反
✅ 检查电阻是否连接正确
✅ 检查代码中引脚号是否正确
✅ 检查是否有其他程序占用引脚问题2:LED常亮不闪烁
✅ 检查代码中是否有delay()
✅ 检查loop()函数逻辑
✅ 检查是否有其他设备干扰
✅ 检查电源是否稳定问题3:闪烁频率不对
✅ 检查delay()参数单位(毫秒)
✅ 检查是否有其他代码影响时序
✅ 检查主频设置是否正确问题4:PWM效果不明显
✅ 检查引脚是否支持PWM(带~符号)
✅ 检查PWM值范围(0-255)
✅ 检查LED类型(有些LED需要更高电压)
总结
学习路径建议:
- 初学者:从最简单的Blink开始,理解setup()和loop()
- 进阶学习:尝试修改delay时间,创建不同的闪烁模式
- 中级项目:加入按钮控制、传感器交互
- 高级应用:使用中断、PWM、多任务处理
- 实际应用:将Blink用作状态指示、警报信号等
最佳实践:
- 始终使用合适的限流电阻保护LED
- 添加串口输出用于调试
- 使用常量定义引脚号,便于修改
- 考虑使用非阻塞代码提高响应性
- 为不同的功能创建独立的函数
Blink程序虽然简单,但包含了Arduino编程的所有核心概念,是学习嵌入式系统的最佳起点!