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:
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)
Page last edited January 22, 2025
Text editor powered by tinymce.