How can I get the servo back immediately!

Hi everybody, could anyone help me on this? After having spent much time online, I’m about to give up.
here is my code.Really basic. I think it’s easy to understand without explanations:

#include <Servo.h>

Servo myservoR;

Servo myservoL;

int ledPinV = 13;

int ledPinR = 12;

int inputPin = 2;

void setup() {

myservoR.attach(5);

myservoL.attach(6);

pinMode(ledPinV, OUTPUT);

pinMode(ledPinR, OUTPUT);

pinMode(inputPin, INPUT); }

void loop() { int val = digitalRead(inputPin);

if (val == HIGH)

{ digitalWrite(ledPinV,LOW);

myservoR.writeMicroseconds(900); //trigger le right servo

myservoL.writeMicroseconds(1000); // trigger the left servo

//Now i want the two servos to move back to (1500) immediately, without delay, because I use them to trigger cameras, and once the picture is made , it’s a mess if they don’t stop pressing the shutter button! Anyhow it doesn’t work. wherever I put the two green code-lines below (1)&(2), even with “delay()” statements

digitalWrite(ledPinR, HIGH); // turns the RedLED on

delay(100); // wait for a 10/second

digitalWrite(ledPinR, LOW); // turn the RedLED off

delay(100);

myservoR.writeMicroseconds(1500); // (1)back to central position

myservoL.writeMicroseconds(1500); //(2)

}

else

{digitalWrite(ledPinV, HIGH);

digitalWrite(ledPinR, LOW);

}

}

The point is what I have written as comment. Should i rewrite all the code? I think it doesn’t work because it’s still inside the loop, but I’m rather as newbie with the Arduino code. I’ve certainly overseen something.

Thanks a lot for any help :frowning:

if you are triggering camera buttons by slow servos, you wont get around the trigger duratation/timing problem.

The way I see to add to this and make it work better is to gear the servos to make the response faster.

Just lengthening the servo horn (arm) and using a contact point driven from a point on the arm farther from the servos pivot point would increase the speed of presses and releases, at the cost of some torque. I dont think button pressing would use much torque qnyway, so thats something you have lots of excess that you can exchange for rate.

Another better trigger mechanism would involve electronically triggering the buttons via whatever circuit the button closes or opens. That would involve minor surgery of the camera, but not much except to add a small audio style jack for plugging in the external trigger wire to your Arduino’s output or relay.

You should probably only enter the servo code once everytime the input pin is triggered.

Something like this might work:

int laststate = LOW;  /* remember last input value */

void loop() { 
  int val = digitalRead(inputPin);

  if ((val == HIGH)&&(laststate ==LOW)) /* Only trigger servos on LOW -> HIGH transition */
  { 
. /* Servo handling code here */
.
  }
  laststate = val;  /* remember last input value */
} /* end of loop */

From the description I am led to believe the shutter triggers (does it ?) and the problem is that you get too many pictures before the servo returns to an “off” position. Is that a correct description of the problem ?

Servo’s have a response time, usually listed at a time to move 60 deg. What’s that time for your servos ? Can you provide us with a model # or link to the servo description/tech data ? The time also depends (somewhat) on the voltage used to power the servos. What is this voltage and where does it come from. Servo’s can draw a fair amount of current and perhaps your problem is the servo is stalling when asked to reverse direction.

Lastly if you want responsive movement you should limit the motion needed. The shutter tripped position commanded should be just enough to trip the shutter. The shutter commanded “off” position should be just off. Can you give us a description (or picture) of the mechanics of the servo & shutter ?

Your code should work pretty much as is, though I’d make some changes. Do you want to be able to take just one exposure at a time or do you want control just as if you had your finger on the shutter release ? That is to also be able to take a series of exposures, back to back, for as long as the inputPin is held ? For just a one shot exposure you’ll want to go from the “off” position to the “trigger” position, perhaps pause a bit, and then back to the “off” position. Then you’ll want a longer pause before looping again to allow you time to get the inputPin back to a “not triggered” state.

ps - don’t the camera(s) used have an electronic shutter trigger ?

Hey, thx a lot mlu, it works!!!

GREAT!!!

I thought it was something like that, set a boolean a operator, but was still unclear I would certainly have spent a lot of time to get this result!!!

I only had to modify your first declaration: “int laststate;” instead of “int laststate = LOW;” which of course was incompatible with your last statement "laststate = val; "

Thx every body. I’m going to answer to each one who tried to help!:slight_smile:

My modified code:

 #include <Servo.h> 
  Servo myservoR; 
  Servo myservoL; 
 
  int ledPinV = 13; 
  int ledPinR = 12;
  int inputPin = 2;                            
  int laststate ;
  void setup()   {
                  myservoR.attach(5); 
                  myservoL.attach(6);
                
                  pinMode(ledPinV, OUTPUT);    
                  pinMode(ledPinR, OUTPUT);            
                  pinMode(inputPin, INPUT); }          
               
           
  void loop()  { int val = digitalRead(inputPin); 

    if ((val == HIGH)&&(laststate ==LOW))
          
 
               { digitalWrite(ledPinV,LOW); 
                    myservoR.writeMicroseconds(900); 
                    myservoL.writeMicroseconds(1000);
                    
    

       digitalWrite(ledPinR, HIGH);                
       delay(100);                                 
       digitalWrite(ledPinR, LOW);                
       delay(100); 
     
   }
      
     { myservoR.writeMicroseconds(1500);  
       myservoL.writeMicroseconds(1500); }
 
   
    
                
    {digitalWrite(ledPinV, HIGH); 
       digitalWrite(ledPinR, LOW);
     }
           laststate = val;             
  }

Actually the modification has an unespected but logical effect: the red Led which is supposed to flash as long as the input is HIGH,to indicate that I have to wait the green light to trigger again, only flashes briefly without coordination with the input. I’m going to think about the way to get that right, but it’s more decorative than useful. More important for me is to center the servos back.

Hi, if found a solution for the red led. Instead of connecting it to pin 13, I connect it in parallel to inputpin 2 so that it indicates the state of the ingoing signal. It doesn’t flashes, but that’s not an issue.

My circuit:

Now the new code:

 #include <Servo.h> 
  Servo myservoR; 
  Servo myservoL; 
 
  int ledPinV = 13; 
 int ledPinR = 12;
  int inputPin = 2;                            
  int laststate ;
  void setup()   {
                  myservoR.attach(5); 
                  myservoL.attach(6);
                
                  pinMode(ledPinV, OUTPUT);    
                 //pinMode(ledPinR, OUTPUT);            
              pinMode(inputPin, INPUT); }          
               
           
  void loop()  { int val = digitalRead(inputPin); 

   if ((val == HIGH)&&(laststate ==LOW)) // important condition to get the servo back immediately. Thx to mlu from Gothenburg, Sweden at Spakfun's! :-)
          
 
               { digitalWrite(ledPinV,LOW); 
                    myservoR.writeMicroseconds(900); 
                    myservoL.writeMicroseconds(1000);
                                       delay(200); } // very important here to give the green led time to get  HIGH
      
               { myservoR.writeMicroseconds(1500);  
                 myservoL.writeMicroseconds(1500); }
 

    
   if (val == LOW)            
    {digitalWrite(ledPinV, HIGH); 
       
     }
           laststate = val;             
  }