Arduino Uno垃圾分类项目中传感器触发后如何让舵机保持位置一段时间
Arduino垃圾分类系统舵机保持位置解决方案
核心问题原因
你当前的代码逻辑是每轮loop()循环都会实时读取传感器状态,一旦传感器检测不到物体,就会立刻执行舵机复位逻辑。而delay()是阻塞函数,调用期间整个程序都会暂停运行,所以会出现舵机延迟动作的问题,不符合你的需求。
解决思路
使用Arduino内置的millis()函数实现非阻塞计时,不需要暂停整个程序,就能实现舵机触发后保持指定时间再复位的效果,三个舵机的计时逻辑相互独立,互不影响。
修改后完整代码
#include <Servo.h> Servo tap_servo_1; Servo tap_servo_2; Servo tap_servo_3; // 1对应电感式传感器,2对应雨滴传感器,3对应红外传感器 int sensor_pin_1 = 4; int tap_servo_pin_1 =5; int sensor_pin_2 =2; int tap_servo_pin_2 =3; int sensor_pin_3 =8; int tap_servo_pin_3 =9; int val_1; int val_2; int val_3; // 新增配置:舵机触发后保持的时间(单位毫秒,3000即3秒,可自行调整) const unsigned long HOLD_TIME = 3000; // 每个舵机的触发标记和触发时间戳 bool servo1_triggered = false; unsigned long servo1_start_time = 0; bool servo2_triggered = false; unsigned long servo2_start_time = 0; bool servo3_triggered = false; unsigned long servo3_start_time = 0; void setup() { pinMode(sensor_pin_1,INPUT); tap_servo_1.attach(tap_servo_pin_1); // 初始化舵机到初始位 tap_servo_1.write(10); pinMode(sensor_pin_2,INPUT); tap_servo_2.attach(tap_servo_pin_2); tap_servo_2.write(0); pinMode(sensor_pin_3,INPUT); tap_servo_3.attach(tap_servo_pin_3); tap_servo_3.write(10); Serial.begin(9600); } void loop() { unsigned long current_time = millis(); // 舵机1(电感式传感器/非金属垃圾)逻辑 val_1 = digitalRead(sensor_pin_1); if(val_1 == 1) { tap_servo_1.write(70); if(!servo1_triggered){ Serial.println("Waste detected is: Non-Metal"); servo1_triggered = true; servo1_start_time = current_time; } }else{ if(servo1_triggered && (current_time - servo1_start_time >= HOLD_TIME)){ tap_servo_1.write(10); servo1_triggered = false; } } // 舵机2(雨滴传感器/湿垃圾)逻辑 val_2 = digitalRead(sensor_pin_2); if(val_2 == 1) { tap_servo_2.write(75); if(!servo2_triggered){ Serial.println("Waste detected is: Wet"); servo2_triggered = true; servo2_start_time = current_time; } }else{ if(servo2_triggered && (current_time - servo2_start_time >= HOLD_TIME)){ tap_servo_2.write(0); servo2_triggered = false; } } // 舵机3(红外传感器/金属垃圾)逻辑 val_3 = digitalRead(sensor_pin_3); if(val_3 == 1) { tap_servo_3.write(70); if(!servo3_triggered){ Serial.println("Waste detected is: Metal"); servo3_triggered = true; servo3_start_time = current_time; } }else{ if(servo3_triggered && (current_time - servo3_start_time >= HOLD_TIME)){ tap_servo_3.write(10); servo3_triggered = false; } } }
关键调整说明
- 新增了每个舵机独立的触发标记和时间戳变量,避免多个舵机工作互相干扰
- 传感器检测到物体时,舵机立刻转动到工作位置,同时记录当前时间,不会有延迟
- 物体离开传感器检测范围后,不会立刻复位舵机,等到累计保持时间达到你设定的
HOLD_TIME后再执行复位操作 - 全程使用非阻塞计时,整个程序不会出现卡顿,三个传感器可以同时正常检测不同的垃圾
- 你可以根据传送带的速度调整
HOLD_TIME的数值,适配实际的分类动作时间需求
内容的提问来源于stack exchange,提问作者Falgun Patel
相关产品推荐
相关产品推荐

