求助:基于Arduino Uno的自动洗手液dispenser水泵仅运行3秒的实现问题
Arduino自动洗手液机:触发后水泵仅运行3秒的解决方案
问题背景
基于Arduino Uno、水泵和红外传感器制作的自动洗手液机,目前触发后水泵持续运行,尝试修改代码时误将逻辑写反,导致触发后延迟3秒才启动水泵,而非运行3秒后停止。原代码如下:
//This c++ code is generated by PictoBlox void setup() { //put your setup code here, to run once: pinMode(9, OUTPUT); pinMode(2, INPUT); digitalWrite(9, false); } void loop() { //put your main code here, to run repeatedly: if(digitalRead(2)) { delay(0.5 * 1000); while(undefined); digitalWrite(9, true); } else { digitalWrite(9, false); delay(.5 * 1000); } }
原代码问题分析
while(undefined);为无效代码,会导致程序卡死- 检测到红外信号后持续输出高电平,无定时关闭逻辑
- 此前尝试的错误方案将延迟操作放在了启动水泵之前,导致触发后先等待3秒再启动水泵,完全颠倒了逻辑
修正方案(新手友好版)
以下代码实现“触发后立即启动水泵,运行3秒后自动关闭”的逻辑,同时加入冷却时间防止重复触发:
// Arduino Uno自动洗手液机代码:触发后水泵运行3秒 void setup() { pinMode(9, OUTPUT); // 水泵控制引脚设为输出 pinMode(2, INPUT); // 红外传感器引脚设为输入 digitalWrite(9, LOW); // 初始状态关闭水泵 } void loop() { // 检测红外传感器触发(默认传感器触发时输出高电平,若为低电平需改为LOW) if(digitalRead(2) == HIGH) { digitalWrite(9, HIGH); // 立即启动水泵 delay(3000); // 保持水泵运行3秒 digitalWrite(9, LOW); // 3秒后关闭水泵 delay(2000); // 冷却2秒,避免手未离开时重复触发 } else { digitalWrite(9, LOW); // 未触发时保持水泵关闭 delay(500); // 降低检测频率,节省资源 } }
逻辑说明
- 触发后先启动水泵,再延迟3秒,彻底解决之前“先延迟后启动”的错误
- 冷却时间可根据需求调整,防止短时间内重复出液
- 若你的红外传感器触发时输出低电平,将代码中
HIGH替换为LOW即可
进阶非阻塞版本(避免程序卡死)
如果需要同时处理其他功能,可使用millis()实现非阻塞计时,避免delay()导致程序无法响应其他操作:
// 非阻塞版:水泵触发后运行3秒,不影响其他程序逻辑 const int pumpPin = 9; const int sensorPin = 2; unsigned long pumpStartTime = 0; bool pumpRunning = false; const unsigned long pumpRunDuration = 3000; // 水泵运行时长(毫秒) const unsigned long cooldownDuration = 2000; // 冷却时长(毫秒) unsigned long lastTriggerTime = 0; void setup() { pinMode(pumpPin, OUTPUT); pinMode(sensorPin, INPUT); digitalWrite(pumpPin, LOW); } void loop() { unsigned long currentTime = millis(); bool isSensorTriggered = (digitalRead(sensorPin) == HIGH); // 满足触发条件:传感器触发、水泵未运行、已过冷却期 if(isSensorTriggered && !pumpRunning && (currentTime - lastTriggerTime) > cooldownDuration) { digitalWrite(pumpPin, HIGH); pumpStartTime = currentTime; pumpRunning = true; } // 检查水泵是否已运行够3秒 if(pumpRunning && (currentTime - pumpStartTime) > pumpRunDuration) { digitalWrite(pumpPin, LOW); pumpRunning = false; lastTriggerTime = currentTime; // 记录触发时间,开始冷却 } delay(100); // 轻微延迟降低检测频率 }
内容的提问来源于stack exchange,提问作者UdySnkr
相关产品推荐
相关产品推荐

