How to control a servo motor with Raspberry Pi 4

What is a Servo motor?

A servomotor or servo is an electromechanical device that allows very precise control of the speed and angular displacement of its axis, generally limited to 180 degrees. It is mainly composed of a DC motor, a speed reducer, a shaft, a control circuit, and a feedback mechanism, usually a potentiometer.

How does a Servo motor work?

A microcontroller, for example a Raspberry Pi 4, sends an electrical pulse (PWM) to the servomotor. This reads the amplitude of the pulse, through its control circuit, and drives the DC motor. The speed reducer starts up. The rotation of the shaft turns the potentiometer knob changing its output voltage. This value is used by the control circuit to calculate the position, direction and angular velocity of the shaft.

Next we will see how to rotate a servomotor 180 degrees using a Raspberry Pi 4.

Hardware required

For this project we will use a Raspberry Pi 4 and a Sunfunder 9g SG90 Micro Servo.

Sunfunder 9g SG90 Micro Servo.

Circuit wiring

Servo motors typically come with three different colored wires: orange for control; red for power; and brown for ground.

Connect the servo motor cables to the Raspberry pins as follows: the orange cable to GPIO pin 23; the black wire with any of the GND pins; and the red wire with the 3.3V pin.

Python code to rotate a servo 180 degrees back and forth

import RPi.GPIO as GPIO
import time

SERVO_MIN_PULSE = 500
SERVO_MAX_PULSE = 2500
Servo = 23

def map(value, inMin, inMax, outMin, outMax):
    return (outMax - outMin) * (value - inMin) / (inMax - inMin) + outMin

def setup():
    global p
    GPIO.setmode(GPIO.BCM)       
    GPIO.setup(Servo, GPIO.OUT)  
    GPIO.output(Servo, GPIO.LOW) 
    p = GPIO.PWM(Servo, 50)     
    p.start(0)                    

def setAngle(angle):      
    angle = max(0, min(180, angle))
    pulse_width = map(angle, 0, 180, SERVO_MIN_PULSE, SERVO_MAX_PULSE)
    pwm = map(pulse_width, 0, 20000, 0, 100)
    p.ChangeDutyCycle(pwm)
def loop():
    while True:
        for i in range(0, 181, 5):   
            setAngle(i)    
            time.sleep(0.002)
        time.sleep(1)
        for i in range(180, -1, -5): 
            setAngle(i)
            time.sleep(0.001)
        time.sleep(1)
def destroy():
    p.stop()
    GPIO.cleanup()

if __name__ == '__main__':    
    setup()
    try:
        loop()
    except KeyboardInterrupt:
        destroy()

Code by SunFounder

To run the code, go to the Raspberry Pi OS desktop. Click on the Raspberry menu > Programming > mu. Copy and paste the code. Click Save and save the file with a .py extension. Finally, click Run.

Leave a Comment

Scroll to Top