//引脚信息定义
int buttonPin = 2; //按钮连接的引脚
const int ledCount = 3; //LED灯的数量
int ledPins[ledCount] = {5,6,9}; //LED灯连接的引脚集合
int pilotPin = 3; //模式指示灯的引脚
//模式信息定义
int modeTotal = 7; //模式的数量
int currentMode = 0; //当前模式的索引
// 按钮状态变量
volatile unsigned long pressStartTime = 0; // 记录按钮按下的时间
volatile bool buttonHandled = true; // 按钮标记,true表示无待处理操作,即按钮未触发
void setup() {
//初始化引脚
for(int i = 0;i < ledCount;i++) pinMode(ledPins[i],OUTPUT);
pinMode(pilotPin, OUTPUT);
pinMode(buttonPin,INPUT_PULLUP); // 启用引脚内部上拉电阻,避免引脚悬空,保证引脚状态稳定
//内部上拉电阻效果(对buttonPin):按钮松开时为HIGH,按下时为LOW
// 设置中断:指定中断引脚为buttonPin,中断触发时调用的函数buttonISR,下降沿触发
attachInterrupt(digitalPinToInterrupt(buttonPin), buttonISR, FALLING);
}
void loop() {
// 处理按钮动作
if(!buttonHandled && digitalRead(buttonPin) == HIGH) { // 检测释放动作
unsigned long duration = millis() - pressStartTime; // 计算按压持续时间
if(duration > 50) { // 防止轻微抖动
currentMode = (currentMode+1)%modeTotal;
}
allOff();
pilotFlicker(currentMode);
buttonHandled = true; // 按钮标记已处理
}
// 执行模式
switch(currentMode) {
case 0: M1(); break;
case 1: M2(); break;
case 2: M3(); break;
case 3: M4(); break;
case 4: M5(); break;
case 5: M6(); break;
case 6: M7(); break;
}
}
//指示灯闪烁函数
void pilotFlicker(int n){
for(int i=0;i<n+1;i++){ //模式i就闪烁i下
digitalWrite(pilotPin, HIGH);
delay(500);
digitalWrite(pilotPin, LOW);
delay(500);
}
}
//ISR
void buttonISR() {
if(buttonHandled) { // 仅当标志位为true时记录时间,避免重复响应抖动信号
pressStartTime = millis(); // 记录按下时刻的时间戳
buttonHandled = false; // 标记需要处理,即按钮触发
}
}
//模式1:单向流水灯1
void M1(){
for(int i=0;i<ledCount;i++){
digitalWrite(ledPins[i],HIGH);
delay(1000);
digitalWrite(ledPins[i],LOW);
}
}
//模式2:单向流水灯2
void M2(){
for(int i=ledCount-1;i>=0;i--){
digitalWrite(ledPins[i],HIGH);
delay(1000);
digitalWrite(ledPins[i],LOW);
}
}
//模式3:警报灯
void M3(){
allOn(); //全开
delay(300);
allOff(); //全关
delay(300);
}
//模式4:随机闪烁
void M4(){
static int lastLED = 0; //利用静态变量记录上一个led灯
int newLED = random(ledCount); //随机挑选下一个led灯
digitalWrite(ledPins[lastLED],LOW);//关闭旧灯
digitalWrite(ledPins[newLED],HIGH);//打开新灯
lastLED = newLED;
delay(random(50,200)); //停顿时间随机
}
//模式5:呼吸灯
void M5(){
static int brightness = 0; //需要循环函数达到呼吸效果,因此使用静态变量
static bool rising = true;
for(int i=0;i<ledCount;i++){ //从左到右
analogWrite(ledPins[i],brightness);
}
if(rising){
if(++brightness >= 255) rising = false; //逐渐变亮
}else{
if(--brightness <= 0) rising = true; //逐渐变暗
}
delay(10);
}
//模式6:单灯闪烁x3
void M6(){
for(int i=0;i<ledCount;i++){
for(int j=0;j<3;j++){ //闪烁x3
digitalWrite(ledPins[i],HIGH);
delay(300);
digitalWrite(ledPins[i],LOW);
delay(300);
}
}
}
//模式7:瀑布灯
void M7(){
allOn();
delay(1000);
for(int i=0;i<ledCount;i++){
digitalWrite(ledPins[i], LOW);
delay(1000);
}
}
//关闭所有灯
void allOff(){
for(int i=0;i<ledCount;i++){
digitalWrite(ledPins[i],LOW);
}
}
//打开所有灯
void allOn(){
for(int i=0;i<ledCount;i++){
digitalWrite(ledPins[i],HIGH);
}
}