Raspberry Pi Servo Motor control
In addition to stepper motors, there are also small and cheap servo motors. The control of Raspberry Pi servo motors is very simple and thanks to the small size and weight they are used in many areas.
Unlike stepper motors, servomotors can be controlled with a single GPIO.
In this tutorial, I’ll show an example of how to use Python to control one or more servo motors.
Required Hardware Parts
- Servo motor
- Jumper cable
- if necessary, a battery holder + (rechargeable) batteries, as an external power supply
Of course, it is possible to supply the servo motor with an external power source, but this only makes sense when using several motors. For that, rechargeable batteries/regular batteries would still be needed.
In most cases, the colors of the servo are as follows and are connected to the Pi:
Black – comes to GND (pin 6) from the Pi
Red – comes to 3V3 (pin 1) from the Pi
Yellow/Orange – to a free GPIO pin (e.g., GPIO17, pin 11)
If you want to play it safe, you can set a ~ 1kΩ resistor between the data pin (yellow/orange) and the Pi. Normally this is not necessary.
If the servo motor does not rotate correctly, this may also influence the power supply of the Raspberry Pi (just look at the datasheet, what the engine consumes). In such a case an external power source makes sense (usually it is 4 to 6V).
Software for controlling the Raspberry Pi servo motors
Unlike stepper motors, servo motors don’t occupy many GPIO pins to command a movement. For this, the rotation is controlled by the length of the pulse.
We either start python (
sudo python) or open a new script (
sudo nano servomotor.py) with the following content:
import RPi.GPIO as GPIO import time servoPIN = 17 GPIO.setmode(GPIO.BCM) GPIO.setup(servoPIN, GPIO.OUT) p = GPIO.PWM(servoPIN, 50) # GPIO 17 for PWM with 50Hz p.start(2.5) # Initialization try: while True: p.ChangeDutyCycle(5) time.sleep(0.5) p.ChangeDutyCycle(7.5) time.sleep(0.5) p.ChangeDutyCycle(10) time.sleep(0.5) p.ChangeDutyCycle(12.5) time.sleep(0.5) p.ChangeDutyCycle(10) time.sleep(0.5) p.ChangeDutyCycle(7.5) time.sleep(0.5) p.ChangeDutyCycle(5) time.sleep(0.5) p.ChangeDutyCycle(2.5) time.sleep(0.5) except KeyboardInterrupt: p.stop() GPIO.cleanup()
If the servo motor shakes a bit while it is not moving, you can pause the pulse with
For servo motors and their driver boards, the indication of the period and the duty cycle is usually made in the datasheet. In the example of a MG996R we have the following: The period is 20ms long. In addition, a duty cycle of between 5% and 10% of the period is expected. Thus the pulse duration is between 1ms and 2ms. Usually, servos can rotate between 0 and 180°. So we have to adjust the pulse length in between. A length of 1.5ms (7.5%) thus gives an angle of 90 °. And all at precisely 50x per second (50Hz).
If it bothers you that the servo (SG90) can not rotate 360 °, there is a “hack“.