servo position - coming at it from a different direction?!

I'm pushing an MG996R servo and find that when positioning to a given degree of rotation, the shaft stops at in a different place point depending upon whether it travels in CW or CCW direction. It's consistent and predictable - just that points arrived at CW and CCW aren't the same.

Let's say I want to reposition the shaft to destination 88deg. If the shaft starts from lower than the destination like at 78deg and I tell it to go to 88deg via servo.write(88) it will travel CW to a position I will call "A". But if the shaft position is higher than the destination like 104deg and I tell it to go to 88deg again via servo.write(88) it will go CW to a different position I will call "B". For me, "A" and "B" are very different positions yet both claim to be 88deg! I arrive at both via servo.write(88), and both report back "88" from servo.read(). Yet the positions are off by about 10deg!

Is this common knowledge? Or so folks just not expect such accuracy. I'd expect the server to know how to find like 88deg pretty accurately when twisting in either direction to get there. But seems not the case.

Comments? Advice?

I would try a better quality servo

Yes a better servo would help. This is caused by hysteresis in the servo’s gearing.

Grumpy_Mike: Yes a better servo would help. This is caused by hysteresis in the servo's gearing.

More likely in the potentiometer as it is usually down-stream of the gear train,

...R

I would say you are both right. Gearing and pot but also possible hysteresis in the controller. I know some servos have a pretty big controller hysteresis to eliminate jitter (at the cost of precision).

Is this common knowledge?

Yes! This is normal, expected and is fine in a servos normal application.

The problem lies with your assumptions about servo usage.

Mark

holmes4: Yes! This is normal, expected and is fine in a servos normal application.

I had forgotten that and I had only been explaining it to someone last week :)

...R

gtrMechanix: both report back "88" from servo.read().

Except that servo.read() has nothing to do with where the servo really is, it's merely telling you where you last commanded it to go; it's not a "report back" from the servo.

If you need to know where the servo really is, you need to tap the internal pot. You can try these from adafruit for instance, or try a hack like this instructable.

manor_royal: If you need to know where the servo really is, you need to tap the internal pot... these from adafruit for instance, or try a hack like this instructable.

Wow, now it makes sense. I have some CNC experience where setting x to 1.234 means x will position at 1.234 or die trying (assuming proper hardware of course). I could tell the term "servo" in each realm meant something fairly different, but I presumed accuracy would show up in the numbers.

The little servos I use seem accurate except for the hysteresis - once i dance around that in code it's less a mystery. But these links for adding a real feedback loop are great; I may try that.

I ordered some replacement servos of same model. I think that in addition to the hysteresis that there is a "dirty pot" thing going on - a glitchy-ness that grows over time, such that when I give successive advances like servo.write(88). servo.write(89). servo.write(90) that sometimes one will get skipped. It may position at 88, then no movement, then 90. The 88 and 90 are positionally accurate, but is as though it got lazy or confused on 89. It sweeps smoothly past 89 but does not stop there. this makes incremental movement weird when it just fails to take the next step but then takes two steps. I will check whether 1) a replacement servo fixes that which should indicate deterioration inside the server (a potentiometer for indexing?! really?!), and then 2) maybe I'll try the hacks to get actual feedback going and see what light that sheds.

but is as though it got lazy or confused on 89.

Perhaps you should take a peak at the Servo library. The library's primary means of writing to a servo is using writeMicroseconds(). write() maps the angle specified to some number of microseconds for the call to writeMicroseconds().

You can get better accuracy using writeMicroseconds() directly.

You can get better positional accuracy by overshooting and going back, if you are moving counterclockwise, but not if going clockwise. That way, all the backlash is the same every time.