How to use MG90S Servo Motor with Raspberry Pi Pico using micropython

Posted

in

by

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 PicoServo Motor
GNDGND (Brown color wire)
VsysVCC (Red color wire)
GP9Signal (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 by
pwm.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)

Comments

One response to “How to use MG90S Servo Motor with Raspberry Pi Pico using micropython”

  1. John Milne Avatar
    John Milne

    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

Leave a Reply

Your email address will not be published. Required fields are marked *