Servo Accuracy

so i found a problem about accuracy of servo motor (TowerPro MG996R), the very clear factor is i think i use very cheap motor, here in Indonesia i bought those MG996R with price around 40K-60K IDR which around 4-5 in US$, and second i also use cheap CH340 UNO board. then the problem itself is the accuracy of angular position of the servo with "sweep" code from included Arduino example files which the code mean operating the servo with movement of rotate from 0 to 180 degree and back to 0 again in loop. so when i upload this code the actual rotation of my MG996R is exceed 180 degree, somewhere around 205 degree (in real condition the servo is rotate 0-205 degree).

what analysis about this problem, is it really the quality factor of cheap servo and board i use? is there any guarantee if i use ATMega UNO boards and higher quality servos with the included Ardunio servo library the sweep code will run exactly 0-180-0 in accurate actual result? or maybe there are solution to fix this without changing my hardware, maybe using other libraries?

is there any guarantee if i use ATMega UNO boards and higher quality servos with the included Ardunio servo library the sweep code will run exactly 0-180-0 in accurate actual result?

No

You can, however, set the range of pulse widths, and hence the movement end points used by a sketch when writing to a servo. See https://www.arduino.cc/en/Reference/ServoAttach

Using writeMicroseconds() instead of write() will also give you more steps for a given range of servo movement but the program can do nothing to improve the mechanical accuracy or range of movement of a servo.

It's easy to misunderstand servo.write(angle). Using angles of 0 to 180 isn't really intended to give specific angles even though it does seem like that. write(0) just means travel as far as possible in one direction and write(180) means go to the maximum travel in the opposite direction. For some servos that may be only 120 degrees and for others it may be 200 or more (for a winch servo 0 - 180 may be 5 or 6 full rotations, over 1000 degrees of travel).

Basically if you want accurate positioning you need to calibrate the movements of your particular servo, as UKHeliBob suggests, using servo.attach and preferably writeMicrseconds().

Steve

+1 to the idea of using the min and max optional parameters for the servo.Attach()

Instead of

 myservo.attach(9);

or whtever pin number you are using, try using something like this

 myservo.attach(9, 1000, 2000);

You might need to play with the actual min and max parameters a bit to find what best gives you 180 degrees of movement.

You'll, also, find out that over time, about a weeks worth of continuous operation, those plastic geared servos become less accurate as the plastic gears wear down.

I switched to using stepper motors instead, cheap 28BYJ48 has 4075 half-steps for 360° rotation, that is 11.3 steps per degree and not only 1 step per degree of rotation of a servo.

Here I used full-stepping, and even with that one revolution did lift microscope 18mm, which is 8.8µm(!) per step: https://forum.arduino.cc/index.php?topic=649270.msg4642265#msg4642265

This is animation with microscope moving 8.8µm in a single step between 1360x768 screenshots: (the camera preview has resolution 0.21µm per pixel, shows center part of 12MP frame) |500x282