Monthly Archives: November 2021

Servos Suck

At least the cheap analog ones do…

I’m working on a project that was envisioned to use up to 32 servos, and therefore a bought a bunch of cheap servos off of AliExpress for the prototype (there may be no production-type…). They were the infamous “Tower Pro SG90 9g” servo:

RC Mini Servo Tower Pro SG90 Micro Servo for RC 250 450 Helicopter Air  Plane Car Drop SG90 9G Micro Servo Motor For Robot RC|Parts & Accessories|  - AliExpress

The title says:

Mini SG90 9G 180 Degree Micro Servo Motor

Which sounded like what I wanted for my application, and they were cheap – also what I wanted – so I ordered 40 of them and waited for them to show up. Which they did in about 3 weeks, which was a bit surprising given the currently supply chain issues. While I wait, I do some coding.

I’m driving them using my Fade Animation System – one of the points of the project it to add servo support. To write that support, I read a few articles on servos and they all had an picture like this:
enter image description here

You can get what you want from a PWM subsystem if it’s a good one, and I’m running on the ESP32, so it’s a very good one.

It set up the PWM so that it runs at 50 Hz and 14 bits of resolution, so I get 0-16383 as my full counts. A little math tells me that 1 ms / 20 ms is 5% or 819, and 2 ms is 10%, or 1638. I code that up, look at the output on my scope, and it works as expected – I get nice 1ms and 2ms pulses at the extremes. And it works on my test servos – they nimbly go back and forth.

Along the way, I designed a little servo connector board:

image

The ESP32 has 16 PWM outputs so it will support 16 servos, and I had no desire to wire them together by hand.

When my big shipment of servos show up, I plug one in, write some code – in the Fade Language – and hook up a servo. My 180 degree servo works, very nicely going back and forth. For 90 degrees. I tested my code, played around with a few things, did some more extensive reading, and had my first insight.

The little 1ms – 2ms chart is just plain wrong. If you vary your pulse width from 1ms to 2ms, you will get servo movement, and it will probably be around 90 degrees, but there’s no actual standard. If you want to explore how far your servo will actually move, you will need pulses that are shorter than 1ms and longer than 2ms. How short and how long? That must be established experimentally – the counts that work on my SG90 servos are 350 and 2150 – that seems to give me full movement without a dead zone. It’s not assured that it will even be symmetrical at both ends of the scale.

I had to change the Fade servo support to allow the code to specify these two limit values. It turns out that was a good thing as there is no defined direction for servos as well; big width might mean clockwise or it might mean counter-clockwise. Neat.

That didn’t take long to figure out and the code was pretty simple to fix, but there was something else I discovered is true, at least for these servos…

180 degrees isn’t 180 degrees. The physical range of the servo is about 200 degrees, but when you drive it, 160 degrees is all that you get. Or all that I get with that specific servo, or likely this servo batch – some people say their Tower Pro SG90 servos go a full 180 degrees and others say they only go to 160 degrees the way that I do. I’m going to put that down to poor manufacturing tolerances in the electronics, but it could be that there are multiple factories assembling these things and they use slightly different parts.

There are digital servos that apparently are much better behaved. They not surprisingly cost a lot more.

There’s a nice article here that goes into most of this.