Push button servo controller sketch. Help, ideas, hand-holding Please?

I'm looking for a little help, guidance, ideas.

I found a sketch on a closed forum http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1246742084 here that looked to be just about exactly what I needed. It was originally written as a two button, one servo controller with a few minor errors that were easily corrected. I can attach the original sketch if anyone wants to see it.

After correcting the errors and testing the sketch as I went, I started to add an additional servo and an additional separate button set to control that servo. Testing as I went along. It works great! EXCEPT! And here is where I need a little help:

If I use myservo1 going either forward or reverse by pushing one of its two attached buttons and then do the same for myservo2, that servo slews about 20°. The same thing happens if I to this in the reverse; the second servo slews or jumps 20° sometimes forward, sometimes backwards.

Here is the sketch:
(Thanks mem)

#include <Servo.h>

  Servo myservo1;          // define servo aliases
  Servo myservo2;
  #define leftPin 2        // define buttons attached to pins
  #define rightPin 3
  #define upPin 4
  #define downPin 5
  int pos = 90;          // set angle when inialitized
  int delayPeriod = 150;   // increasing this slows down the servo slew movement
                          // 1000 too much 300 jumpy 100 smooth slew 80 fast 50 too fast 70 testing
void setup()
{
  myservo1.attach(10);    // attaches the servo on pin 9 to the servo object
  myservo2.attach(9);     // attaches the servo on pin 10 to the servo object
  myservo1.write(pos);    // center the servo from inialitization
  myservo2.write(pos);    // center the servo from inialitization
  pinMode(leftPin, INPUT);   
  pinMode(rightPin, INPUT);  
  pinMode(upPin, INPUT);     
  pinMode(downPin, INPUT);   
 
  digitalWrite(leftPin, HIGH);    // turn on pullup resistor
  digitalWrite(rightPin, HIGH);   // turn on pullup resistor
  digitalWrite(upPin, HIGH);      // turn on pullup resistor 
  digitalWrite(downPin, HIGH);    // turn on pullup resistor
 
   // left/right servo control
}
void loop()
{
  if(digitalRead(leftPin) == HIGH)        // left button instructions  
  {
   // in steps of 1 degree
   if( pos > 0)
	--pos;
    myservo1.write(pos);		  // tell servo to go to position in variable 'pos'
    delay(delayPeriod);			    
  }
  if(digitalRead(rightPin) == HIGH)       // right button instructions  
  {
   if( pos < 180)
	 ++pos;
    myservo1.write(pos);		  // tell servo to go to position in variable 'pos'
    delay(delayPeriod);	 
  }

   // up/down servo control  
   { 
   if(digitalRead(upPin) == HIGH)         // up button instructions  
  {
   // in steps of 1 degree
   if( pos > 0)
	--pos;
    myservo2.write(pos);		  // tell servo to go to position in variable 'pos'
    delay(delayPeriod);			    
  }
  if(digitalRead(downPin) == HIGH)        // down button instructions  
  {
   if( pos < 180)
	 ++pos;
    myservo2.write(pos);		  // tell servo to go to position in variable 'pos'
    delay(delayPeriod); 
  }
} }

Any ideas?
Am I missing something?
This is my first real sketch and I am a veteran of Arduino for a total of six days!

I have tried tons of things! namely changing the parameters of the pinMode, adding and deleting digitalWrite, Playing with the delayPeriod timing.
I have also tried to play with the pull-down resistors only to find out that if i use a 10k, 4.7k or even a 220? the buttons do not respond. I'm currently using a 270? pull-down and the servos no longer chatter.

Again, any ideas?
I'm using it to control the x-y axis of a security camera via a switched joy stick controller.

I would really like to solve this puzzle. But if anybody has a different sketch that accomplish this I would really appreciate taking a gander at it.

Thank you all in advance.

Peace.

Hi ih8mud

Your sketch enables internal pull-ups in setup but the loop code is checking for a HIGH value when it should be checking for LOW. Try removing the external resistors and changing the four button test lines from:
if(digitalRead(___Pin) == HIGH)
to
if(digitalRead(___Pin) == LOW)

This code only handles one button press at a time, are you wanting to hold more than one button down to control multiple servos?

Hey dude

I am only learning servo control myself at the moment, so may be missing something...

BUT

You are using the same variable, pos, to hold the position of your up/down servo and your left/right servo, so moving one servo is going to affect the position of the other.

I would create 2 pos variables, say servo1Pos and servo2Pos and use each of these where relevant.

cheers

Thanks for the replies!

Try removing the external resistors and changing the four button test lines from:
if(digitalRead(___Pin) == HIGH)
to
if(digitalRead(___Pin) == LOW)

I tried this and the servos still chatter without the resistors.

are you wanting to hold more than one button down to control multiple servos?

It would be ideal to control each servo at the same time. What would I need to do in order to make this sketch handle more than one servo?

I would create 2 pos variables, say servo1Pos and servo2Pos and use each of these where relevant.

Thanks for the idea. now I need to figure out how to make the two variables work. Any ideas?

Peace.

Hey All!

Ah! I think I fingered it out! It seems to work now without having the servos jump and I had to keep the external resistord (270?) in place otherwise the servos get the jitters.

Thanks AgeingHippy for putting me on the correct path!

Here's the sketch so far:

// test sketch a.2
#include <Servo.h>

  Servo servo1;          // define servo aliases
  Servo servo2;
  #define leftPin 2        // define buttons attached to pins
  #define rightPin 3
  #define upPin 4
  #define downPin 5
  int pos1 = 45;          // set angle when inialitized
  int pos2 = 90;
  
  int delayPeriod = 80;   // increasing this slows down the servo slew movement
                          // 1000 too much 300 jumpy 100 smooth slew 80 fast 50 
                          // too fast 70 testing
                          // Project addition idea:
                          // add variable to control slew rate via potentiometer 
                          // connected to analog input pin
                          
void setup()
{
  //test
  servo1.write(pos1);  // Put servo1 at home position 
  servo2.write(pos2);  // Put servo1 at home position 
    
  servo1.attach(10);    // attaches the servo on pin 9 to the servo object
  servo2.attach(9);     // attaches the servo on pin 10 to the servo object

  pinMode(leftPin, INPUT);   
  pinMode(rightPin, INPUT);  
  pinMode(upPin, INPUT);     
  pinMode(downPin, INPUT);   
 
//  digitalWrite(leftPin, HIGH);    // turn on pullup resistor
//  digitalWrite(rightPin, HIGH);   // turn on pullup resistor
//  digitalWrite(upPin, HIGH);      // turn on pullup resistor 
//  digitalWrite(downPin, HIGH);    // turn on pullup resistor
 //test 
  if(digitalRead(leftPin) == LOW);    // turn on pulldown resistor
  if(digitalRead(rightPin) == LOW);   // turn on pulldown resistor
  if(digitalRead(upPin) == LOW);      // turn on pulldown resistor 
  if(digitalRead(downPin) == LOW);    // turn on pulldown resistor
 
   // left/right servo control
}
void loop()
{
  if(digitalRead(leftPin) == HIGH)        // left button instructions  
  {
   // in steps of 1 degree
   if( pos1 > 0)
	--pos1;
    servo1.write(pos1);		  // tell servo to go to position in variable 'pos1'
    delay(delayPeriod);			    
  }
  if(digitalRead(rightPin) == HIGH)       // right button instructions  
  {
   if( pos1 < 180)
	 ++pos1;
    servo1.write(pos1);		  // tell servo to go to position in variable 'pos1'
    delay(delayPeriod);	 
  }

   // up/down servo control  
   { 
   if(digitalRead(upPin) == HIGH)         // up button instructions  
  {
   // in steps of 1 degree
   if( pos2 > 0)
	--pos2;
    servo2.write(pos2);		  // tell servo to go to position in variable 'pos2'
    delay(delayPeriod);			    
  }
  if(digitalRead(downPin) == HIGH)        // down button instructions  
  {
   if( pos2 < 180)
	 ++pos2;
    servo2.write(pos2);		  // tell servo to go to position in variable 'pos2'
    delay(delayPeriod); 
  }
} }

I know it's a bit unorganized and very verbose. Any suggestions on maybe cleaning it up a bit? Like I said, I'm very green at this.

Thanks all for helping me think this through.

I'm still very open to suggestions and comments on improving this sketch.

Peace

Hey Dude

One more thing I have found, is that you also can get interference if you use the same power source for your microprocessor (Arduino) and the servo motors. At least, this is occurring with my tests using towerpro servos brought from DealExtreme.

Using a separate power source gives better performance.

  if(digitalRead(leftPin) == LOW);    // turn on pulldown resistor
  if(digitalRead(rightPin) == LOW);   // turn on pulldown resistor
  if(digitalRead(upPin) == LOW);      // turn on pulldown resistor 
  if(digitalRead(downPin) == LOW);    // turn on pulldown resistor

The comments are flat out wrong. There are no pulldown resistors on the Arduino, so you can't turn them on. You don't turn on pullup resistors using digitalRead. A do nothing if test seems useless.

Any suggestions on maybe cleaning it up a bit?

Each { and } should be on a separate line. Only the necessary { and } should be used. The one before the if(digitalRead(upPin) == HIGH) statement is not needed, nor is the matching }. Line the { and } up with the statement they go with.

Comments that say the exact same thing as the code are not necessary.
servo2.write(pos2); // tell servo to go to position in variable 'pos2'
What else could that statement be doing?

Thanks PaulS. you are absolutely correct. My bad! What do you expect from a nube?

Now I know. In the future I will be more careful about my excessive comments.

Fat fingers! Disregard the previous re-post.

Well, I worked on it some more and corrected the non "relevant" "{" and "}" 's and the really "flat out wrong" statement regarding the pulldown resistors.

I also added a variable so that I can adjust she slew rate via a pot rather than changing the parameter and uploading each time.

// test sketch 3.c
#include <Servo.h>

  Servo servo1;          // define servo aliases
  Servo servo2;
  #define leftPin 2        // define buttons attached to pins
  #define rightPin 3
  #define upPin 4
  #define downPin 5
  int pos1 = 90;          // set angle when inialitized
  int pos2 = 135;
  
     #define POT 3        // pot to analog pin 3
     int potValue = 0;    // variable for pot value
                          
void setup()
{
  servo1.write(pos1);  // Put servo1 at home position 
  servo2.write(pos2);  // Put servo1 at home position 
    
  servo1.attach(10);    // attaches the servo on pin 9 to the servo object
  servo2.attach(9);     // attaches the servo on pin 10 to the servo object

  pinMode(leftPin, INPUT);   
  pinMode(rightPin, INPUT);  
  pinMode(upPin, INPUT);     
  pinMode(downPin, INPUT);   
}

void loop()
{
//pot control  
  {
      potValue = analogRead(potValue);                // reads the value of the potentiometer 
                                                      // (value between 0 and 1023)
      potValue = map(potValue, 0, 1024, 1, 400);      // scale it to use it with the 
                                                     // servo (value between 0 and 1024)
  }
// left/right servo control
  if(digitalRead(leftPin) == HIGH)        // left button instructions  
  {
   // in steps of 1 degree
   if( pos1 > 0)
	--pos1;
    servo1.write(pos1);		  // tell servo to go to position in variable 'pos1'
    delay(potValue);			    
  }
  if(digitalRead(rightPin) == HIGH)       // right button instructions  
  {
   if( pos1 < 180)
	 ++pos1;
    servo1.write(pos1);		  // tell servo to go to position in variable 'pos1'
    delay(potValue);	 
   }

// up/down servo control  
 
   if(digitalRead(upPin) == HIGH)         // up button instructions  
   {
   // in steps of 1 degree
   if( pos2 > 0)
	--pos2;
    servo2.write(pos2);		  // tell servo to go to position in variable 'pos2'
    delay(potValue);			    
   }
   if(digitalRead(downPin) == HIGH)        // down button instructions  
   {
   if( pos2 < 180)
	 ++pos2;
   servo2.write(pos2);		  // tell servo to go to position in variable 'pos2'
   delay(potValue); 
   } 
}

I hope I did better this time.

Again, if anybody can offer constructive criticism by example in how I can make this sketch more effecient, I would appreciate hearing from you.

And also please understand that I have only been playing with the Arduino unit for a week. So I don't know everything some people do. Thanks All.

Peace.

      potValue = map(potValue, 0, 1024, 1, 400);      // scale it to use it with the 
                                                     // servo (value between 0 and 1024)

Again there are unnecessary { and }, and the comments are sometimes inconsistent with the code. I won't mention them again, though, unless it is relevant, as in this case. What kind of servo do you have that starts at 1 and goes to 400? Most servos have a range from 0 to about 180.

Never mind. I see that potValue doesn't control a servo at all.

  if(digitalRead(leftPin) == HIGH)        // left button instructions

I see no statement that enables the internal pullup resistor. The comparison to HIGH implies the use of a pulldown resistor, but there is no mention of the use of one. Do you actually have external pulldown resistors?

I'd like to see you work on the format of your code. Random indenting does nothing to make it readable. Try using the Tools + Auto Format option, and see what it does to the code. In general, I find that it makes it easier to see the range of blocks, etc., making the code easier to understand at a glance.