Introduction to SG90 Servo Motors
The SG90 is a compact positional servo motor designed for applications requiring precise angular positioning and holding capabilities. Servo mechanisms, derived from the Greek word for "slave," are systems that follow external commands to achieve desired motion parameters including position, velocity, and torque.
There are two main types of servo motors available:
- Digital Servos: These consist of a motor, reduction gears, and control circuitry. They maintain their position after receiving a single PWM signal.
- Analog Servos: Traditional servos that require continuous PWM signals to maintain position and control rotation speed.
SG90 Technical Specifications
- Recommended operating voltage: 5V
- Rotation range: 0° to 180°
- Operating weight: 9g
- Operating speed: 0.12 sec/60° at 4.8V
- Stall torque: 1.8 kgf·cm at 4.8V
Working Principle
Inside the servo, a reference voltage is established. When a PWM signal from a microcontroller enters through the signal line, it creates a DC bias voltage that compares with the internal reference voltage. The resulting voltage difference drives the motor driver chip, determining rotation direction. As the motor rotates, it turns a potentiometer through reduction gears, nullifying the voltage difference and stopping the motor at the desired position.
Wiring Configuration
The SG90 servo has three wires:
- Brown (or black): Ground (GND)
- Red: Power supply (5V)
- Orange (or yellow): Control signal (connected to microcontroller GPIO)
PWM Control Method
The SG90 is controlled using a PWM signal with a 20ms period. The pulse width varies from 0.5ms to 2.5ms, corresponding to a 0° to 180° rotation range. The relationship between pulse width and angle is linear.
Important note: Servos require time to reach their target position, with larger angular changes requiring more time. If commands are sent too quickly, the servo will respond to the latest command from its current position rather than completing the previous movement.
| Pulse Width (ms) | Angle (°) |
|---|---|
| 0.5 | 0 |
| 1.0 | 45 |
| 1.5 | 90 |
| 2.0 | 135 |
| 2.5 | 180 |
Implementation Code
The following code demonstrates how to control the SG90 servo using an STM32 microcontroller. A timer generates a 20ms PWM signal, and the angle is mapped to the corresponding pulse width.
servo_driver.h
#ifndef SERVO_DRIVER_H
#define SERVO_DRIVER_H
void initializeServo(void);
void setServoPosition(float position);
#endif
servo_driver.c
#include "stm32f10x.h"
void initializeServo(void)
{
// Enable peripheral clocks
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
// Configure GPIO pin for alternate function push-pull
GPIO_InitTypeDef gpioConfig;
gpioConfig.GPIO_Mode = GPIO_Mode_AF_PP;
gpioConfig.GPIO_Pin = GPIO_Pin_0;
gpioConfig.GPIO_Speed = GPIO_Speed_50MHz;
GPIO_Init(GPIOA, &gpioConfig);
// Configure timer for internal clock
TIM_InternalClockConfig(TIM2);
// Set up timer base configuration
TIM_TimeBaseInitTypeDef timerConfig;
timerConfig.TIM_ClockDivision = TIM_CKD_DIV1;
timerConfig.TIM_CounterMode = TIM_CounterMode_Up;
timerConfig.TIM_Period = 20000 - 1; // Auto-reload value for 20ms period
timerConfig.TIM_Prescaler = 72 - 1; // Prescaler for 1MHz clock
timerConfig.TIM_RepetitionCounter = 0;
TIM_TimeBaseInit(TIM2, &timerConfig);
// Configure PWM mode
TIM_OCInitTypeDef pwmConfig;
TIM_OCStructInit(&pwmConfig);
pwmConfig.TIM_OCMode = TIM_OCMode_PWM1;
pwmConfig.TIM_OCPolarity = TIM_OCPolarity_High;
pwmConfig.TIM_OutputState = TIM_OutputState_Enable;
pwmConfig.TIM_Pulse = 0; // Initial duty cycle
TIM_OC1Init(TIM2, &pwmConfig);
// Enable timer
TIM_Cmd(TIM2, ENABLE);
}
void setServoPosition(float position)
{
// Map angle (0-180) to pulse width (500-2500 microseconds)
TIM_SetCompare1(TIM2, (position / 180 * 2000) + 500);
}
main.c
#include "stm32f10x.h"
#include "delay.h"
#include "oled.h"
#include "servo_driver.h"
float currentAngle;
int main(void)
{
OLED_Init();
initializeServo();
while (1)
{
OLED_ShowNum(1, 1, currentAngle, 3);
setServoPosition(currentAngle);
currentAngle += 30;
if (currentAngle > 180)
{
currentAngle = 0;
}
Delay_ms(500);
}
}
Controlling 360° Continuous Rotation Servos
In addition to the 180° positional servo, there's also a 360° continuous rotation variant. Unlike the 180° servo, the 360° version cannot be positioned at specific angles. Instead, it controls rotation direction and speed. It also uses a 20ms PWM signal, but with different pulse width interpretations:
| Pulse Width (ms) | Rotation Behavior |
|---|---|
| 0.5-1.5 | Forward rotation, decreasing speed |
| 1.5 | Stopped |
| 1.5-2.5 | Reverse rotation, increasing speed |