How to Use a Servo Motor With the Raspberry Pi - Make Tech Easier

2022-09-03 23:36:13 By : Ms. Justin Chan

Pick up your jumper wires, we'll spin a servo motor with the Raspberry Pi!

DC motors are great, but it’s hard to make them control robotic hands and fingers. You just can’t get the angle right. But with servo motors, you can always be sure that they’ll stop at the right angle, all the time.

So pick up your jumper wires, we’ll spin a servo motor with the Raspberry Pi and make it stop at any angle!

Also read: How to Use Pushbuttons With Raspberry Pi GPIO Pins

A servo motor is a DC motor that lets you control its angle. You can set it to turn 90 degrees, stop, then back 90 degrees. They’re useful when you need precision on an automatically-moving part.

Inside a servo motor are three parts: a DC motor, a potentiometer, and a circuit that controls the motor.

The potentiometers in servo motors are resistors, just like the resistors you use when lighting up LEDs. The exception being they can change resistance values when you turn them.

In servo motors, the potentiometer is geared to the DC motor so that it would turn when the DC motor spins. This lets you know the motor shaft’s angle. The controller circuit tells it to stop when it reaches a certain angle.

With that in mind, using servo motors with the Raspberry Pi means you’re telling the controller circuit to spin the DC motor until it reaches a certain angle.

Also read: Raspberry Pi Monitor Not Working? Try These Fixes

Pulse Width Modulation (PWM) is the heart of this whole servo-moving thing. It’s a method of controlling the timing between pulse waves in a PWM signal.

As a more layman-friendly explanation, imagine the Raspberry Pi emitting 3.3V from pin 7. On an oscillator making a graph of voltage over time, that would make a plot on the 3.3V side which becomes a long line as time passes by. When it suddenly drops to 0V, the oscillator makes a vertical line to the 0V side. Then it makes a horizontal line from there over time.

That is called a pulse wave. PWM is when you control either the distance between two pulse waves (length of 0s) or the length of the pulse, itself (length of 1s). This is also known as a duty cycle. It’s what you change while using the ChangeDutyCycle() function.

PWM control is an important function in many microcontrollers, not just the Raspberry Pi. It lets you control and output so many other different stuff, all the while just using a tiny bit of electricity to work.

Also read: How to Program an Arduino with a Raspberry Pi

Servo wires can come in different colors depending on the manufacturer. Wire them to the Raspberry Pi like this:

The wire you’re connecting to pin 7 is the servo’s “signal” wire. This is connected straight to the controller circuit.

If you don’t have enough male-to-female jumper wires, you can make your own with a male-to-male and a female-to-female jumper wire connected together.

Tip: If you’re having trouble looking for pin 7, hold your Raspberry Pi in a way that the GPIO pins are placed on the right. Then starting from the top-left pin, that would be pin 1. To the right of it is pin 2. Below pin 1 is pin 3 and so on.

Tip: It’s easier to see the Raspberry Pi move when you place a piece of tape on it. But ideally, you should use the “horn” that comes with the servo straight from the box.

Also read: 10 Useful Python One-Liners You Must Know

In like in most of the other instructions we do, we’ll divide this code into four parts:

As always, these are not “standard” divisions. It’s just good practice to divide your code into smaller bits when programming things. That makes editing and debugging a lot more easier!

The import commands section is where you’re supposed to load your modules. Here, we’re using two modules: RPi.GPIO and time.

import RPi.GPIO as GPIO imports the RPi.GPIO module. This lets you control the black pins (GPIO) where you fit the code wires in. The latter part of this line, as GPIO, declares a new variable named GPIO. Here, GPIO will always mean RPi.GPIO unless changed in the later part of the code. You can replace GPIO with any other variable name you want!

from time import sleep is another way to import a module. But instead of importing the whole module, you’re just importing a part of it. Here, we just took the sleep part of the time module. This lets you use the sleep() function which pauses the code for a given amount of seconds.

Setup commands let you set up and define things before going to the looped part.

servoPin = 7 defines the variable servoPin and gives it the value 7. We’re using this to say that the pin for controlling the servo motor will be pin 7.

Why define a pin number? Sometimes, when you change your mind and think, say, you want to move it to pin 40, then it’s easier to change just one pin number than have to look for the number 7 all over your code.

GPIO.setwarnings(False) stops a warning message that comes out when you run a Python script that uses the GPIO pins. It’s set to “True” by default.

GPIO.setmode(GPIO.BOARD) defines which pinout you’re using. There are two types: BOARD and BCM. In BOARD, you’re defining pins based on where they are. Pin 1 is at the top left, pin 2 to its right, and so on.

On the other hand, BCM stands for “Broadcom” and picks pins based on their Broadcom SOC channel. This is a pin-specific number. Unlike BOARD, it’s easier to make mistakes with BCM because the pin number you’re gonna use changes based on which Raspberry Pi model you’re using.

GPIO.setup(servoPin, GPIO.OUT) defines pin 7, that pin we defined earlier as servoPin, and assigns it as an output pin.

pin7 = GPIO.PWM(servoPin, 50) is another variable we’re defining. GPIO.PWM(servoPin, 50) means that you’re making the output pin servoPin release a PWM signal. We’ll talk about PWM (Pulse Width Modulation) in a later part. But to sate some curiosity, PWM means you’re turning the pin on and off at regular intervals. The second part, 50, tells the pin to be turned on 50% of the interval, then turn off.

Lastly, pin7.start(0) makes pin 7 start doing the PWM thing, making it ready to go!

Programming complex code can be done in two ways: type and retype the same thing, over and over and over again, or type that thing once in a variable, and reduce ten lines of code into one line. The thing that makes that easier is called a “function” and no programmer in their right mind would favor the former over a nice function.

The functions in the function declarations part are actually just one giant “function in a function.” We’ll start at the bottom function first, sweep(), which uses the other function angleToDutyConvert() inside it.

def sweep(degrees): defines a function name, sweep, and gives it one parameter: degrees. We want this function to take an angle in degrees and sweep slowly until it reaches that angle. That’s while it prints out the current angle as it moves so you’d know how far it’s gone already.

Normally, servo motors will move to a target angle as fast as they can. So to make a servo motor “sweep” slowly, we’ll have to make it move and stop at a small angle until it reaches the target angle.

To do that, we need a for loop. The line for pos in range(0, degrees, +5): is a for loop that saves the current position in degrees to a variable, pos, and loops between the starting part of the range() function, 0, and the max value, degrees while incrementing by 5.

You can visualize it like this. The value for pos starts at 0. Then it moves by +5. The for loop checks if it’s still below the max value (the degrees part). If it’s not, then it starts doing what’s inside the loop then goes back to add +5 to pos. Since it used to be 0, the next value should be 0 + 5 = 5. It checks again and repeats until pos becomes either bigger or at the same level as degrees.

The next part does things in reverse. Starting from the value of degrees, the servo will move by -5 until the value of posgoes down to 0.

Now you may notice that each for loop has two lines, print(pos) and angleToDutyConvert(pos). The first one, print(pos), prints the value of pos into the console, which makes things easier to see. angleToDutyConvert(pos), on the other hand, is that custom function in our function.

Despite being written earlier, it’s easier to explain this after explaining what it’s going to be used in. angleToDutyConvert(angle) is a custom function, like sweep(degrees). So what’s this for?

Remember that sweep(degrees) takes in a number in degrees. That’s cool and all, but computers (and the servo’s controller circuit) don’t know what a “degree” is. But they do know duty cycles.

For most servo motors, they figure out the “angle” by listening to duty cycles. To convert a number from degrees to duty cycles, you should divide the angle by 18 and add 2 to the quotient. And that’s exactly what the line dutyCycle = angle / 18 + 2 is for.

Now the next part of the function does most of the legwork. GPIO.output(servoPin, GPIO.HIGH) turns pin 7 on, sending a signal to the servo motor. pin7.ChangeDutyCycle(dutyCycle) changes the duty cycle with that value you got from converting degrees to duty cycles. And then sleep(0.15) pauses the code for 0.15 seconds.

The last two parts, GPIO.output(servoPin, GPIO.LOW) and a second sleep(0.15), temporarily turn pin 7 off. They’re not much of a “vital” code, but they help with jittering, especially when you want the servo to hold its position.

Now it’s time to make things work. Using a while loop, you can turn the servo motor with the Raspberry Pi for as long as you want it to.

while True: is a while loop that never ends. Whatever you place inside it will get repeated forever, as long as you feed it electricity.

But the real MVP here is the sweep() function, which is that function we made earlier. You can add more of these to make the servo motor sweep at different angles. Just remember that whatever number you put between the parentheses, that’s gonna be the angle the servo will move in.

Also read: Python While Loop: Intro and Explanation

The red indicator LED lets you know if your Raspberry Pi is having enough electricity running through it. If it dies down while running a servo motor, then it’s probably running on low power. Servo motors need a lot of electricity to work, so you might want to use a proper power supply unit and not just a simple phone charger.

Most hobbyist servo motors can’t spin more than 180° at all. Asking it to spin a full 360° would be a stretch. But there are other servos that spin continuously. They’re called continuous rotation servos.

Jittering in servo motors can be due to a lot of reasons. Low power, code issues, or even just because you’re using a cheap one made from cheap parts. The gears could have been misaligned. Turning off the PWM signal when you want it to stay in place can help, though.

Our latest tutorials delivered straight to your inbox

How to Create a .Desktop File for Your Application in Linux

How to Cast Your Android Screen onto Your Linux Desktop

How to Fix 'No SIM Card Detected' Error on Android and iPhone

How to Install Safari on Linux

How to Access an Android Phone With a Broken Screen

How to Set Up Bluetooth in Linux

How to Use Google Authenticator on a Windows PC

6 Ways to Check Hard Disk Health in Windows

How to Fix Mobile Data Not Working on Android

6 Ways to Easily Send Text Messages (SMS) from Your PC

Affiliate Disclosure: Make Tech Easier may earn commission on products purchased through our links, which supports the work we do for our readers.

© 2022 Uqnic Network Pte Ltd. All rights reserved.