I have this MG90S small servo motor. It is supposed to go from 0° to 180°.
Because of their low cost, they have a short range which is less than 180°. Some go to 135°, 100° or 150°.
PWM signal required by servo to move.
Frequency = 50Hz
Time Period = 0.02 Second or 20 mili second
Pulse width range: 500us to 2500us
Properties of pulse width
At 500us pulse width the servo position will be 0°
At 2500us pulse width the servo position will be 180°
It is a good habit to check the servo controls before putting it in a project and make the adjustments in code or in hardware.
Hardware Connections
| Raspberry Pi Pico | Servo Motor |
|---|---|
| GND | GND (Brown color wire) |
| Vsys | VCC (Red color wire) |
| GP9 | Signal (Orange color wire) |
Most small and micro Servo operate from 5V to 6V.
If a servo is designed to operate at 3.3V always check it’s datasheet carefully.
Calculations
Raspberry pi pico has a 16 bit PWM controller.
This means we set its frequency to 50Hz bypwm.freq(50)This means that one oscillation has 65535 steps
65535 steps = 20 ms
First we convert angles to pulse width time
pulse width = angle/90 + 0.5
then we convert pulse width to step count
steps count = ( 65535 * pulse width ) / 20
Code
import machine
import utime
Led_pin = 25
LED = machine.Pin(Led_pin, machine.Pin.OUT)
# Configure the GPIO pin for PWM
pwm_pin = machine.Pin(9)
pwm = machine.PWM(pwm_pin)
# Set the PWM frequency to 50 kHz
pwm.freq(50)
# Debug Message Print
debug = 0
time_delay = 1/10
increment_step = 100
decrement_step = -200
'''
# Function: deg_to_time
# Parameters: deg : degree (0 - 180)
# Description: This function takes the degree and translates them
to Pulse Width time.
For a servo motor we have to use a pulse width of 500us to 2500us
'''
def deg_to_time(deg):
temp = ((deg/90)+0.5)
if debug:print("deg ",deg," to timems: ",temp)
return temp
'''
# Function: timems_to_duty
# Parameters: timems : pulse width time in milli second
# Description: This function takes pulse width duration of 500us to 2500us.
and generates a duty cycle value.
'''
def timems_to_duty(timems):
temp = 20/timems
temp1 = 65535/temp
if debug:print("timems to duty: ",temp1)
return temp1
'''
# Function: set_pwm
# Parameters: duty : duty cycle value (0 - 65535)
# Description: This function takes a duty cycle value and set it for the PWM.
'''
def set_pwm(duty):
pwm.duty_u16(int(duty))
if debug:print("duty cycle: ",duty)
def angle_to_pwm(angle):
set_pwm(int(timems_to_duty(deg_to_time(angle))))
while(1):
# sweep from 0 to 180
for _ in range(0,180,1):
angle_to_pwm(_)
utime.sleep(time_delay)
# sweep from 180 to 0
for _ in range(180,0,-1):
angle_to_pwm(_)
utime.sleep(time_delay)
your code for running an MG90S micro server motor does not control it do 180degrees in either direction, it does several complete revolutions then gradually slows down and changes direction before doing several revolutions in the opposite direction.
running it from a Pico W