简体   繁体   English

伺服电机收到任何传感器的信号后如何停止一段时间?

[英]How to halt a servo motor for some time after it receives a signal from any sensor?

I am working on a simple Arduino Uno based project called "Waste segregation system".我正在研究一个简单的基于 Arduino Uno 的项目,称为“废物分离系统”。 For that I've used 3 different sensors (IR, Inductive Proximity and Raindrop) and 3 Micro servo motors.为此,我使用了 3 个不同的传感器(IR、感应接近和雨滴)和 3 个微型伺服电机。 Basically what it does is, different servo motor rotates according to the type of object it detects from a moving conveyor (Like Non-metal, Wet or Metal).基本上它的作用是,不同的伺服电机根据它从移动传送带检测到的物体类型(如非金属、湿或金属)旋转。 So, everything works fine but the only issue I face is, I can not hold servo motor for some time at the newer position after the sensor senses any object.所以,一切正常,但我面临的唯一问题是,在传感器感应到任何物体后,我无法将伺服电机保持在较新的位置一段时间。 It returns to it's initial position after when the object is no more in front of a sensor.当物体不再位于传感器前面后,它会返回到它的初始位置。

I tried using delay() function at different parts of the code but it's not working properly.我尝试在代码的不同部分使用 delay() 函数,但它无法正常工作。 Like if I use delay(3000);就像我使用 delay(3000); the servo also moves 3 seconds later after sensing an object which is not desirable.在感应到不需要的物体后,伺服也会在 3 秒后移动。

I would be so grateful of you if you help me somehow.如果您能以某种方式帮助我,我将不胜感激。 Thanks in advance :)提前致谢 :)

The code I used;我使用的代码;


#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");
  
  }
 }   

Based on my comment, then:根据我的评论,然后:

You instead want the servo to stay at position 70 some time after the object is not detected anymore.相反,您希望伺服器在不再检测到物体后的某个时间停留在位置 70。

You need something that ignores the sensor value after an object is being identified.您需要在识别对象后忽略传感器值的东西。 At the moment every loop iteration (which is way faster than the mechanics of your system) will check the sensor value so you'll see that the servo goes back to the initial position quite instantaneously.目前,每次循环迭代(这比您的系统机制快得多)都会检查传感器值,因此您会看到伺服立即返回到初始位置。 Let's add a refractory period of say 3seconds.让我们添加一个 3 秒的不应期。 In this period you don't want to check the val_x sensor.在此期间您不想检查 val_x 传感器。

The problem with sleep is that it's a blocking function and the entire program will hang. sleep的问题在于它是一个阻塞函数,整个程序都会挂起。 You instead want to "freeze" the time after detecting an object and check again after a determined amount of time has passed.相反,您希望在检测到对象后“冻结”时间,并在经过确定的时间后再次检查。

 
// 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.      

     }   

Another idea would instead require a more sophisticated software but it will also make a better use of you hardware resources.另一个想法是需要更复杂的软件,但它也可以更好地利用您的硬件资源。 I'll give you the idea.我给你出主意。

You can trigger serveral interrupts from the GPIO with edge detection:您可以通过边沿检测从 GPIO 触发多个中断:

  • 0 -> 1: object is detected. 0 -> 1:检测到物体。 ISR gives the command to the servo. ISR 向伺服器发出命令。 Stop timer.停止计时器。
  • 1 -> 0: object has gone. 1 -> 0:对象已经消失。 ISR starts timer. ISR 启动计时器。

And then the timer.然后是计时器。

  • Timer overflow: time has passed after object was gone.定时器溢出:对象消失后时间已过。 Give command to the servo to come back to init.向伺服发出命令返回初始化。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM