Robotic Arm: How to move servo one degree

Hi Guys,
I’m in the process of trying to make a robotic arm but I’m having trouble before really starting the project!
I’m trying to simply use 2 buttons to control a servo. One button makes the servo go one direction and the other button makes the servo go the other way.

I can get the servo to move to 180 and to 0 with the individual buttons being pressed but I want the servo to move only one degree when the button is pressed, when the button is held down I want the servo to move in one direction until it either reaches 180 or 0, or when the button is released.

Here is my code to get the servo to move to 180/0:

#include <Servo.h>

Servo myservo;

int button = 6;
int button2 = 9;

int buttonState = 0;
int button2State = 0;

void setup() {
  myservo.attach (3); //attaches servo to pin 3
  
  pinMode (button, INPUT);
  pinMode (button2, INPUT); //declares buttons as inputs
  
  digitalWrite (button, HIGH);  //uses internal pull-up resistor
  digitalWrite (button2, HIGH);
  
  myservo.write (90); //centers servo
  delay (500);
 }

void loop() {
  buttonState = digitalRead (button);
  button2State = digitalRead (button2); //reads buttons and declares them as a state
  delay (1);
  
  if (buttonState == LOW) { //if button = LOW, eg when button is pressed
    for (int pos=90; pos < 180; pos++) { //write servo to 180 degrees, I want this line to write the servo one degree to the right
    myservo.write (pos);
    }   
    }
  
  if (button2State == LOW) { //if button = LOW, eg when button is pressed
    for (int pos=90; pos > 0; pos--){ //write servo to 180 degrees, I want this line to write the servo one degree to the left
    myservo.write (pos);
  }
}
}

I hope this all makes sense!

Any help will be appreciated!
Thanks nathman11

First thing to do

  for (int pos=90; pos < 180; pos++) { //write servo to 180 degrees, I want this line to write the servo one degree to the right
    myservo.write (pos);
    }

Instead of a for loop just change the position variable and write the new value to the servo each time the button BECOMES pressed, not when it IS pressed. Test the position variable and do not let it exceed the 0 to 180 range. For more precise movement, assuming that the servo is a decent one, use writeMicroseconds() instead of write() as the granularity of the movement is smaller.

Second thing to do
When the button is held down for a period you decide, allow the program to change the position variable at intervals until the button is released. Use millis() timing for this as using delay() will cause the program to effectively halt waiting for the delay() to end.

Some servo/button test code that might be worth a look. Can’t remember if it worked or not.

//zoomkat servo button sweep test 12-23-2013
// Powering a servo from the arduino usually *DOES NOT WORK*.

#include <Servo.h>
int button1 = 5; //button pin, connect to ground to move servo
int press1 = 0;
int button2 = 6; //button pin, connect to ground to move servo
int press2 = 0;
Servo servo1;
int pos = 90; // variable to store and set the servo position 

void setup()
{
  Serial.begin(9600);
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  servo1.attach(7);
  servo1.write(pos); //starting position
  digitalWrite(5, HIGH); //enable pullups to make pin high
  digitalWrite(6, HIGH); //enable pullups to make pin high
  Serial.println("servo button sweep test 12-23-2013");
}

void loop()
{
  press1 = digitalRead(button1);
  if (press1 == LOW)
  {
    pos=(pos+1);
    if(pos>180) pos=180; //limit upper value
    Serial.println(pos); //for serial monitor debug
    servo1.write(pos); // tell servo to go to position in variable 'pos' 
    delay(150); // waits 150ms to slow servo movement 
  }    

  press2 = digitalRead(button2);
  if (press2 == LOW)
  {
    pos=(pos-1);
    if(pos<0) pos=0; //limit lower value
    Serial.println(pos); //for serial monitor debug
    servo1.write(pos); // tell servo to go to position in variable 'pos' 
    delay(150); // waits 150ms to slow servo movement
  }
}

You may also be interested in how the servo is controlled in the demo several things at a time.

...R

Hi Guys, Thanks heaps for your help! I'll have to try it out and see if it works. Thank you for all your time! Nathman11

Hi Zoomkat,
I tried your program and it doesn’t seem to work, I edited it so that it would work with the pins I had the button and servo attached to and it seems to move to 90 degrees in the void setup() part but then it just slowly moves from 90 to 180.
Any ideas how to fix it?
I tried using the same concept in my original code which has worked here is the code:

#include <Servo.h>

Servo myservo;

int button = 6;
int button2 = 9;

int buttonState = 0;
int button2State = 0;
int pos = 90;

void setup() {
  myservo.attach (3); //attaches servo to pin 3
  
  pinMode (button, INPUT);
  pinMode (button2, INPUT); //declares buttons as inputs
  
  digitalWrite (button, HIGH);  //uses internal pull-up resistor
  digitalWrite (button2, HIGH);
  
  myservo.write (pos); //centers servo
  delay (500);
 }

void loop() {
  buttonState = digitalRead (button);
  button2State = digitalRead (button2); //reads buttons and declares them as a state
  delay (1);
  
  if (buttonState == LOW) { //if button = LOW, eg when button is pressed
    pos = (pos+1); 
    myservo.write (pos);
    delay (20);
    }   
  
  if (button2State == LOW) { //if button = LOW, eg when button is pressed
    pos = (pos-1);
    myservo.write (pos);
    delay (20);
  }
}

Once again thanks heaps!
nathman11

but then it just slowly moves from 90 to 180.

How are your buttons electrically connected on your arduino? The servos should only move when the button is depressed, and not move when the buttons are released. Also my code prints the position to the serial monitor for debugging, you might want to try that too.