Arduino烟雾探测器:实现蜂鸣器持续报警至外部中断的技术问询
解决烟雾探测器蜂鸣器持续报警及外部中断停止的问题
嘿,我来帮你搞定这个烟雾探测器的蜂鸣器需求!针对你的两个问题,我给你详细解答和修改后的代码:
问题1:能否直接移除tone()函数的定时参数?
完全可以!Arduino的tone()函数如果省略第三个参数(持续时间),它会一直持续播放指定音调,直到你主动调用noTone()函数来停止。这正是你需要的持续鸣响效果。
问题2:如何实现蜂鸣器持续鸣响直至外部中断触发?
要做到这一点,我们需要添加一个外部中断触发源(比如一个按钮),当触发中断时停止蜂鸣器并重置报警状态。下面是修改后的完整代码,我会标注关键修改点:
// 定义引脚 #define SMOKE_SENSOR_PIN 0 #define GREEN_LED 8 #define RED_LED 7 #define BUZZER_PIN 9 #define INTERRUPT_PIN 2 // 用引脚2作为外部中断触发(Uno的2、3引脚支持外部中断) bool isAlarming = false; // 标记当前是否处于报警状态 void setup() { Serial.begin(9600); pinMode(SMOKE_SENSOR_PIN, INPUT); pinMode(GREEN_LED, OUTPUT); pinMode(RED_LED, OUTPUT); pinMode(BUZZER_PIN, OUTPUT); pinMode(INTERRUPT_PIN, INPUT_PULLUP); // 使用内部上拉电阻,按钮接GND // 绑定中断:当引脚2检测到电平下降沿(按钮按下)时,调用stopAlarm函数 attachInterrupt(digitalPinToInterrupt(INTERRUPT_PIN), stopAlarm, FALLING); digitalWrite(GREEN_LED, HIGH); // 初始状态绿灯亮 } // 中断服务函数:停止报警 void stopAlarm() { noTone(BUZZER_PIN); // 停止蜂鸣器 isAlarming = false; digitalWrite(RED_LED, LOW); digitalWrite(GREEN_LED, HIGH); } void loop() { int sensorValue = analogRead(SMOKE_SENSOR_PIN); int digitalValue = digitalRead(SMOKE_SENSOR_PIN); Serial.print("模拟值: "); Serial.println(sensorValue); Serial.print("数字值: "); Serial.println(digitalValue); delay(2000); // 检测到烟雾且未处于报警状态时,启动报警 if (sensorValue < 100 && !isAlarming) { tone(BUZZER_PIN, 200); // 移除定时参数,持续鸣响 isAlarming = true; digitalWrite(RED_LED, HIGH); digitalWrite(GREEN_LED, LOW); } // 未检测到烟雾但处于报警状态时,恢复正常状态 else if (sensorValue >= 100 && isAlarming) { stopAlarm(); // 调用停止报警函数 } }
关键修改说明:
- 全局变量
isAlarming:用来跟踪当前是否在报警状态,避免重复触发tone()函数,也能在中断时重置状态。 - 外部中断配置:使用
INPUT_PULLUP让中断引脚默认处于高电平,当按钮按下(接GND)时触发下降沿中断,调用stopAlarm()停止报警。如果想用重启引脚触发,只需要把中断引脚换成重启对应的引脚,调整触发逻辑即可。 tone()的使用:移除了第三个定时参数,让蜂鸣器持续鸣响,直到noTone()被调用。- 状态同步:报警时红灯亮绿灯灭,正常状态则相反,中断触发后立即恢复正常状态。
硬件连接提示:
- 把一个按钮的一端接引脚2,另一端接GND(不需要额外上拉电阻,代码里用了内部上拉)。
- 蜂鸣器的正极接引脚9,负极接GND(有源蜂鸣器直接接即可;无源蜂鸣器建议串联一个1kΩ左右的限流电阻)。
这样就能实现你要的效果:检测到烟雾时蜂鸣器持续响,直到触发外部中断(比如按下按钮)才停止。
内容的提问来源于stack exchange,提问作者M.E. Team
相关产品推荐
相关产品推荐

