Note
Hello, welcome to the SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts Community on Facebook! Dive deeper into Raspberry Pi, Arduino, and ESP32 with fellow enthusiasts.
Why Join?
Expert Support: Solve post-sale issues and technical challenges with help from our community and team.
Learn & Share: Exchange tips and tutorials to enhance your skills.
Exclusive Previews: Get early access to new product announcements and sneak peeks.
Special Discounts: Enjoy exclusive discounts on our newest products.
Festive Promotions and Giveaways: Take part in giveaways and holiday promotions.
👉 Ready to explore and create with us? Click [here] and join today!
Lesson 33: Servo Motor (SG90)
In this lesson, you will learn how to control a servo motor (SG90) using the Raspberry Pi Pico W. You will be introduced to the concepts of Pulse Width Modulation (PWM) for controlling the angle of the servo motor. The lesson includes writing a MicroPython script to make the servo sweep smoothly through its entire range of motion, from 0 to 180 degrees and back.
Required Components
In this project, we need the following components.
It’s definitely convenient to buy a whole kit, here’s the link:
Name |
ITEMS IN THIS KIT |
LINK |
|---|---|---|
Universal Maker Sensor Kit |
94 |
You can also buy them separately from the links below.
Component Introduction |
Purchase Link |
|---|---|
Raspberry Pi Pico W |
|
Wiring
Code
import machine
import time
# Initialize PWM on pin 16 for servo control
servo = machine.PWM(machine.Pin(16))
servo.freq(50) # Set PWM frequency to 50Hz, common for servo motors
def interval_mapping(x, in_min, in_max, out_min, out_max):
"""
Maps a value from one range to another.
This function is useful for converting servo angle to pulse width.
"""
return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min
def servo_write(pin, angle):
"""
Moves the servo to a specific angle.
The angle is converted to a suitable duty cycle for the PWM signal.
"""
pulse_width = interval_mapping(
angle, 0, 180, 0.5, 2.5
) # Map angle to pulse width in ms
duty = int(
interval_mapping(pulse_width, 0, 20, 0, 65535)
) # Map pulse width to duty cycle
pin.duty_u16(duty) # Set PWM duty cycle
# Main loop to continuously move the servo
while True:
# Sweep the servo from 0 to 180 degrees
for angle in range(180):
servo_write(servo, angle)
time.sleep_ms(20) # Short delay for smooth movement
# Sweep the servo back from 180 to 0 degrees
for angle in range(180, -1, -1):
servo_write(servo, angle)
time.sleep_ms(20) # Short delay for smooth movement
Code Analysis
Importing Modules and Initializing Servo:
The
machinemodule is crucial for accessing the PWM functionality needed to control the servo, andtimeis used for implementing delays. The servo is initialized on pin 16 of the Raspberry Pi Pico W, setting its frequency to 50Hz, a typical value for servo control.import machine import time servo = machine.PWM(machine.Pin(16)) servo.freq(50)
Mapping and Servo Control Functions:
The
interval_mappingfunction translates the desired servo angle into a PWM pulse width. Theservo_writefunction then converts this pulse width into a duty cycle, which is used to set the servo’s position. These functions are central to converting the angular position into an appropriate PWM signal.Please refer to Work Pulse for information about the work pulse of the servo.
def interval_mapping(x, in_min, in_max, out_min, out_max): return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min def servo_write(pin, angle): pulse_width = interval_mapping(angle, 0, 180, 0.5, 2.5) duty = int(interval_mapping(pulse_width, 0, 20, 0, 65535)) pin.duty_u16(duty)
Main Loop for Continuous Movement:
The main loop is where the servo is controlled to sweep from 0 to 180 degrees and back. This is achieved by looping through the range of angles and calling
servo_writefor each angle, with a short delay to ensure smooth movement.while True: for angle in range(180): servo_write(servo, angle) time.sleep_ms(20) for angle in range(180, -1, -1): servo_write(servo, angle) time.sleep_ms(20)