Hobby Servos, also sometimes called Standard or Micro servos, are small boxy motors.

The size of the 'box' may vary but they always have three wires for power and control and the wires are connected together into one 3-pin plug

You might find a servo extender or 'extra long headers' helpful for plugging servos into breadboards:

Three pin Servo Extension Cable - 30cm / 12" long.
Stretch out your servo connections with this flexible servo extension cord. It has a 3 pin shrouded "male" connection to plug your servo into and then, 30cm later, a 3 pin...
$1.95
In Stock
5 pieces of Extra-long break-away 0.1 inch 16-pin strip male header
Breakaway header is like the duct tape of electronics, and this header is one better with extra long pins on both sides. This makes it great for connecting things together that...
$3.00
In Stock

Servos are a lot different than DC motors because while DC motors turn all the way around, standard servos only move back and forth about 180 degrees. But they can be controlled to rotate to a specific angle.

For more info on servos, check out this page.

Follow the diagram above to breadboard the circuit. These are the connections you'll make:

Pico

  • Pico pin 1 (GP0)  to servo yellow data wire
  • Pico GND to servo black/brown GND wire
  • Pico pin 5 (GP3) to mode button to GND
  • Pico pin 30 (RESET) to reset button to GND

Power

  • Power supply 5V+ to 47uF capacitor to GND
  • 5V rail to servo red/orange +V wire

Code

Copy the code from the element below, and paste it into a fresh file in Mu. Save the file to your Pico's CIRCUITPY drive as code.py It will automatically run the code!

Press the mode button to have the servo go directly to 0º, 90º, and 180º positions. Press the button a second time to have it smoothly sweep through its range.

# SPDX-FileCopyrightText: 2021 jedgarpark for Adafruit Industries
# SPDX-License-Identifier: MIT

# Pico servo demo
# Hardware setup:
#   Servo on GP0 with external 5V power supply
#   Button on GP3 and ground

import time
import board
from digitalio import DigitalInOut, Direction, Pull
import pwmio
from adafruit_motor import servo

print("Servo test")

led = DigitalInOut(board.LED)
led.direction = Direction.OUTPUT
led.value = True


def blink(times):
    for _ in range(times):
        led.value = False
        time.sleep(0.1)
        led.value = True
        time.sleep(0.1)


# Mode button setup
button = DigitalInOut(board.GP3)
button.direction = Direction.INPUT
button.pull = Pull.UP
mode = -1  # track state of button mode

# Servo setup
pwm_servo = pwmio.PWMOut(board.GP0, duty_cycle=2 ** 15, frequency=50)
servo1 = servo.Servo(
    pwm_servo, min_pulse=500, max_pulse=2200
)  # tune pulse for specific servo


# Servo test
def servo_direct_test():
    print("servo test: 90")
    servo1.angle = 90
    time.sleep(2)
    print("servo test: 0")
    servo1.angle = 0
    time.sleep(2)
    print("servo test: 90")
    servo1.angle = 90
    time.sleep(2)
    print("servo test: 180")
    servo1.angle = 180
    time.sleep(2)


# Servo smooth test
def servo_smooth_test():
    print("servo smooth test: 180 - 0, -1º steps")
    for angle in range(180, 0, -1):  # 180 - 0 degrees, -1º at a time.
        servo1.angle = angle
        time.sleep(0.01)
    time.sleep(1)
    print("servo smooth test: 0 - 180, 1º steps")
    for angle in range(0, 180, 1):  # 0 - 180 degrees, 1º at a time.
        servo1.angle = angle
        time.sleep(0.01)
    time.sleep(1)


def run_test(testnum):
    if testnum is 0:
        servo_direct_test()
    elif testnum is 1:
        servo_smooth_test()


while True:
    if not button.value:
        blink(2)
        mode = (mode + 1) % 2
        print("switch to mode %d" % (mode))
        time.sleep(0.8)  # big debounce
        run_test(mode)

How It Works

Libraries

First, the libraries are imported for time so it can pause, board for pin definitions, digitalio to use buttons, pwmio for Pulse Width Modulation (PWM), and the servo module from adafruit_motor for easy servo motor control.

import time
import board
from digitalio import DigitalInOut, Direction, Pull
import pwmio
from adafruit_motor import servo

LED

The on-board LED is set up and turned on to show that the code is running, and will blink when the button is pressed.

led = DigitalInOut(board.LED)
led.direction = Direction.OUTPUT
led.value = True


def blink(times):
    for _ in range(times):
        led.value = False
        time.sleep(0.1)
        led.value = True
        time.sleep(0.1)

Button

The button is set up on pin GP3 as an input with internal pull up resistor. When the button is pressed the mode variable will increment to set the servo test state.

button = DigitalInOut(board.GP3)
button.direction = Direction.INPUT
button.pull = Pull.UP
mode = -1  # track state of button mode

PWM & Servo

The PWM pin is used to control the servo angle. PWM is a digital approximation of an analog signal, allowing a smooth-ish range of varying control to be specified for the motor speed.

The PWM output will be set to pin GP0, duty cycle to half of the full 65,535, and PWM frequency of 50Hz.

The servo object is then created, specifying the PWM pin and the minimum and maximum pulse values for the servo - in microseconds. (This can vary from servo to servo, see datasheets or ask your vendor for details.)

pwm_servo = pwmio.PWMOut(board.GP0, duty_cycle=2 ** 15, frequency=50)
servo1 = servo.Servo(
    pwm_servo, min_pulse=500, max_pulse=2200
)

Servo Test Functions

The servo can be controlled to go directly to a particular angle by sending servo.angle commands.

This first function allows us to easily test sending the servo directly to 90º, 0º, and 180º.

The second function steps smoothly to an angle in 1º increments.

# Servo test
def servo_direct_test():
    print("servo test: 90")
    servo1.angle = 90
    time.sleep(2)
    print("servo test: 0")
    servo1.angle = 0
    time.sleep(2)
    print("servo test: 90")
    servo1.angle = 90
    time.sleep(2)
    print("servo test: 180")
    servo1.angle = 180
    time.sleep(2)


# Servo smooth test
def servo_smooth_test():
    print("servo smooth test: 180 - 0, -1º steps")
    for angle in range(180, 0, -1):  # 180 - 0 degrees, -1º at a time.
        servo1.angle = angle
        time.sleep(0.01)
    time.sleep(1)
    print("servo smooth test: 0 - 180, 1º steps")
    for angle in range(0, 180, 1):  # 0 - 180 degrees, 1º at a time.
        servo1.angle = angle
        time.sleep(0.01)
    time.sleep(1)

This guide was first published on Feb 17, 2021. It was last updated on Nov 29, 2023.

This page (Servo Motors) was last updated on Nov 29, 2023.

Text editor powered by tinymce.