Making a Move

We have buttons and LED's available to the system so it's probably time to introduce some element of movement. One of the cheapest and easiest ways to do this is with a servo, typically a small geared electric motor with it's own built in control circuitry. A single digital control line commands the servo to drive to a specific angle and the servo monitors it's own position as it attempts to move to that angle as quickly as possible.

Servos are very versatile devices, you can get some basic 9g servos for only a few pounds each. Servos come in a range of standard rectangular sizes so they're easy to draw and have mounting points built into the plastic shells. If you require stronger/faster movement you can often buy a more expensive servo that fits into the same space and is controlled in exactly the same way so switching them over is incredibly easy.

Most servos are controlled through a standard three wire connection, two wires for power and GND, the third wire carries a PWM signal (the kind we previously used to dim our LED's). The amount of time the signal is on for controls the angle of the servo. A servo pulse of 1ms will set the angle of the servo to 0 degrees, 2ms will set the angle to 90 degrees. The pulse repeats every 20ms and the servo will constantly try to drive to the target angle. The gif above is not sped up and these little 9G servos (with metal gears) will be able to move through the full 90 degrees in just under half a second. The joy of the arduino environment is that somebody else has already written a library to generate these servo control signals.

The code to control a servo could be as simple as above. Include the servo library, define a servo that you're going to use, initialise the servo to use IO pin D5 and then in the main loop drive the servo between 0 and 90 degrees, waiting half a second between each new angle command. Obviously we should never use the delay function as previously discussed but it serves for this simple demo.

How do we know that the servo will take half a second to move between the two positions? We don't! We can set it up on the bench and time it but because there is no feedback from the servo we can never be sure how long it takes exactly, or even if it made it at all before it was asked to go to the next angle. This is the main limitation of this kind of servo control.


The arduino servo library is a great utility for the control of these devices, after being set up it simply takes an integer value for the angle and it converts it directly to the correct length of ms pulse. This means you can move the servo to any one of 90 different positions between the two angles, I may be a bit of a perfectionist but I feel you can actually see the jump between individual degrees. The library does actually allow you to set the millisecond value directly so instead of having 90 discrete steps you can control the servo with 1000 discrete steps, more than enough for the perfectionist it me.


I purchased these 9g servos through aliexpress, they are actually rated to turn through 180 degrees and I'm not ashamed to admit this took me longer than it should to work this out.
With regards to the servo timings and angles, it is more accurate to say a servo pulse of 1.5ms length will drive the servo to a neutral 'zero' angle. Change the pulse duration by +/- 0.5ms will change the angle of the servo by +/- 45 degrees. This makes it much easier to understand that these extended angle servos work over a larger range of pulse durations and +/- 1ms to the pulse changes the angle +/- 90 degrees. The change in the code should be as simple as adjusting the microsecond values?

The reason this doesn't immediately work is actually due to a safety feature of the arduino library. Imagine for a minute we try to drive the servo to an angle of 180 degrees using a 3500 ms pulse. This is well outside the specification and could ultimately result in the parts inside the servo running into their limits and trying to damage itself. To prevent this the arduino library limits the range of acceptable values that can be sent to the servo, anything over or under predefined values get limited to the minimum or maximum to stop that from happening.

Although it is not uncommon to use 0.5ms to 2.5ms signals for servos, the library defaults the safe values between 1 and 2ms. Because these are the defaults they aren't set at any point in our demo program. If we want to extend this range to create a wider range of movement it needs to be done at the point of initialisation.


So that is the basics of how a servo works and how to control it from the arduino directly. Next time I'll this to drive multiple servos and have better control over those servos too. I'll also bring in the gauges that I'm using in the final game to have something a bit more interesting to control.

Popular posts from this blog

Wiring the Ruida Controller

Toothless Dragon Cake

Laser Cut Cryptex