two synchronized servomotors

Hi everyone, I’m trying to make an electronic arm.
On the base I would like to use two servo motors like this project (See Attachment and link):

My motors are MG996R

if I put the two servo motors at 90 degrees my result is the one attached, they are not aligned.
Not even modifying the code in this way, as suggested by other projects found on google:
myservo.attach(9,600,2300);

I also tried to take it apart and reassemble it after putting it at 90 degrees but the result is the one attached, because the servomotors with their teeth can not be put in the perfect position, I can choose to fit it one step forward or one step back but the result is worse than the one attached.
how can I do?
thank you

arm.jpg

I can't see any code. If you're using the Servo library and you're not using writeMicroseconds() then start with that. It allows more accuracy than the basic write(angle).

If that won't do it you'll need to change the mechanical attachment of the arm to the servo.

Steve

Try this test program to find the microseconds position closest to 90°, then use that with an offset.

/*
  Try this test sketch with the Servo library to see how your
  servo responds to different settings, type a position
  (0 to 180) or if you type a number greater than 180 it will be
  interpreted as microseconds(544 to 2400), in the top of serial
  monitor and hit [ENTER], start at 90 (or 1472) and work your
  way toward zero (544) 5 degrees (or 50 micros) at a time, then
  toward 180 (2400).
*/
#include <Servo.h>
Servo servo;

void setup() {
  // initialize serial:
  Serial.begin(9600); // set serial monitor baud rate to match,
                      // set line ending to "Newline"
  servo.write(90);
  servo.attach(9);
  prntIt();
}

void loop() {
  // if there's any serial available, read it:
  while (Serial.available() > 0) {

    // look for the next valid integer in the incoming serial stream:
    int pos = Serial.parseInt();
    if(Serial.read() == '\n'){} // skips 1 second delay
    pos = constrain(pos, 0, 2400);
    servo.write(pos);
    prntIt();
  }
}
void prntIt()
{
  Serial.print("  degrees = ");
  Serial.print(servo.read());
  Serial.print("\t");
  Serial.print("microseconds =  ");
  Serial.println(servo.readMicroseconds());
}

iacoposk8:
My motors are MG996R

if I put the two servo motors at 90 degrees my result is the one attached, they are not aligned.

No, they are hobby servos, they are not precision manufactured, they are made to a low price for controlling RC cars/planes.

Higher grade servos cost more.

The biggest problem I see is your level-arm looks too large for a small servo like that to be able to
provide enough torque, have you done the calculations for torque? You realize most servo's rated
torque is not a continuous rating and that they can cook if under constant high torque load?

You have the added problem of the two unmatched servos fighting each other since their
notion of positions doesn't match up. Perhaps some sort of calibration could be done
to better match them?

Trim and reversing.

Since the 2 servos are attached from opposite sides, one will need to turn in the opposite direction.
You will need to reverse one servo. This can be done by adding to the initial position for one servo and subtracting from the initial position from the other.

And as you have discovered, the exact position of the 2 servos given the same position instruction will differ. So build in a trim. this can be a number that is added to the position calculation for one servo.

Oh, if you are working on a project where you want precise servo movements, do not use servo.write()
This only has 180 steps. Instead, use servo.writeMicroseconds(). This permits much finer movement. Maybe 1000 steps, up to about 1800 steps, depending on how you initialize the logical servo and what signal range the actual servo accepts.

Using two servos like this is never great IMO , but people do it .. - the position of the servo is determine by the internal feedback pot . Two pots will not track accurately over the full travel , so they will fight at some points increasing current , but reducing torque .
A big servo is the answer or make your own using a geared motor ( and external feedback pot - google that ; there are some examples using windscreen wiper motors , which can be found cheaply and are powerful, there will be other options )

As a bit on information that is kinda sorta related to your issue. As was mentioned above use .writeMicroseconds for more precision. With .writeMicroseconds your offset will have more meaning.

The servo you are using can go from 0 to 180 degrees. That is a travel range from 500uSec to 2500uSec. That is a travel distance of 2000Usec. 2000 is an important number as you seek precise servo control. 1500uSec = 90 degrees. And with a limit of servo travel set to 180 degrees (0,180) you get 5.55uS per degree. I found it is way better to use 5.54uS per degree over a 2000uS range. As you may be able to see you can get 5.5 increments per degree at 0 to 180.

Playing with numbers lets say you limit your servo travel to 90 degrees around the center position. That's + 45 and -45 off of 90. You still get a 2000uSec range which gives you 11.11uS per degree. Now the ability to more precisely position the servo has went way up.

Problem, the plastic geared servos will quickly wear out and will not be as precise as metal geared servos.

You should not connect a metal geared servo to directly to your Arduino; it's just a bad habit to get into and will bite you.

I supply metal geared servos with their own well regulated 5V 2+ amp source; tie grounds together. You can apply a bit more voltage for better torque to the metal geared servos.

Servo shoe horns attach to the metal geared servos, when the servo is driven to 1500uS, at an offset of 25uS. meaning that the servo will be at position 90 with either a 1475uS or a 1525uS torque sent to it; depending on mounting. First drive the servo to 1500, attach the shoe horn, and then figure out the adjustment angle. Write those values down for each servo. Leave the servo powered whiles you seat the shoehorn.

Have fun.

How many answers, thanks guys!
Sorry for the delay in the answer.
In the end the problem was just mechanical, I have this hub:

and I can screw it in 4 different positions, I thought they were all the same, but no.

Now I have this problem (see link): same servomotor, same configuration in attach, but one has a greater excursion than the other, why?

#include <Servo.h>

const int n_servo = 3;
Servo servo[n_servo];

void moveTo(int n_sync, int idx[], int degree[]){
  int count_success = 0;
  while(count_success < n_sync){
    count_success = 0;
    for(int i = 0; i < n_sync; i += 1){
      int pos = servo[idx[i]].read();

      if(pos < degree[i]){
        pos += 1;
      }
      if(pos > degree[i]){
        pos -= 1;  
      }
      if(pos == degree[i]){
        count_success += 1;
      } else {
        servo[idx[i]].write(pos);
      }
    }
    delay(10);
  }
}

int idx[] = {0};
int deg[] = {0};
void setup()
{
  servo[1].attach(4,570,2300);
  servo[2].attach(5,570,2300);

  deg[0] = 0;
  deg[1] = 0;
  deg[2] = 180;

  moveTo(3, idx, deg);
  delay(1000);
 
  deg[0] = 180;
  deg[1] = 180;
  deg[2] = 0;

  moveTo(3, idx, deg);
  delay(1000);
  
  deg[0] = 90;
  deg[1] = 90;
  deg[2] = 90;
  
  moveTo(3, idx, deg);
  delay(1000); 
}

iacoposk8:
How many answers, thanks guys!
Sorry for the delay in the answer.
In the end the problem was just mechanical, I have this hub:

and I can screw it in 4 different positions, I thought they were all the same, but no.

Now I have this problem (see link): same servomotor, same configuration in attach, but one has a greater excursion than the other, why?

#include <Servo.h>

const int n_servo = 3;
Servo servo[n_servo];

void moveTo(int n_sync, int idx, int degree){
  int count_success = 0;
  while(count_success < n_sync){
    count_success = 0;
    for(int i = 0; i < n_sync; i += 1){
      int pos = servo[idx[i]].read();

if(pos < degree[i]){
        pos += 1;
      }
      if(pos > degree[i]){
        pos -= 1; 
      }
      if(pos == degree[i]){
        count_success += 1;
      } else {
        servo[idx[i]].write(pos);
      }
    }
    delay(10);
  }
}

int idx = {0};
int deg = {0};
void setup()
{
  servo[1].attach(4,570,2300);
  servo[2].attach(5,570,2300);

deg[0] = 0;
  deg[1] = 0;
  deg[2] = 180;

moveTo(3, idx, deg);
  delay(1000);

deg[0] = 180;
  deg[1] = 180;
  deg[2] = 0;

moveTo(3, idx, deg);
  delay(1000);
 
  deg[0] = 90;
  deg[1] = 90;
  deg[2] = 90;
 
  moveTo(3, idx, deg);
  delay(1000);
}

Wow! You just discovered a fundamental law of mechanical engineering! Without FEEDBACK, you can never synchronize two or more motions.

Your only feedback is you eyeballs noticing the moving arms don’t keep up the same movement. No feedback to the servos.

If you actually expect this to work in synchronization, you must have one servo electronics control both motors, or design a system so the second servo is aware of the position of the first servo and adjust it’s movement to correspond to the first servo.

Paul

you are right! thanks for the answer.
in this product

seems 2 servomotors, which way have they chosen to manage the two engines in this project?

iacoposk8:
you are right! thanks for the answer.
in this product: Saldi 6DOF Metal RC Robot Arm abb Braccio robot industriale con 6 Servo Con / bluetooth Con - Banggood Array sold out-arrival notice-arrival notice

seems 2 servomotors, which way have they chosen to manage the two engines in this project?

If you expect people to go look at what you have posted, make it a clickable link.

If you want to know about some device, either by it and figure it out, or look at the documentation. A sales picture will not help anyone.

Paul