Servo motors are a type of motor commonly used in robotics and mechatronics for precise position control. Unlike DC motors that rotate continuously, servo motors can be commanded to move to specific angular positions.
Precise angular control (typically 0-180 degrees)
Built-in position feedback mechanism
High torque for their size
Commonly used in robotics, RC vehicles, and automation
Servo motors use a control circuit to maintain their position. The basic components of a servo motor include:
DC motor
Gearbox
Potentiometer for position feedback
Control circuit
The servo receives a PWM (Pulse Width Modulation) signal that tells it what position to maintain. This ties in directly with our previous lesson on DC motor control using PWM!
Detailed Explanation
Concise Explanation
Understanding servo specifications is crucial for effective mechatronic design. Key parameters to look for include:
operating voltage
PWM requirements
torque
speed
range of motion
weight
dimensions
Knowing these specs helps in choosing the right servo, powering it correctly, writing accurate control code, and designing mechanisms within the servo's capabilities.
You can see the PWM period for our SG90 servos is 20ms (50Hz).
The pulse width determines the angle:
~1ms pulse: 0 degrees (all right)
~1.5ms pulse: 90 degrees (center)
~2ms pulse: 180 degrees (all left)
For this lesson, we'll be using the Micro:bit GPIO Expansion Board.
Here's how to wire it up:
Connect the power wire (red) to the 5V pin on the expansion board
Connect the ground wire (brown) to the GND pin
Connect the signal wire (orange) to the P0 pin
The USB cable will provide 5v to the GPIO board. This will then provide the neccessary 5v to the servo. Do not run the servo from the micro:bit.
The GPIO board can be attached to a breadboard to make wiring easier. For this project you may like to attach the servo directly to the board.
from microbit import *
pin0.set_analog_period(20) # Set PWM Period
while True:
pin0.write_analog(50) # Full Right
sleep(1000)
pin0.write_analog(100) # Full Left
sleep(1000)
Why do we use the values 50 and 100?
There are two key things you need to know when using the 'analog' pins on the microbit to control PWM signals:
set_analog_period(value) - sets up the frequency of the PWM signal
write_analog(value) - takes values from 0 to 1023. These values represent the duty cycle of the PWM signal.
pin0.set_analog_period(20) - This sets up a 20ms period (50Hz frequency) for the PWM signal.
In the write_analog() function, the micro:bit maps the 0-1023 range to the 0-20ms period linearly. So:
0 corresponds to 0ms pulse width
1023 corresponds to 20ms pulse width
To get a 1ms pulse to make the servo go full right (0 degrees):
1ms / 20ms = 5%
5% of 1023 = 51
We run pin0.write_analog(50) which is close approximation of 51
To get a 2ms pulse to make the servo go full right (0 degrees):
2ms / 20ms = 10%
10% of 1023 = 102
We run pin0.write_analog(100) which is close approximation of 100
Rotate the servo left when button A is pressed, and right when button B is pressed.
Use button_a.is_pressed() and button_b.is_pressed() to detect button presses.
Remember to set up your pin for servo control with pin0.set_analog_period(20).
Use pin0.write_analog(value) to control the servo position.
Initialize servo pin
Set analog period
While true:
If button A is pressed:
Rotate servo left
Else if button B is pressed:
Rotate servo right
Wait for a short time
Make the servo smoothly sweep left and right using a loop.
Use a for loop to gradually change the servo position.
Remember to include small delays between position changes for smooth movement.
Initialize servo pin
Set analog period
While true:
For position from left to right:
Set servo to position
Wait for a short time
For position from right to left:
Set servo to position
Wait for a short time
Write a rotate_servo(pin, angle) function to simplify your code and help with future projects.
The function should take a pin object and an angle (0-180) as parameters.
Convert the 0-180 degree range to the servo's range for write_analog.
Remember to handle cases where the input angle might be outside the range.
rotate_servo(pin, angle):
If angle < 0:
Set angle to 0
If angle > 180:
Set angle to 180
Calculate servo value from angle
Write analog value to pin