You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 13:45:02