Trigger Servos with Infrared Reflectance Sensor

Hi guys...I'm fairly new to arduino and I'm trying to develop something for my physical computing class but I'm having a lot of problems...

I'm using 2 servos to rotate 2 circular wood boards, and I want them to be trigerred by movement, detected by IR reflectance sensor...I can have the servos rotate, or the IR sensor turn on and off and led by movement, separately. When I try to merge them....It reads on the serial monitor but the servo doesn't move....any idea why?

For testing purposes this code has only one servo?

#include <Servo.h> 

Servo myservo1; 

int potpin=0;
int val;    // variable to read the value from the analog pin 
int pos = 0; //uitil here servo

int ledPin = 13;       // choose pin for the LED
int inputPin = 8;      // choose input pin (for Infrared sensor)
int value = 0;           // variable for reading the pin status

void setup() {
  pinMode(ledPin, OUTPUT);   // declare LED as output
  pinMode(inputPin, INPUT);  // declare Infrared sensor as input
  Serial.begin(9600);
  
  myservo1.attach(0);//servo  
}

void loop(){
  value = digitalRead(inputPin);  // read input value
  if (value == HIGH) {            // check if the input is HIGH
    digitalWrite(ledPin, LOW);  // turn LED OFF
    Serial.println("AAoff");
    
        for(pos = 0; pos < 180; pos += 1)  // goes from 0 degrees to 180 degrees 
        {                                  // in steps of 1 degree 
          myservo1.write(pos);
          //myservo2.write(pos);    // tell servo to go to position in variable 'pos' 
          delay(10);                       // waits 15ms for the servo to reach the position 
          Serial.println("Servooff");
        } 
    
  } else {
    digitalWrite(ledPin, HIGH); // turn LED ON
    Serial.println("AAon");
    
    
        for(pos = 180; pos>=1; pos-=1)  // goes from 0 degrees to 180 degrees 
        {                                  // in steps of 1 degree 
          myservo1.write(pos);
         // myservo2.write(pos);    // tell servo to go to position in variable 'pos' 
          delay(10);                       // waits 15ms for the servo to reach the position 
    Serial.println("Servoon");
        } 
      
  }
}

Thanks in advance for any help you can give me!

Because you're attaching the servo to one of the serial interface pins?

oh...I just connect the servo to ground and 5v ? but then how do i declare it in the code?

I'm a noob in this area :X

Your servo attach is to pin zero. Attach it to some other pin that isn't being used for some other purpose.

got it...rx or tx were bad pinds to use 8)

another question....is there any wait to stop the servo after it does each one of the for cycles?

The idea is to have the servos stopped at beginning, trigger them if the infrared sensor is trigered, they will rotate 180 degrees, they will stop there, and after some time they'll go back to the original position....I looked over the documentation but I couldn't figure it out,,,if anyone could point me in some direction i would be appreciated!

Thanks

If it heps, the idea is to build this:

so what i need is for them to be still at first....and when someone tries to reach inside the box, they will rotate, like closing a door (that's exatly the idea). Since one of them stays on the bottom and another on top, they actually have to make the exact same movement.

I just can't figure out how to control them to stop when the door is closed, open after X seconds and stay still again :sweat_smile:

The servo library you're using provides a write() method which tells the servo to go to a specific position. You will need to work out what values correspond to your 'open' and 'closed' positions by trial and error.

You will probably want to drive both servos separately for flexibility, but given that you want them to move together you could choose to wire both servos up to the same output.

Your program needs to initialise the servo and sensor pins and set the servos to the 'open' position during setup.

In the main loop you need to read your sensor, work out how much time has elapsed since it was last triggered, decide whether the servos should be in the 'open' or 'closed' positions based on the elapsed time since the last trigger, and tell the servos to go to the open or closed positions.

If you want the doors to open or close slower than the servos maximum speed then instead of just sending the servo to a position, you will need to remember where it is currently and move it a small amount in the direction you want it to go and then pause briefly before continuing.

this seems to work

#include <Servo.h> 

/* in degrees */
#define INITIAL_POSITION -180
#define END_POSITION 180
/*in milisecs */
#define DELAY 20
Servo myservo1; 
Servo myservo2; 

int potpin=0;
int val;    // variable to read the value from the analog pin 
int pos = INITIAL_POSITION; //uitil here servo

int ledPin = 13;       // choose pin for the LED
int inputPin = 8;      // choose input pin (for Infrared sensor)
int value = 0;           // variable for reading the pin status



void setup() {
 pinMode(ledPin, OUTPUT);   // declare LED as output
 pinMode(inputPin, INPUT);  // declare Infrared sensor as input
 Serial.begin(9600);
  
 myservo1.attach(5);//servo  
 myservo2.attach(10);//servo  
 myservo1.write(pos);
        myservo2.write(pos);
}

void loop(){
 value = digitalRead(inputPin);  // read input value
 if (value == HIGH)              // check if the input is HIGH
 {
  if(pos != END_POSITION)
  {
   digitalWrite(ledPin, LOW);  // turn LED OFF
   Serial.println("AAoff");
   pos++;                                  // in steps of 1 degree 
   myservo1.write(pos);
                        myservo2.write(pos);
   //myservo2.write(pos);    // tell servo to go to position in variable 'pos' 
   delay(DELAY);                       // waits 15ms for the servo to reach the position 
   Serial.println("Servooff");

  }
 } 
 else 
 {
  if(pos != INITIAL_POSITION)
  {
   digitalWrite(ledPin, LOW);  // turn LED OFF
   Serial.println("AAon");
   pos--;                                  // in steps of 1 degree 
   myservo1.write(pos);
                        myservo2.write(pos);
   //myservo2.write(pos);    // tell servo to go to position in variable 'pos' 
   delay(DELAY);                       // waits 15ms for the servo to reach the position 
   Serial.println("Servoon");

  }
   
 }
}

and i just realized one of my servos is broken --'

so i have a problem....i was using one of these infrared reflectance sensors to trigger servos by hand movement (or to trigger an led on and off as a convenience for explanation)

problem: stopped working!!!

the only sensors I have now are the QTR-1A ones and I'm not sure if they can do the same I was doing with the other one and I have no time to order new ones to Portugal....any thoughts on either it's possible or not?

Thank you so much

It doesn't look good - the spec on the pololu site says:

Optimal sensing distance: 0.125" (3 mm)

Maximum recommended sensing distance: 0.25" (6 mm)

Which I'm guessing is a little short for your purposes. Nonetheless, what values are you getting on your AnalogReads?

at the distance i need, it reads 0...you're right...I have one of these here:

Even though I find them to be finisky, they might be a much better solution no?

That looks more like a PIR.

It is indeed a PIR movement sensor....it might not be the best to detect a hand reaching inside a box (either that or my code is not ideal) but at least it does work unlike the qtr-1a :zipper_mouth_face:

Or do you think it won't work well to trigger servos?

This is what I'm trying to do, but it's not working well...the LED just stays on forever.. (meaning that it's only detecting one state of the PIR)

#include <Servo.h> 

/* in degrees */
#define INITIAL_POSITION -180
#define END_POSITION 180
/*in milisecs */
#define DELAY 1
Servo myservo1; 
Servo myservo2; 

int potpin=0;
int val;    // variable to read the value from the analog pin 
int pos = INITIAL_POSITION; //uitil here servo

int ledPin = 13;       // choose pin for the LED
int switchPin = 2;      // choose input pin (for Infrared sensor)
int value = 0;           // variable for reading the pin status

void setup() {
 pinMode(ledPin, OUTPUT);   // declare LED as output
 pinMode(switchPin, INPUT);  // declare Infrared sensor as input
 Serial.begin(9600);
  
 myservo1.attach(3);//servo  
 myservo2.attach(9);//servo  
 myservo1.write(pos);
 myservo2.write(pos);
}

void loop(){
 value = digitalRead(switchPin);  // read input value
 if (value == HIGH)              // check if the input is HIGH
 {
  if(pos != END_POSITION)
  {
   digitalWrite(ledPin, HIGH);  // turn LED OFF
   Serial.println("AAoff");
   pos++;                                  // in steps of 1 degree 
   myservo1.write(pos);
   myservo2.write(pos);
   //myservo2.write(pos);    // tell servo to go to position in variable 'pos' 
   delay(DELAY);                       // waits 15ms for the servo to reach the position 
   Serial.println("Servooff");

  }
 } 
 else 
 {
  if(pos != INITIAL_POSITION)
  {
   digitalWrite(ledPin, LOW);  // turn LED OFF
   Serial.println("AAon");
   pos--;                                  // in steps of 1 degree 
   myservo1.write(pos);
   myservo2.write(pos);
   //myservo2.write(pos);    // tell servo to go to position in variable 'pos' 
   delay(DELAY);                       // waits 15ms for the servo to reach the position 
   Serial.println("Servoon");

  }
   
 }
}

And the idea is still to trigger servos by movement...any thoughts? Thanks guys

Does it have to be a movement detector, or could you trigger based on some sort of beam across the front of the box?

it oculd be as you described peter, as long as it's something I can build with the hardware I have at the moment (the assignment is due monday).

I managed to get this working (so so), but this sensor is way too sensitive --'