Servo project help!

Ok, so I’m messing around with an Arduino Uno and a couple of radioshack servos, one standard one micro (amongst a few other things). I’m attempting to write a code where when I use a push button the micro servo rotates and then after a delay the standard servo does the same, plus a basic LED for indication.
I’m having issues writting the program, I’ve managed to get them to move, but I need to maintain the button pressed for a REALLY long time for them to go off, it was working perfectly with one servo (one quick tap and it all happened swiftly) but now the standard servo won’t stop vibrating, they go off at the same time instead of with a delay in between and they misbehave after the loop ends… any ideas?

#include <Servo.h>

Servo pinservo;  // servo pin release object
Servo mtrservo; // servo motor disengage object
               
 
 int ppos = 0;    // variable to store the pinservo position 
 int pushbutton = 2; // button on pin 2
 int LED = 3; //led on pin 3
 int mpos = 0; // variable for motor servo position
 
 
 void setup() 
{ 
  pinservo.attach(9);  // servo on pin 9
 pinMode(ppos, OUTPUT);
 pinMode(pushbutton, INPUT);
 pinMode(LED,OUTPUT);
 digitalWrite (pushbutton, LOW);
 
 mtrservo.attach(7);
 pinMode(mpos,OUTPUT);
 pinMode(pushbutton,INPUT);
 digitalWrite (pushbutton,LOW);
} 
 
 void loop() 
{ 
  
    if (digitalRead(pushbutton) == LOW)

  for(ppos = 0; ppos < 25; ppos += 25)  // degrees from 0 to 45
  for (mpos = 0; mpos < 90; mpos += 90)
  {                                 
    pinservo.write(ppos);    //servo to position in variable "pos"
    mtrservo.write(mpos);                      
  } 
  if (digitalRead(pushbutton) == HIGH) 
  
  for(ppos = 25; ppos>=25; ppos-=25)  // goes from 45 degrees to 0 degrees 
  for(mpos =90 ; mpos>=90; mpos-=90)
  {
     mtrservo.write(mpos);  //motor disengage, go to variable "mpos"
     delay(250);
     pinservo.write(ppos);              // tell servo to go to position in variable 'ppos' 
  delay(50);                             // waits 750ms for the servo to reach the position (affects LED response)
  }
  if(digitalRead(pushbutton) == HIGH){//if button is pressed turn LED on, else off
    digitalWrite(LED,LOW);
  }else{
    digitalWrite(LED,HIGH);
  }
}

And here’s my wiring… not sure if it’s this or the code…

Some comments about your code.

  if (digitalRead(pushbutton) == LOW)
    for(ppos = 0; ppos < 25; ppos += 25)  // degrees from 0 to 45
      for (mpos = 0; mpos < 90; mpos += 90)
      {                                 
        pinservo.write(ppos);    //servo to position in variable "pos"
        mtrservo.write(mpos);                      
      }

It is not immediately obvious to me what statement(s) will be executed if

  if (digitalRead(pushbutton) == LOW)

is true. The statements to be executed would be better in a block with braces round them.

What is the object of

    for(ppos = 0; ppos < 25; ppos += 25)  // degrees from 0 to 45

anyway ? What values will ppos have ? Does the servo really move from 0 to 45 degrees ?

Similarly

      for (mpos = 0; mpos < 90; mpos += 90)

and

      for(mpos =90 ; mpos>=90; mpos-=90)

How is the pushbutton wired ?
How are the servos powered ? Directly from the Arduino or externally ?

That will do for now I think.

Ok, well I’ll do my best to try and explain my logic behind it…

For the

if (digitalRead(pushbutton) == LOW)
    for(ppos = 0; ppos < 25; ppos += 25)  // degrees from 0 to 45
      for (mpos = 0; mpos < 90; mpos += 90)
      {                                 
        pinservo.write(ppos);    //servo to position in variable "pos"
        mtrservo.write(mpos);                      
      }

I just pretty much wrote this so that the servos reset to the position they were in and the variables to reset to the way they were prior to the button being pressed once it is released, I suppose there could be a simpler way to set this with a loop but my skills are limited when it comes to Arduino still and that’s what I could think of to get it done. The comments there are actually a bit off, I forgot to update them once I changed the range of motion of the servo, they do move the degrees marked by the values (whenever they don’t misbehave and start randomly sweeping)

I made this wiring schematic online, it’s pretty close to what I actually have, (assume all vertical strips on the breadboard are live and the resistors are of varying values but I wasn’t sure how to change the value on the site and I accidentally deleted the whole thing trying to change it)

for(ppos = 0; ppos < 25; ppos += 25)  // degrees from 0 to 45
      for (mpos = 0; mpos < 90; mpos += 90)
      {                                 
        pinservo.write(ppos);    //servo to position in variable "pos"
        mtrservo.write(mpos);                      
      }

The for loops should not even be there.

        pinservo.write(0);
        mtrservo.write(0);

is all it does.

What people are trying to tell you is that you do not understand how to use a FOR loop.

Look carefully at this and think about what it does. Go though all the steps one by one with a pen and a piece of paper.

for(ppos = 0; ppos < 25; ppos += 25) {

You will see that it starts with ppos = 0.
It checks to see if ppos < 25 - it is, so it goes though the loop
Then it adds 25 to ppos making it 25
Now it checks to see if ppos < 25 - it is not, so it skips the loop and goes on to the next stuff

I don’t think that’s what you think is happening.

…R

Ok, I see what you guys mean, thanks I'll fix that ASAP. I suppose somewhere along the lines undecided to make my life harder adding all that. I'm still having issues with them missbehaving and triggering at the same time instead of one after the other... I've been trying to get the mtrservo to go before the pinservo with an adjustable delay but I've only made them delay their simultaneous movement after the button press..

Powering the servos from the Arduino is a bad idea.

You need to sort out the power as Paul suggests and can you explain what you want to do in more detail ?

I'm attempting to write a code where when I use a push button the micro servo rotates and then after a delay the standard servo does the same, plus a basic LED for indication.

What should happen if you hold the button down ? What should happen if you just tap the button ? What triggers the servos to return to their starting position ? Time passing, releasing the button or something else ?

I had no idea the servos being connected to the arduino was bad, how is it that should be done? I saw a couple of servo examples in the servo library and they all seemed to connect to the arduino so I assumed it was fine…guess not.

What should happen if you hold the button down ?
What should happen if you just tap the button ?
What triggers the servos to return to their starting position ? Time passing, releasing the button or something else ?

Well when the button is tapped the servos should go off and move to the set angle (one after the other with a delay) and and then return to their original position after two seconds pass.

Honestly it does;‘t matter how they do it, the gist of it is that I’m trying to get two servos to move 45 degrees (mtrservo then pinservo) with only one button they could be toggled on/off by the button presses, it could bes et with delays or any other way… but I just can’t seem to get them to sync up :’(

The servo connection problem is nothing to do with the pins used. The servos take more current from the Arduino than is advisable so it is preferable to use an external power supply for them with a common GND to the Arduino.

This sounds like the outline of what you want to do

start of loop
  read the button pin
  if the button becomes pressed
    issue the command for move servo 1 to 45 degress
    wait for required period
    issue the command for move servo 2 to 45 degrees
  end if
  wait for 2 seconds
  issue the command for move servo 1 to the original position
  issue the command for move servo 2 to the original position
end of loop

There are many details to sort out such as how to detect that the button has become depressed rather than being currently depressed, and how to know that the servos have reached 45 degrees. (Actually that is not possible with normal servos so what can you do ?) How should you implement the waits ? Using the delay() function, or is there a better way ? (There is)

First off, thanks for the continued help and yes, that’s exactly what I am looking to do,

UKHeliBob:
The servo connection problem is nothing to do with the pins used. The servos take more current from the Arduino than is advisable so it is preferable to use an external power supply for them with a common GND to the Arduino.

This sounds like the outline of what you want to do

start of loop

read the button pin
  if the button becomes pressed
    issue the command for move servo 1 to 45 degress
    wait for required period
    issue the command for move servo 2 to 45 degrees
  end if
  wait for 2 seconds
  issue the command for move servo 1 to the original position
  issue the command for move servo 2 to the original position
end of loop



There are many details to sort out such as how to detect that the button has become depressed rather than being currently depressed, and how to know that the servos have reached 45 degrees. (Actually that is not possible with normal servos so what can you do ?) 
How should you implement the waits ? Using the delay() function, or is there a better way ? (There is)

Interesting, this is my first time working with arduino after having a very poor introduction to it and I was under the impression that the servo could be controlled by imputing an angle value. I’ll have to look into that although I’m sure that’s easy enough to understand and find.

When in comes to the button issue I don’t believe I know how to solve the issue, I just now thought I could always just make the whole system a toggle with the button, simply have the servos move with their respective wait in between and stay there until the next press, simplifying the process, maybe with something like this example I found

#include <Servo.h>
int button = 5; //button pin, connect to ground to move servo
int press = 0;
Servo servo;
boolean toggle = true;

void setup()
{
  pinMode(button, INPUT); //arduino monitor pin state
  servo.attach(7); //pin for servo control signal
  digitalWrite(5, HIGH); //enable pullups to make pin high
}

void loop()
{
  press = digitalRead(button);
  if (press == LOW)
  {
    if(toggle)
    {
      servo.write(160);
      toggle = !toggle;
    }
    else
    {
      servo.write(20);
      toggle = !toggle;
    }
  }
  delay(500);  //delay for debounce
}

The wait issue between servos however is a whole different deal, I thought it’d be easy to just use the delay() command but I have had absolutely no success with it… what other way is there to set a delay between actions other than the actual delay command? I’ve done a couple of google searches for that but it always keeps leading me back to the same thing

I was under the impression that the servo could be controlled by imputing an angle value

You can. What you can't do is tell when it has got there.

what other way is there to set a delay between actions other than the actual delay command?

Let is all intone the mantra

"Look at the blink without delay example, without delay. Ommmmm"

AWOL:

I was under the impression that the servo could be controlled by imputing an angle value

You can. What you can't do is tell when it has got there.

Ahh ok, now I get it... ok so then it looks like setting the delays between servos will be the trickiest thing to get down, couldn't you use the Servo.read() function to get the relative value of the servo's position and using that as a marker for them to proceed?

No, Servo.read just returns the last position you wrote, whether or not the servo has got there yet. There is no two way communication with the servo.

Ok, so then I suppose it would all have to be time based for the servo to get there and then the delay to kick in?

Yes, it will need to be time based using delay() or the BWD technique.

Despite BWB being better to use in the long run (see below) I suggest that you use delay() at first and get the program working. As to reaction to the button becoming pressed rather than being pressed, have a look at the StateChangeDetection example in the IDE.

BWD is better for most purposes because it uses the technique of noting a start time and then looking every now and again to see if the timing period has ended. If it has then do the next action. If not, then do something else such as reading another input, which you cannot do using delay() because the program stalls until the delay is over.

UKHeliBob:
BWD is better for most purposes because it uses the technique of noting a start time and then looking every now and again to see if the timing period has ended. If it has then do the next action. If not, then do something else such as reading another input, which you cannot do using delay() because the program stalls until the delay is over.

Ok, I’ll look into BWD and see how to use it, right now I simplified the code after realizing my loops were kind of off… this is pretty much what it looks like now

#include <Servo.h>

Servo pinservo;  // servo pin release object
Servo mtrservo; // servo motor disengage object
               
  
 int pushbutton = 2; // button on pin 2
 int LED = 3; //led on pin 3 
 
 
 void setup() 
{ 
  pinservo.attach(9);  // servo on pin 9
 pinMode(pushbutton, INPUT);
 pinMode(LED,OUTPUT);
 digitalWrite (pushbutton, LOW);
 
 mtrservo.attach(7);
 pinMode(pushbutton,INPUT);
 digitalWrite (pushbutton,LOW);
} 
 
 void loop() 
{ 
  
  if (digitalRead(pushbutton) == LOW)
{
  digitalWrite(LED,HIGH);
 pinservo.write(0);// both servos go back to their initial position on button release
 mtrservo.write(0);
}
  if (digitalRead(pushbutton) == HIGH)
  {
  digitalWrite(LED,LOW);
 mtrservo.write(45);
 delay(1000);
 pinservo.write(10);
  }
}

I’m playing around with the way the button is set up since I still need to hold it down for a really long time before the servos trigger, but other than that it looks a lot cleaner and it seem to be working properly so far. I’ll look into BWD and see if I’m able to implement it for the servo delays, right now I’m trying playing with the delay until I’m able to sort the button problem out.

I wrote a more extensive demo of the blink without delay technique in this thread. It includes reading a switch.

...R

I’m playing around with the way the button is set up since I still need to hold it down for a really long time before the servos trigger,

You might want to try a setup like below where the button pin is set high and the button pulls the button pin low.

//zoomkat servo button test 7-30-2011

#include <Servo.h>
int button1 = 4; //button pin, connect to ground to move servo
int press1 = 0;
Servo servo1;

void setup()
{
  pinMode(button1, INPUT);
  servo1.attach(7);
  digitalWrite(4, HIGH); //enable pullups to make pin high
}

void loop()
{
  press1 = digitalRead(button1);
  if (press1 == LOW)
  {
    servo1.write(160);
    delay(2000);
    servo1.write(20);
  }
}