How to Hold the Two Shafts of Servo Motor ?

I want to hold two shafts of servo motor.

Hardware :
Two servo motors HS-805BB connecting to PC power, 5 voltage.
servo One HS-805BB connecting to pin 9 of Arduino Uno border.
servo two HS-805BB connecting to pin 10 ot Arduino Uno border.

After I run the folowing program

#include <Servo.h> 

Servo myservo;
int servo_one=30;
int servo_two=90;
void setup() 
{ 
 myservo.attach(9);
 myservo.write(servo_one);//set servo one to 30 degree position.
 myservo.attach(10);
 myservo.write(servo_two);  // set servo two to 90 degree position.
} 

void loop() {}

when I check the two shafts by hand. I find.
The shaft of servo one is not held (it is easy to move by hand).
The shaft of servo two is held( it is hard to move by hand)

I change the program, moving
myservo.attach(10);
myservo.write(servo_two);
up, that is following program

#include <Servo.h> 

Servo myservo;
int servo_one=30;
int servo_two=90;
void setup() 
{ 
 myservo.attach(10);
 myservo.write(servo_two);  // set servo two to 90 degree position.
 myservo.attach(9);
 myservo.write(servo_one);//set servo one to 30 degree position.
  
} 

void loop() {}

After I run this program I find.
The shaft of servo one is held (it is hard to move by hand).
The shaft of servo two is not held( it is easy to move by hand)

I hope to get help:
How to hold the two shafts of servo motor ?

If you have two physical servo objects, you need to have two logical servo objects - two instances of the Servo class. You currently only have one. It is connected to either pin 9 OR pin 10, depending on which code you are running.

#include <Servo.h> 

Servo myservo1;
Servo myservo2;
int servo_one=30;
int servo_two=90;
void setup() 
{ 
 myservo1.attach(10);
 myservo1.write(servo_two);  // set servo two to 90 degree position.
 myservo2.attach(9);
 myservo2.write(servo_one);//set servo one to 30 degree position.
} 

void loop() {}

Hi robtillaart
you are number one servo motor control programmer. I run your program, yes it is strongly holding tow servo motor shafts.
also thank for PaulS.

too much honor, just reading the manuals and tutorials helps a lot :wink:

I am careful to read at learing

and Servo library at

but got no ideals like you gave, very important is this
Servo myservo1;
Servo myservo2;
could you tell me where you find this tip at

It is normal Object Oriented thinking: you make an instance for every real life object; so every servo needs one instance.

after some searching I found these two links too

With your tip I rewrite my program, two shafts were strongly holding.
I will read information you provided.
Thank you a lot.

#include <Servo.h> 
Servo myservo1;
Servo myservo2;
//Servo myservo;
int servo_one ;
int servo_one_flag=0;
int servo_two;
int servo_two_flag=0;

void setup() 
{ 
 
   Serial.begin(9600);
  
} 

void loop() {

 if(servo_one_flag==1)
{servo_one = 30;
 myservo1.attach(9);
 myservo1.write(servo_one);
 servo_one_flag=0;
}
else {
  servo_one = 150;
 myservo1.attach(9);
 myservo1.write(servo_one);
 servo_one_flag=1;
}
 
 Serial.print("servo_one's angle =");
Serial.println(servo_one);
delay(1000); 
   if(servo_two_flag==1)
{servo_two = 30;
 myservo2.attach(10);
 myservo2.write(servo_two);
 servo_two_flag=0;
}
else {
  servo_two = 120;
 myservo2.attach(10);
 myservo2.write(servo_two);
 servo_two_flag=1;
}
Serial.print("servo_two's angle =");
Serial.println(servo_two);
delay(1000);


}

YOu need to attach only once in setup. That makes your code looks like:

#include <Servo.h> 

// VARIABLES
Servo myservo1;
Servo myservo2;

int servo_one ;
int servo_one_flag=0;
int servo_two;
int servo_two_flag=0;

void setup() 
{ 
   Serial.begin(115200);  // please use highest baudrate possible

   // SETUP SERVOS
   myservo1.attach(9);
   myservo2.attach(10);
} 

void loop() 
{
  if(servo_one_flag==1)
  {
    servo_one = 30;
    myservo1.write(servo_one);
    servo_one_flag=0;
  }
  else 
  {
    servo_one = 150;
    myservo1.write(servo_one);
    servo_one_flag=1;
  }
  Serial.print("servo_one's angle =");
  Serial.println(servo_one);

  delay(1000); 
  if(servo_two_flag==1)
  {
    servo_two = 30;
    myservo2.write(servo_two);
    servo_two_flag=0;
  }
  else
  {
    servo_two = 120;
    myservo2.write(servo_two);
    servo_two_flag=1;
  }
  Serial.print("servo_two's angle =");
  Serial.println( myservo2.read() );  // read back the value from the servo object
  delay(1000);

}

Hi robtillaart
I try put more than 9600, like Serial.begin(14400), but it is not work. I don't know why ?maybe it is related to the kind of boarder.
Yes I agree that myservo.read() is better to get a real value of the angle from currenting running servo.

I rewrote my program, it is a program to run two servo motors at the same time and is strongly holding the shafts. I got the key to open the robot arm's door.

#include <Servo.h> 
Servo myservo1;
Servo myservo2;
int servo_one ;
int servo_flag=0;
int servo_two;
int pinx = 9;
int piny = 10;
void setup() 
{ 
 Serial.begin(9600);
 } 

void loop() {
if(servo_flag==1)
{servo_one = 0;
 myservo1.attach(pinx);
 myservo1.write(servo_one);
 servo_two = 30;
 myservo2.attach(piny);
 myservo2.write(servo_two);
 servo_flag=0;
}
else {
  servo_one = 180;
 myservo1.attach(pinx);
 myservo1.write(servo_one);
 servo_two = 120;
 myservo2.attach(piny);
 myservo2.write(servo_two);
 servo_flag=1;
}
 Serial.print("servo_one's angle =");
 Serial.println(myservo1.read());
 Serial.print("servo_two's angle =");
 Serial.println(myservo2.read());
 delay(1000); 
}

Hi jack_lai

you missed robtillaart's excellent suggestion of moving the attach code into the setup() part.

IF you change the Serial.begin(value) you must ALSO make the same change in the Serial Monitor (on the pc) - they must match. If you use another program to talk to the COM port, it, too, must be set to the same value as you put in Serial.begin. That is true of all boards.

BTW, when I use several Servos like that, I give them usefull names, that reflect what they mechanically do. The beginning of my code would be along the lines of

Servo Upper, Lower ; // Two servos. The name reflects what mechanic they power, rather than "1" or "2"
void setup() {
  Lower.attach(pinx) ; // this will power (and thus hold position) of the servos at start.
  Upper.attach(piny) ; // unfortunatly they also will go the servo library default position (roughly mid position) at full power until they get a new write
  Serial.begin(9600) ; // if you set this to 14400 you ALSO need to set the SerialMonitor speed window or whatever terminal program you use
}
void loop() {
 if (.. decision value..)
  Upper.write(30) ;
  Lower.write(120) ;
 } else ......

Lastly, the read() function of Servo does not return the actual position, it only returns the last write() value you gave (which should be the position they are at, if no mechanical failure) so it can not be used to "measure" the position. There is no electrical signal from the servo back to the Arduino to do that.

// unfortunatly they also will go the servo library default position (roughly mid position)

This comment caught my eye.
There seems to me no reason you shouldn't perform a "write" or "writeMicroseconds" before performing the "attach".
The default positions are setup in the constructor.

There seems to me no reason you shouldn't perform a "write" or "writeMicroseconds" before performing the "attach".

The attach() function is used to define which pin the servo is attached to. How can you usefully perform a write() before defining the pin that the servo is attached to?

How can you usefully perform a write() before defining the pin that the servo is attached to?

You're performing the write to the servo object.
The object doesn't need to be attached to a pin for the "ticks" member variable to be written.

The comment was that the servo always moves to the centre when attached, and that this was in some way undesireable; all I did was to suggest a way to move the servo to some other default position when attached.

Imagine your sketch runs to completion, parking the three servos at 30, 60 and 120 "degrees".
It would be nice if resetting the board didn't cause them to jerk over to 90 "degrees".

The object doesn't need to be attached to a pin for the "ticks" member variable to be written.

I hadn't looked at the code. I can see how the write() would simply set up a position variable, in the absence of being able to actually perform the move to that position. Then, I presume, when an attach occurs, there is known position to move to.

Thanks for sharing.

I agree, it does sound sort of counter-intuitive - and I guess the behaviour is not guaranteed in future versions.

I think the strangeness comes from thinking of the "attach" as being more like a constructor (that's my excuse, anyway), which it most certainly isn't.

I think the strangeness comes from thinking of the "attach" as being more like a constructor (that's my excuse, anyway)

I've gotten used to constructors not being able to do everything I would expect a constructor to be able to do. I've become used to using a begin() method to perform the tasks that the constructor would normally perform. I know that one can not call methods like Serial.print() and expect useful action unless one has called Serial.begin().

I had assumed that Servo.attach() was similar to Serial.begin(), in that it needed to be called before other Servo functions would be reasonably used. Thinking about it, I guess the function would have been called begin(), instead of attach(), if that was indeed the case.

Interesting point, AWOL. I found that attach() followed shortly by a write() was sufficient for it not to go to the middle first. Your suggestion is more elegant.

The "real" problem with Servo on power initialization (in this case, when you do attach) is that the Servo will go to the write()/middle position from whereever it was from its idle/non-powered state. You cant ask a Servo to stay where it happens to be on attach/power on. In a clumsy way I was hinting at this by pointing out default behavior.

Anyhow, let us leave the thread for the OriginalPoster and his problem. :slight_smile: How is it going jack_lai?