首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何使伺服电机在接收到来自传感器的信号后暂停一段时间?

如何使伺服电机在接收到来自传感器的信号后暂停一段时间?
EN

Stack Overflow用户
提问于 2021-10-25 10:46:01
回答 1查看 139关注 0票数 0

我正在做一个简单的基于Arduino Uno的项目,叫做“垃圾分离系统”。为此,我使用了3个不同的传感器(红外,感应接近和雨滴)和3个微型伺服电机。基本上,它所做的是,不同的伺服电机旋转根据它从移动的传送带(如非金属,湿或金属)检测到的对象的类型。所以,一切都很好,但我面临的唯一问题是,在传感器检测到任何物体后,我不能在较新的位置保持伺服电机一段时间。当物体不再位于传感器前面时,它会返回到初始位置。

我尝试在代码的不同部分使用delay()函数,但它不能正常工作。例如,如果我使用延迟(3000);伺服也会在检测到不希望的对象后3秒后移动。

如果你能以某种方式帮助我,我将不胜感激。提前感谢:)

我使用的代码;

代码语言:javascript
复制
#include <Servo.h>
Servo tap_servo_1;
Servo tap_servo_2;
Servo tap_servo_3;  

// here No. 1 is for Inductive sensor, No.2 is for Raindrop sensor and No.3 is for IR sensor //  

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;


void setup()
{
 pinMode(sensor_pin_1,INPUT);
 tap_servo_1.attach(tap_servo_pin_1);
 
 pinMode(sensor_pin_2,INPUT);
 tap_servo_2.attach(tap_servo_pin_2);
 
 pinMode(sensor_pin_3,INPUT);
 tap_servo_3.attach(tap_servo_pin_3);
}

void loop()
{
  val_1 = digitalRead(sensor_pin_1);
  
  if(val_1==0)
  {tap_servo_1.write(10);
  }
  if (val_1==1)
  {tap_servo_1.write(70);
  Serial.println("Waste detected is: Non-Metal");
   
  }

  
  val_2 = digitalRead(sensor_pin_2);
  
  if(val_2==0)
  {tap_servo_2.write(0);
  }
 if (val_2==1)
 {tap_servo_2.write(75);
 Serial.println("Waste detected is: Wet");
 }

 
 val_3 = digitalRead(sensor_pin_3);
  
 if (val_3==0)
  {tap_servo_3.write(10);
 }
 if (val_3==1)
  {tap_servo_3.write(70);
  Serial.println("Waste detected is: Metal");
  
  }
 }   
EN

回答 1

Stack Overflow用户

发布于 2021-10-25 11:45:17

根据我的评论,那么:

相反,您希望在不再检测到对象后的一段时间内,伺服保持在位置70。

您需要在识别对象后忽略传感器值的东西。目前,每一次循环迭代(比系统的机制都要快得多)都会检查传感器的值,这样你就会看到伺服系统很快就回到了初始位置。让我们添加一个不稳定周期,比方说3秒。在此期间,您不希望检查val_x传感器。

sleep的问题是它是一个阻塞函数,整个程序都会挂起。相反,您希望在检测到对象后“冻结”时间,并在确定的时间量过去后再次检查。

代码语言:javascript
复制
// Store time here - init at zero 
unsigned long non_metal_detect_time = 0;
unsigned long       wet_detect_time = 0;
unsigned long     metal_detect_time = 0;

unsigned long ms_from_detection_non_metal;
unsigned long ms_from_detection_metal;
unsigned long ms_from_detection_wet;

    void loop()
    {
      val_1 = digitalRead(sensor_pin_1);
      
      ms_from_detection_non_metal = millis() - non_metal_detect_time ;

      // we care about this value only if 3s have passed otherwise we
      // ignore the value from the sensor even if the object is not there
      if(val_1==0 && ms_from_detection_non_metal > 3000  )
      {
        tap_servo_1.write(10);
      }
      

      if (val_1==1)
      { 
        // save when it's detected
        non_metal_detect_time = millis();
        tap_servo_1.write(70);
        Serial.println("Waste detected is: Non-Metal");
       
      }
    
      // You can do the same modifications for the other sensors.      

     }   

另一种想法是需要更复杂的软件,但它也可以更好地利用硬件资源。我会给你这个想法。

您可以从带边沿检测的GPIO触发多个中断:

  • 0 -> 1:检测到对象。ISR向伺服系统发出命令。停止计时器。
  • 1 -> 0:对象已消失。ISR启动计时器。

然后是定时器。

  • 计时器溢出:对象消失后已过时间。向伺服器发出返回初始状态的命令。
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69706670

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档