DIY Servo Motor

138K18167

Intro: DIY Servo Motor

DC Motors can be made to turn either clockwise or counter-clockwise by changing the polarity of the voltage applied to their terminals. The torque that is generated at the output shaft can be scaled up or scaled down by using a gear train. In most motors, like the one shown below, the gear train scales up the torque of the motor by using a reduction gearing that outputs a much higher torque (albeit at the cost of a much reduced output RPM).

The problem with DC motors is that when they have a voltage applied to their terminals, they tend to rotate forever in a particular direction, stopping or reversing the motor can only be achieved by cutting off electric supply or reversing polarity. In a DC Motor, speed control can be achieved by varying the terminal voltage but position control of the shaft is very difficult to implement.

Servo motors on the other hand, allow us to control the position (or angle) of the motor output shaft. This can be very useful when we want to move a control surface such as a rudder or a thruster to a particular position.

STEP 1: Dealing With Cost

Servo motors are expensive. They get more and more expensive as their output torque increases. Digital servos are even more expensive than analog ones and I am not sure that one can even buy servo motors with torques higher than about 30 kgf-cm.

I needed a servo motor that could generate 120 kgf-cm of torque for a robotics application. As you can see from my extrapolated price graph, this type pf servo would have cost me a few hundred dollars!

To get around this, I decided to make my own servo motor using a cheap (under 20$) DC motor and some simple electronics.....

STEP 2: How It Works...

In order to control the shaft position of a DC motor (and thereby convert it into a servo motor), you need to be able to ‘encode’ the position of the shaft. This ‘current position’ will be compared against an ‘desired position’ and a ‘positional error’ will be generated. Voltage applied to the motor terminals will be so as to cause the shaft to turn to reduce ‘positional error’ to zero. This sort of a ‘feedback’ system is also used in commercially available servo motors.

To implement the feedback loop you will need to fix the shaft of a rotary potentiometer to the foundation of the motor while allowing the potentiometer’s body to rotate freely with the motor shaft. This arrangement is known as a shaft encoder. Now, as the motor shaftrotates , there will be a corresponding angular movement between the potentiometer shaft and its body. By sensing the voltage at the wiper terminal of the potentiometer, you can measure the angular position of the motor shaft. This angle will then be fed into the feedback loop allowing software on a microcontroller to control the angular position of the motor shaft.

STEP 3: Circuit Diagram

I used Fritzing to create the circuit diagram for my DIY servo motor. You can download the circuit by clicking the link below.

To be able to turn the motor shaft in both directions, you will need to use a H-bridge IC like an L293N. Any microcontroller can be used to control the servo, in the circuit above, I use an Arduino Mega.

STEP 4: Code


Download the arduino sketch (customServo.ino) that controls the motor using the links below. Within the code is the c++ class DCMotor. This class has a member function GoToAngle(i,j) where 'i' is the desired angle of the shaft and 'j' is the turning speed of the motor. You can call GoToAngle() repeatedly or whenever required to bring the motor shaft to any desired angle. The code is heavily commented at every step so that it is easy to read.

The embedded video demonstrates the whole build process. The code shown in the video is of a slightly older version and is not the same as contained in customServo.ino

53 Comments

I'm wondering why can't we use the built-in Arduino Servo library to control this motor?
Otherwise it's a great and a very useful project, thanks!
The Arduino Servo library only sends PWM signals to the servo motor. All the necessary positional calculations are done by electronics inside the servo motor casing using a potentiometer linked to the output gear, much like the potentiometer in this project. So the only way to just use the Arduino Servo Library would be to rip open a servo motor, somehow connect the potentiometer to whatever high torque motor shaft you wanted to use and then I guess it would work.
so the Arduino you are using here 'let's call it Arduino (1)' is playing the role of the servo's electronics, and it needs another Arduino (2) to control the whole set (DC Motor + Arduino(1) + motor driver). Am I right?
I think this video clarifies what I mean.
thanks for you response.

I did not see the video, so this post may be redundant. I strongly recommend selecting a linear taper potentiometer. That is a pot where say a 5% turn results in a 5% change in resistance. This relationship holds for the entire sweep of the pot, and would make the correlation easier. Logarithmic taper or audio taper pots would hamper the resolution. I have seen home made optical encoders made using pie shaped or finer patterns printed on a clear sheet of plastic, cut into a disc . Then you are counting pulses. That approach suits my application because it allows continuous rotation and very good resolution.
Would this be controllable via a pwm rc receiver?
You would need to make some modifications to the code, but yes, it could be done. It's just a question of mapping the PWM signal to valid motor commands. You could analogRead() the PWM from the receiver and use Arduino's map() function to convert the PWM value to a valid motor order.

Hello vu2aeo,

Thnx for your code example, its was very helpfull! I changed your code a bit so it would work with my adafruit motorshield. It use it to just set the motor in a desired porsition. It works fine for angles higher than around 70 degrees but if the potentiometer is set at at lower angle than 70 degrees, the program freezes(altough the motor shaft keeps turning). For higher angels it works perfectly. Have you run into a similar problem?

Sorry, I'm starting to lose my patience. Please read the instructable properly. The circuit diagram and its software, source code, everything is given. I'm happy to try and clear any genuine questions you may have, but unfortunately it appears that you are not really trying to apply yourself.

Many potentiometers are designed for use in audio equipment and the resistance of the wiper is not linear at all. It may be logarithmic. So a change of 10 degrees angle will not translate to the same analog reading when the knob is at different positions.

I think this may be the problem you are facing.

You may need to manually check the wiper resistance values at different positions of the knob to verify if this is what is happening...

sir, tq for the tutorial...

but can i ask about how to control it multiple?

can i just use the signal(wiper) pin to put as input...?

I quite certain that would work......but you would need to remember to
poll BOTH the wiper pins every so often. You will need to modify the
code for this.

Poll?
Im sorry but i never heard the term... Cant really blame mr cause im new... I google but not found...
So... Erm... What is poll?
Ermm... Found it... Sorry...
Tq for reply and take your time...
(im not good with english)

hi there!

are you using the motor driver as H-Bridge( 4 quadrant) configuration or 2 quadrant operation?

Because i am thinking of controlling 2 servomotors with single motor driver.

I feel we can use 2 quadrant operation because we are not using braking.. only direction control.

Thanks!

I quite certain that would work......but you would need to remember to poll BOTH the wiper pins every so often. You will need to modify the code for this.

it is very useful. but where can i get the code of obey order that is showed in the video

I have a doubt...

I have done something like this project, but I have used a encoder. When I put some weight, the motor turn hot (like this is overworked for the change of sense in the turn of the motor). What can I do?

where is the custom servo.ino ??

More Comments