4. 按键控制LED开关

任务说明

本案例使用Arduino开发板、一个轻触按键和一个LED,实现按键控制LED亮灭的功能。按下按键时LED点亮,再次按下时LED熄灭,每次按键切换一次LED状态。通过该任务掌握digitalRead()读取数字输入、digitalWrite()控制数字输出,以及按键消抖和状态切换的基本方法。

硬件连接

  • LED正极(长脚)→ Arduino数字引脚D9(通过220Ω限流电阻)
  • LED负极(短脚)→ GND
  • 按键一端 → Arduino数字引脚D2
  • 按键同一侧另一端 → GND
  • 按键另一侧一端 → 5V(通过10kΩ上拉电阻)
电路说明:按键采用上拉电阻接法,未按下时D2读到HIGH,按下时D2读到LOW。LED阳极经限流电阻接D9,阴极接地。

完整代码

const int buttonPin = 2;   // 按键连接到D2
const int ledPin = 9;      // LED连接到D9

int ledState = LOW;        // LED当前状态
int buttonState = 0;       // 当前读取到的按键状态
int lastButtonState = HIGH; // 上一次按键状态(上拉,默认HIGH)
unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // 消抖时间50ms

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP); // 启用内部上拉,无需外部上拉电阻
  digitalWrite(ledPin, ledState);
}

void loop() {
  int reading = digitalRead(buttonPin);

  // 按键状态变化时记录时间
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  // 若状态稳定超过消抖时间,则确认按键状态
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // 仅在按键按下(LOW)且之前状态为HIGH时切换LED
    if (reading == LOW && buttonState == HIGH) {
      ledState = !ledState;
      digitalWrite(ledPin, ledState);
    }
    buttonState = reading;
  }

  lastButtonState = reading;
}

代码说明

代码使用INPUT_PULLUP启用Arduino内部上拉电阻,因此无需外接上拉电阻。核心逻辑在loop()中:每次读取D2引脚状态,当检测到电平变化时记录时间戳;若状态稳定超过50ms(消抖),则确认按键状态。只有当检测到按键从释放变为按下(即从HIGH变为LOW)时,才翻转LED状态并写入D9引脚。这种边沿检测方式确保每次按下只切换一次,长按不会重复触发。

验证方法

  1. 按上述连接搭建电路,将代码上传至Arduino开发板。
  2. 观察LED初始状态为熄灭。
  3. 按下按键并松开,LED应点亮;再次按下并松开,LED应熄灭。
  4. 快速连续按动按键,每次按下LED状态都应切换一次,且不会出现闪烁或一次按下多次切换的现象。
  5. 若LED状态与按键动作不一致,检查接线是否正确、D2和D9引脚是否与代码一致。

判定标准

满足以下条件即判定案例通过:每次按下并松开按键,LED亮灭状态恰好切换一次;按键抖动不会导致LED状态误切换;松开按键期间LED状态保持不变。

Arduino UNO D2 D9 GND 轻触按键 A1 A2 B1 B2 LED + - 220Ω D2 → 按键A1 内部上拉至5V 按键A2 → GND D9 → 220Ω → LED+ LED- → GND 信号线 GND 上拉路径 LED控制线

状态切换逻辑

程序维护两个关键状态变量:ledState记录当前LED的亮灭状态,buttonState记录确认后的按键状态。每次检测到按键从释放变为按下(下降沿),就执行ledState = !ledState翻转LED状态。消抖机制通过比较当前读取值与上次稳定值的时间差实现,只有超过50ms的稳定电平才被确认为有效按键动作,从而避免机械抖动造成的误触发。