如何修正Arduino倒计时、PIR传感器与继电器程序,实现顺序工作?
问题分析与代码修改方案
原代码的核心问题是没有区分程序的不同阶段,导致倒计时和PIR检测同时运行,且初始灯光状态不符合预期。以下是针对性的修改方案:
核心修改思路
- 用状态变量划分程序阶段:倒计时阶段、运行阶段(倒计时结束后)
- 初始状态下强制关闭灯光,仅在倒计时完成后开启
- 严格控制逻辑顺序:完成10次倒计时 → 开启灯光 → 启动PIR移动检测
修改后的完整代码
#define relayPin 12 #define pirPin1 8 #define pirPin2 9 #define pirPin3 10 #define pirPin4 11 // 状态定义:区分程序的不同阶段 #define STATE_COUNTDOWN 0 #define STATE_RUNNING 1 int currentState = STATE_COUNTDOWN; int val1 = 0, val2 = 0, val3 = 0, val4 = 0; long buzzerFrequency = 1000; float buzzerDuration = 100; int startNumber = 9; // 从9到0共10次倒计时 int endNumber = 0; const int buzzerPin = 6; void setup() { pinMode(buzzerPin, OUTPUT); pinMode(relayPin, OUTPUT); pinMode(pirPin1, INPUT); pinMode(pirPin2, INPUT); pinMode(pirPin3, INPUT); pinMode(pirPin4, INPUT); Serial.begin(115200); // 初始状态关闭灯光(继电器高电平断开) digitalWrite(relayPin, HIGH); Serial.println("系统初始化,灯光关闭,开始倒计时"); } // 执行倒计时逻辑 void doCountdown() { if (startNumber >= endNumber) { tone(buzzerPin, buzzerFrequency, buzzerDuration); // 蜂鸣器响一次 Serial.print("倒计时:"); Serial.println(startNumber + 1); // 显示当前倒计时次数(10到1) delay(1000); startNumber--; } else { // 倒计时完成,开启灯光并切换到运行状态 digitalWrite(relayPin, LOW); Serial.println("倒计时结束,灯光开启,开始检测移动"); currentState = STATE_RUNNING; } } // 处理PIR移动检测逻辑 void handlePIR() { val1 = digitalRead(pirPin1); val2 = digitalRead(pirPin2); val3 = digitalRead(pirPin3); val4 = digitalRead(pirPin4); if (val1 == HIGH || val2 == HIGH || val3 == HIGH || val4 == HIGH) { // 检测到移动,关闭灯光 digitalWrite(relayPin, HIGH); Serial.println("检测到移动!灯光关闭,延迟10秒"); delay(10000); // 10秒后重新开启灯光 digitalWrite(relayPin, LOW); Serial.println("灯光重新开启"); } else { // 无移动,保持灯光开启状态 digitalWrite(relayPin, LOW); delay(100); // 降低串口输出频率,避免刷屏 } } void loop() { // 根据当前状态执行对应逻辑 if (currentState == STATE_COUNTDOWN) { doCountdown(); } else if (currentState == STATE_RUNNING) { handlePIR(); } }
关键修改说明
- 状态变量控制流程:通过
currentState变量确保只有完成倒计时后,才会进入PIR检测阶段,解决了倒计时时PIR提前工作的问题。 - 初始灯光状态修正:
setup中直接将继电器设为HIGH(关闭灯光),符合需求中“倒计时结束后才开灯”的要求。 - 倒计时逻辑优化:添加了倒计时次数的串口打印,便于调试;倒计时完成后自动切换状态并开启灯光。
- PIR检测逻辑完善:确保检测到移动后,灯光关闭10秒再重新开启,符合需求描述。
内容的提问来源于stack exchange,提问作者Prajna Paramitha
相关产品推荐
相关产品推荐

