Servo on pushbutton

I have put together a program to control a project I'm working on, but decided to add 1 more servo. I need it to move 180 degrees when I push a button and stay there. When the same button is pushed again, the servo will return to its original position. As of right now, the servo will go to 180 and return to 0 but won't stay at 180. The rest of the program works fine. Servo 4 and button 3 are what are being used for this function and those parts are all in RED in the code.

#include <Servo.h>

Servo myservo1; // Tension servo
Servo myservo2; // Angle servo
Servo myservo3; // Fire pin servo
Servo myservo4; // Reload servo

int potpin1 = 0; // Analog pin used to connect the potentiometer for angle
int potpin2 = 1; // Analog pin used to connect the potentiometer for tension
int buttonPin1 = 17; // Fire!
int buttonPin2 = 16; // Reset
int buttonPin3 = 18; // Reload
int buttonState1 = 0; // Set buttonState for fire
int buttonState2 = 0; // Set buttonState for reset
int buttonState3 = 0; // Set buttonState for reload
int pos = 0; // Variable to store the servo position
int directionState = 0; // Variable for reading the direction of servo
int val; // variable to read the value from the analog pin
int ledPin = 13; // Ready light, if you have one change pin number

void setup()
{
myservo1.attach(9); // Attaches the tension servo on pin 9 to the servo object
myservo2.attach(6); // Angle servo on pin 6
myservo3.attach(5); // Fire servo on Pin 5
myservo4.attach(3); // Reload servo on Pin 3
pinMode(buttonPin1, INPUT); // Set Fire button to input
pinMode(buttonPin2, INPUT); // Set Reset button to input
pinMode(buttonPin3, INPUT); // Set Reload button to input
pinMode(ledPin, OUTPUT); // LED for ready light
}

void loop()
{
// Reset program. When reset button is pressed this is what happens
if (buttonState2 = digitalRead(buttonPin2))
{
digitalWrite(ledPin, LOW); // turns light off
delay (1000); // wait for servo
myservo3.write(120); // makes sure fire pin is out of the way
delay(500); // wait for servo to move
myservo1.write(0); // release tension
delay(500); // another wait
myservo2.write(20); // hit the arm down if needed
delay(500);
myservo3.write(0); // locks fire pin
val = analogRead(potpin2); // reads the value of the potentiometer for angle
val = map(val, 1023, 0, 0, 100); // scale it
myservo2.write(val); // sets the servo position according to the scaled value
delay(100); // wait
digitalWrite(ledPin, HIGH); //turn on ready light!
}
// End reset

else
// Main program!
//If fire button pressed:
if (buttonState1 = digitalRead(buttonPin1))
{
digitalWrite(ledPin, LOW); // ready light off
delay (500);
val = analogRead(potpin1); // Reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 1023, 0, 0, 220); // Scales it to use it with the servo (value between 0 and 180)
myservo1.write(val);
delay (1000);
myservo3.write(120);

//Reloading!!!!!
delay (1000); // Waits for fire servo
myservo3.write(120); // Makes sure fire pin is out of the way
delay(500); // Wait for fire servo to move
myservo1.write(0); // Release tension
delay(500); // Another wait
myservo2.write(20); // Hit the arm down if needed
delay(500);
myservo3.write(0); // Firing Pin locks arm
val = analogRead(potpin2); // Reads the value of the potentiometer for angle
val = map(val, 1023, 0, 0, 100); // Scale it
myservo2.write(val); // Sets the servo position according to the scaled value
delay(100); // Wait
digitalWrite(ledPin, HIGH); // Turn on ready light
}
// End of fire button

else
{
// This controls the angle live via pot
val = analogRead(potpin2); // Reads the value of the potentiometer (value between 0 and 1023)
val = map(val, 1023, 0, 0, 100); // Scale it for max angle and stop it from hitting things!
myservo2.write(val); // Sets the servo position according to the scaled value
delay(100); // Waits for the servo to get there
}

// Reload Ammo
{ (buttonState3 = digitalRead(buttonPin3));
// If reload button is pressed:
if (directionState == 0) {
if (buttonState3 == HIGH) {
directionState = 1; // The direction for Reload servo is clockwise
// Goes from 0 to 180 degreres in steps of 1 degree
for(pos = 0; pos < 180; pos=pos+5)
{
myservo4.write(pos); // Tell Servo to go to position in variable in "pos"

delay(15); // Waits 15 ms for the servo to reach the position
}
}
}

else if (directionState == 1); {
// The button is pushed
if (buttonState3 == HIGH) {
directionState = 0; // The direction for the servo is anti-clockwise

// Goes from 180 degrees to 0 degrees in steps of 1 degree
for(pos = 180; pos>=1; pos=pos-5)
{
myservo4.write(pos); // Tell servo to go to position in variable "pos"
delay(15); // Waits 15ms for the servo to reach the position
}
}
}
}
}

Actually your problem description is nice, you included the whole program (except you forgot the embarce in the "code tags" which you do by highlighting the code and then push the "curly paper piece" in the edit bar.) The code is a bit "messy" with wrong indentations and needless brackets. Still, taking the reload section of your program and reformatting it I get

{  
 (buttonState3 = digitalRead(buttonPin3));
  // If reload button is pressed:
     if (directionState == 0) {
        if (buttonState3 == HIGH) {
          directionState = 1; // The direction for Reload servo is clockwise
            **// Goes from 0 to 180 degreres in steps of 1 degree
        }
     }
       else // ( direction state is known to be !=0
         if (directionState == 1); {
           // The button is pushed
           if (buttonState3 == HIGH) {
             directionState = 0; // The direction for the servo is anti-clockwise
             ** // Goes from 180 degrees to 0 degrees in steps of 1 degree
           }
       }
}

(I have omitted the code that moves the servo to better see the flow)

The nitpicking bits - your comments are not correct "in steps of 1 degree" vs pos=pos+5 . The outer most curly brackets are without function (but do no harm, except confuse) and also the brackets around the buttonstate3 assignment.

Now to the essential bit. You test if direction is 0, then in the else portion you test if it is 1. If the variable can do other directions it is good code, if it only can 1 or 0 it is redundant to do the 2nd test. Indeed if it only is 0 or 1 you would make the program clearer by calling the variable clockWise and make it a boolean then the code reads if ( clockWise ) { turn CW } else { turn CCW code } which should be clear(er).

Now to the error (unless you have spotted it now with the better indentation and above comments. Try!)
Your code turns CW on the first push. Because of the else the code completes, goes round loop() and comes back a few microseconds later. Direction is set to 1 so we execute the bit after the else, and unless you managed to let go of the button while the servo is turning (180/5*15ms=0.54 second) the button is still DOWN and you thus immediatly do the CCW turn. So you need to test for that the button was let go in between.

To do that problem you need to code a State-Engine with the 4 states: Idle, First push, Armed, Second Push.

So now I'm very confused, this is the first time I have actually coded so Im kind of slow. I'm not sure of what a State-Engine is. Could I fix this by changing the else to if else?

Here is a State Machine sample that might give you some ideas.
Ask if you have any questions.

const unsigned long TaskAwait  = 50UL;   //Runs TaskA every 50ms 
const unsigned long TaskBwait  = 100UL;  //Runs TaskB every 100ms
const unsigned long TaskCwait  = 500UL;  //Runs TaskC every 1/2Sec
const unsigned long TaskDwait  = 1000UL; //Runs TaskD every 1Sec
//add more as needed

unsigned long TimeA;                     //Times up, run Task A
unsigned long TimeB;                     //Times up, run Task B
unsigned long TimeC;                     //Times up, run Task C
unsigned long TimeD;                     //Times up, run Task D
//add more as needed

unsigned long currentmillis; 

//other variables

//define the available states that we can have for this sketch
enum States{
  stateApple, stateOrange, statePear, stateKiwi};
States mState = stateApple;             //we start out in this machine state 

//========================================================== 
void setup()
{
  Serial.begin(9600);
  
  currentmillis = millis();
  TimeA = currentmillis;                 //initailize all times 
  TimeB = currentmillis;                 //
  TimeC = currentmillis;                 //
  TimeD = currentmillis;                 //

  pinMode(13,OUTPUT);                    //
  pinMode(12,OUTPUT);                    //
  pinMode(11,OUTPUT);                    //
  pinMode(10,OUTPUT);                    //
  
  mState = stateApple;                   //we start out in this machine state 

} //        >>>>>>>>>>>>>> END OF setup() <<<<<<<<<<<<<<<<<


void loop()
{
  // keep this at this location
  currentmillis = millis();  


  //************** State Machine section ************** 
  switch (mState)
  {
    //***************************
  case stateApple:

    //is it time to run this section of code?
    if (CheckTime(TimeA, TaskAwait)) 
    {
      TaskA();
    }
    
    //example below, how to change the machine state
    //mState = stateOrange;  

    break;

    //***************************
  case stateOrange:
    //is it time to run this section of code?
    if (CheckTime(TimeB, TaskBwait)) 
    {
      TaskB();
    }

    break;
    //***************************
  case statePear:

    //is it time to run this section of code?
    if (CheckTime(TimeC, TaskCwait)) 
    {
      TaskC();
    }

    break;

    //***************************
  case stateKiwi:

    //is it time to run this section of code?
    if (CheckTime(TimeD, TaskDwait)) 
    {
      TaskD();
    }

    break;

    //***************************
  default: 
    // statements
    break;

    //***************************
  }   // end of switch/case


  //************** Other stuff goes here ************** 


} //        >>>>>>>>>>>>>> END OF loop() <<<<<<<<<<<<<<<<<



// FUNCTIONS
//========================================================== 

//is the delay time period up yet?
boolean CheckTime(unsigned long &lastMillis, unsigned long wait) {

  //is the time up for this task?
  if (currentmillis - lastMillis >= wait) 
  {
    lastMillis += wait;  //get ready for the next timing cycle

    return true;
  }

  return false;

} //END of CheckTime()


//==================
void TaskA()
{
  digitalWrite(13,!digitalRead(13));   //Toggle pin 13
  //Other stuff

} //END of TaskA()

//==================
void TaskB()
{
  digitalWrite(12,!digitalRead(12));   //Toggle pin 12
  //Other stuff

} //END of TaskB()

//==================
void TaskC()
{
  digitalWrite(11,!digitalRead(11));   //Toggle pin 11
  //Other stuff

} //END of TaskC()

//==================
void TaskD()
{
  digitalWrite(10,!digitalRead(10));   //Toggle pin 10
  //Other stuff
  
} //END of TaskD()

//==================




//======================================================================
//                             END OF CODE
//======================================================================

LarryD:
Here is a State Machine sample that might give you some ideas.
Ask if you have any questions.

const unsigned long TaskAwait  = 50UL;   //Runs TaskA every 50ms 

const unsigned long TaskBwait  = 100UL;  //Runs TaskB every 100ms
const unsigned long TaskCwait  = 500UL;  //Runs TaskC every 1/2Sec
const unsigned long TaskDwait  = 1000UL; //Runs TaskD every 1Sec
//add more as needed

unsigned long TimeA;                    //Times up, run Task A
unsigned long TimeB;                    //Times up, run Task B
unsigned long TimeC;                    //Times up, run Task C
unsigned long TimeD;                    //Times up, run Task D
//add more as needed

unsigned long currentmillis;

//other variables

//define the available states that we can have for this sketch
enum States{
  stateApple, stateOrange, statePear, stateKiwi};
States mState = stateApple;            //we start out in this machine state

//==========================================================
void setup()
{
  Serial.begin(9600);
 
  currentmillis = millis();
  TimeA = currentmillis;                //initailize all times
  TimeB = currentmillis;                //
  TimeC = currentmillis;                //
  TimeD = currentmillis;                //

pinMode(13,OUTPUT);                    //
  pinMode(12,OUTPUT);                    //
  pinMode(11,OUTPUT);                    //
  pinMode(10,OUTPUT);                    //
 
  mState = stateApple;                  //we start out in this machine state

} //        >>>>>>>>>>>>>> END OF setup() <<<<<<<<<<<<<<<<<

void loop()
{
  // keep this at this location
  currentmillis = millis();

//************** State Machine section **************
  switch (mState)
  {
    //***************************
  case stateApple:

//is it time to run this section of code?
    if (CheckTime(TimeA, TaskAwait))
    {
      TaskA();
    }
   
    //example below, how to change the machine state
    //mState = stateOrange;

break;

//***************************
  case stateOrange:
    //is it time to run this section of code?
    if (CheckTime(TimeB, TaskBwait))
    {
      TaskB();
    }

break;
    //***************************
  case statePear:

//is it time to run this section of code?
    if (CheckTime(TimeC, TaskCwait))
    {
      TaskC();
    }

break;

//***************************
  case stateKiwi:

//is it time to run this section of code?
    if (CheckTime(TimeD, TaskDwait))
    {
      TaskD();
    }

break;

//***************************
  default:
    // statements
    break;

//***************************
  }  // end of switch/case

//************** Other stuff goes here **************

} //        >>>>>>>>>>>>>> END OF loop() <<<<<<<<<<<<<<<<<

// FUNCTIONS
//==========================================================

//is the delay time period up yet?
boolean CheckTime(unsigned long &lastMillis, unsigned long wait) {

//is the time up for this task?
  if (currentmillis - lastMillis >= wait)
  {
    lastMillis += wait;  //get ready for the next timing cycle

return true;
  }

return false;

} //END of CheckTime()

//==================
void TaskA()
{
  digitalWrite(13,!digitalRead(13));  //Toggle pin 13
  //Other stuff

} //END of TaskA()

//==================
void TaskB()
{
  digitalWrite(12,!digitalRead(12));  //Toggle pin 12
  //Other stuff

} //END of TaskB()

//==================
void TaskC()
{
  digitalWrite(11,!digitalRead(11));  //Toggle pin 11
  //Other stuff

} //END of TaskC()

//==================
void TaskD()
{
  digitalWrite(10,!digitalRead(10));  //Toggle pin 10
  //Other stuff
 
} //END of TaskD()

//==================

//======================================================================
//                            END OF CODE
//======================================================================

Very nice looking example that beginners should be taking some notes from!! Learn functions and how to implement them! It will save you a lot of time recoding things already coded and makes your code easy to follow and debug!

think you may have a bug..

if (directionState==0) is tested and on true your setting directionState =1. Then your retesting with an elseif (directionstate==1). So if directionstate was ==0 both blocks of code will get executed.
Is that the intention?

I just want the servo to move one way at the push of a button. and when the button is pushed again, it moves the opposite direction.

   if (directionState == 0) {
        if (buttonState3 == HIGH) {
            directionState = 1; // **** remove this as the next test will prove true as is and turn the           
                                      //servo back!!
            // Goes from 0 to 180 degreres in steps of 1 degree
            for(pos = 0; pos < 180; pos=pos+5)
            {
              myservo4.write(pos); // Tell Servo to go to position in variable in "pos"
              
              delay(15); // Waits 15 ms for the servo to reach the position
            }
          }
        }
        
        else if (directionState == 1); { //*** if directionState WAS 0 its NOW 1!!!!!
        // The button is pushed
        if (buttonState3 == HIGH) {
          directionState = 0; // The direction for the servo is anti-clockwise
          
          // Goes from 180 degrees to 0 degrees in steps of 1 degree
          for(pos = 180; pos>=1; pos=pos-5)
          {
            myservo4.write(pos); // Tell servo to go to position in variable "pos"
            delay(15); // Waits 15ms for the servo to reach the position
          }

so perhaps after both elseif statements have been evaluated set directionState =!(directionState)..

Or before the testing use a temp variable such as int OriginalDirectionState = directionState, and test the value of OriginalDirectionState in your elseif clauses.

I just want the servo to move one way at the push of a button. and when the button is pushed again, it moves the opposite direction.

Simple button/servo toggle test code you can try to get some ideas. Push button and release to toggle.

//zoomkat servo button toggle test 4-28-2012

#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
}