Home > Industry Insights >Servo
TECHNICAL SUPPORT

Product Support

PWM Signal Control for Servo Motors: A Complete Programming Guide

Published 2026-04-02

This guide explains how to control a standardservomotor using Pulse Width Modulation (PWM) signals. You will learn the exact PWM parameters (period, pulse width,duty cycle) needed to set aservoto any angle from 0 to 180 degrees. The instructions are based on widely available microcontroller platforms and have been verified with common 50Hz analog and digitalservos used in hobby robotics. By following the step‑by‑step code examples and calibration methods, you can reliably position a servo without jitter or drift.

01Core PWM Parameters for Servo Control

A standard servo motor expects a PWM signal with the following fixed characteristics:

Signal period: 20 ms (milliseconds), which equals a frequency of50 Hz.

Pulse width (high time): varies between1.0 msand2.0 ms.

Duty cycle= (pulse width / 20 ms) × 100%.

Desired servo angle Pulse width Duty cycle (approx.)
0° (minimum) 1.0 ms 5.0%
90° (neutral) 1.5 ms 7.5%
180° (maximum) 2.0 ms 10.0%

Note: Some servos may accept 0.5 ms to 2.5 ms for extended range, but the standard 1.0–2.0 ms works for nearly all common servos.

02Programming PWM Output – Step by Step

The following code structure works on any platform that provides hardware PWM (e.g., Arduino, STM32, ESP32, Raspberry Pi with hardware PWM). We use generic pseudocode so you can adapt it to your specific microcontroller.

2.1 Set up the PWM peripheral

Choose a PWM‑capable pin.

Set PWM frequency to50 Hz(period = 20 ms).

Set resolution to at least 8‑bit (0–255) or 16‑bit for finer control.

2.2 Convert desired angle to duty cycle value

For an 8‑bit PWM (0 = 0% duty, 255 = 100% duty):

Duty cycle for 1.0 ms = (1.0 / 20.0) × 255 = 12.75 → round to13

Duty cycle for 1.5 ms = (1.5 / 20.0) × 255 = 19.125 → round to19

Duty cycle for 2.0 ms = (2.0 / 20.0) × 255 = 25.5 → round to26

General formula for any angle (0–180°):

pulse_width_ms = 1.0 + (angle / 180.0)(2.0 - 1.0) duty_value = (pulse_width_ms / 20.0)(2^resolution - 1)

Example for 8‑bit resolution and 45°:

舵机pwm控制源码_pwm控制舵机程序_pwm波控制舵机转动程序

pulse_width_ms = 1.0 + (45/180)1.0 = 1.25 ms

duty_value = (1.25/20)255 = 15.9375 → integer16

2.3 Write the duty value to the PWM register

// Pseudocode pwm_set_frequency(PWM_PIN, 50); // 50 Hz pwm_set_resolution(PWM_PIN, 8); // 8-bit int angle = 90; // target angle int duty = map(angle, 0, 180, 13, 26); // using pre‑computed min/max duty pwm_write(PWM_PIN, duty);

2.4 Real‑world calibration (eliminates jitter)

Because no two servos are exactly identical, always measure the actual pulse width limits:

1. Write a 1.0 ms pulse – observe the servo position. If it does not reach the physical stop, increase pulse width in 0.05 ms steps until it stops moving (record asmy_pulse).

2. Write a 2.0 ms pulse – similarly find the maximum pulse width that gives full rotation (max_pulse).

3. Use these measured values in your code instead of the theoretical 1.0/2.0 ms.

Common case: A typical Tower Pro SG90 micro servo requiredmin_pulse = 0.9 msandmax_pulse = 2.1 msfor a true 0–180° range. Always calibrate per servo model.

03Complete Example Code (Arduino‑style, hardware independent)

// Servo control using PWM – no external libraries required // Works on any board with hardware PWM (e.g., Uno, Nano, Mega, ESP32) const int servoPin = 9; // PWM pin const int freq = 50; // 50 Hz const int resolution = 8; // 8-bit (0-255) // Pre‑calibrated pulse limits (in microseconds) const int minPulseUs = 1000; // 1.0 ms = 1000 µs const int maxPulseUs = 2000; // 2.0 ms = 2000 µs void setup() { // Configure PWM ledcSetup(0, freq, resolution); // channel 0 ledcAttachPin(servoPin, 0); } void setServoAngle(int angle) { // Constrain angle to 0-180 angle = constrain(angle, 0, 180); // Convert angle to pulse width (microseconds) int pulseUs = minPulseUs + (angle(maxPulseUs - minPulseUs)) / 180; // Convert pulse width to duty cycle (0-255) int duty = (pulseUs255) / 20000; // 20000 µs = 20 ms period ledcWrite(0, duty); } void loop() { setServoAngle(0); // move to 0° delay(1000); setServoAngle(90); // move to 90° delay(1000); setServoAngle(180); // move to 180° delay(1000); }

04Troubleshooting Common PWM Servo Issues

Problem Most likely cause Solution
Servo does not move Wrong PWM frequency (not 50 Hz) Set frequency to exactly 50 Hz
Jerky / twitching motion Insufficient power supply Use a separate 5V supply (e.g., 4×AA batteries or 5V/2A regulator)
Inaccurate angles Theoretical pulse limits differ from actual servo Perform calibration (step 2.4) and use measured min/max pulses
Servo hums but doesn’t turn Duty cycle resolution too low (Increase PWM resolution to 10‑bit or 12‑bit
Only moves between 0° and 90° Signal period too short or pulse width range mismatched Verify period = 20 ms, and that you send pulses between 1.0–2.0 ms

05Actionable Recommendations for Reliable Servo Control

1. Always calibrate each servo individually– even two servos of the same model can have ±0.1 ms variation. Write a simple test sketch that sweeps from 0.5 ms to 2.5 ms and note the exact pulse widths for 0° and 180°.

2. Use a separate power supply– never power a servo directly from your microcontroller’s 5V pin (current spikes can reset the board). A 5V/2A regulated supply or 4×NiMH batteries (4.8V) works reliably.

3. Add a 100–470 µF electrolytic capacitoracross the servo’s power terminals close to the servo. This absorbs voltage dips caused by sudden motor starts.

4. Avoid software delayswhile the servo is moving. Use non‑blocking timing (e.g., millis()‑based state machines) so your program can handle other tasks.

5. For high‑precision applications (e.g., robotic arms), use a 16‑bit PWM timer and linear interpolation between calibrated points. Also consider adding a 10‑bit analog feedback potentiometer to close the loop.

Core takeaway: Controlling a servo with PWM is straightforward once you fix the frequency at 50 Hz and map the angle to a 1.0–2.0 ms pulse width. However, real‑world reliability comes from proper calibration, adequate power, and using measured limits rather than theoretical values. Apply the calibration method described in section 2.4 to every new servo you integrate, and your projects will achieve smooth, accurate motion every time.

Update Time:2026-04-02

Powering The Future

Contact Kpower's product specialist to recommend suitable motor or gearbox for your product.

Mail to Kpower
Submit Inquiry
+86 0769 8399 3238
 
kpowerMap