In a previous post I wrote about controlling DC motors using an inexpensive integrated circuit. In this post I will explain how you can use a Micro:Bit to control a servo motor (like those used for steering in radio controlled cars) with no extra electronics (other than a secondary power supply)
Servos are a great way of adding another physical dimension to physical computing projects.
In this brief shot, one of our students demonstrates his Micro:Bit controlled (not quite) walking robot, which is powered by servos, to David Cameron at 10 Downing Street.
The process for controlling servos is a little bit peculiar. This is because these ‘hobbyist’ devices pre-date digital electronics.
Servos generally have 3 wires. A control / data line, and two for power supply (+ve and ground)
Servo motors are designed in such a way that the position of the “servo horn” is determined by the ratio of on time and off time in an (approximately) 20 microsecond pulse.
Most servos have 180 degrees of rotation. Lets say a 20 ms pulse begins, we make our data line “on” or “high” for 1.5 ms. (A pulse must always begin with the leading edge of a high).
This would tell our servo to move to the centre (90 degrees). 2 ms would move it to its full extent clockwise (180 degrees) and 1 ms would move it to its least most extent (0 degrees). For the remainder of the “pulse” the signal should be low.
Therefore, varying the length of the on time between 1.000 ms and 2.000 ms will allow us to move the servo to any position we want.
We cannot use the microbit “delay” function to achieve this level of accuracy. It’s lowest resolution is 1ms therefore we can only use it at best to move the servo either all the way one way or all the way in the other but nothing in-between.
Fortunately it is possible by taking advantage of the analogue output of the Micro:Bit. This analogue out is not true analogue, it is pulse width modulation.
With PWM we send a series of high speed on off pulses. The ratio of on to off time makes it appear to receiving electronics that it is receiving varying voltage levels.
We can take advantage of this feature (credit goes to Andy Huntington at Microsoft for this method)
Let’s assume we have 2 battery packs, a standard 2XAA battery pack for the MicroBit and a second batt(4xAA)ery pack to power the servo.
To connect it up, do the following.
- Cut the plug off the end of the servo wire, separate the 3 wires and strip the insulation from the ends.
- Connect the ground wire from the servo (usually blue / black) to the negative / ground wire from the 4xAA battery pack.
- Connect the +’ve wire from the servo (usually red / orange) to the +’ve wire from the 4xAA battery pack. Important – you MUST insulate this +’ve connection with insulation tape and make sure there is no chance of a short. If you short out the connections from even 4xAA batteries it can generate enough heat to cause a nasty skin burn.
- Connect the ground on the Micro:Bit to the negative / ground connection between 4xAA battery pack and relay. Now insulate this joint too.
- Finally, connect the control wire from the servo (yellow or similar) to one of the Micro:Bit GPIO pins (lets say, pin 0).
We should be able to control the servo now with a few simple lines of code. In Touch Develop:
- Analog write pin 0 (512)
- Analog set period pin 0 (20,000)
This sets up the PWM period of the micro:bit to correspond with the expected 20 ms pulse width.
Now we can write “analogue” values to pin 0, between 35 and 135 (ish) will allow the micro:bit to instruct a servo to any position between 0 and 180 degrees.
Here is a screenshot of one of my test programs controlling a servo attached to pin 0.