Back to Hub | RP2040 MicroPython Lab
PWM Engine Active

Advanced Servo Motor & PWM Simulator

Explore 50Hz vs 100Hz PWM timing, variable rotation limits (90°–360°), speed physics interpolation, and live duty cycle calculations.

SVG Servo Actuator Visualizer Speed: 180°/s
SG90 / DIGITAL SERVO 50Hz • Max 180° CURRENT: 90.0° / TARGET: 90°
50Hz / 100Hz PWM Pulse Width Waveform Period: 20.0ms (50Hz)
1.50 ms
🎛️ Motor Specifications & Interactive Controls
90°
0° (Min) 90° (Mid) 180° (Max)
180 °/sec
10°/s (Slow Motion) 180°/s (Standard SG90) 500°/s (Instant/Fast)
🧮 Live PWM Calculation Breakdown
1. Period from Frequency:
T = 1000 / 50 Hz = 20.0 ms
2. Pulse Width Interpolation (0.5ms - 2.5ms):
Width = 0.5 + (90° / 180°) × (2.5 - 0.5)
Width = 1.50 ms
3. Duty Cycle & 16-Bit Register (duty_u16):
Duty % = 1.50ms / 20.0ms = 7.50%
duty_u16 = int(0.075 × 65535) = 4915
💡 Frequency Effect: Switching to 100Hz doubles the duty cycle fraction (7.5% at 50Hz vs 15.0% at 100Hz) to output the exact same physical pulse width!
🐍 Live MicroPython Driver Code RP2040 Executing
from machine import Pin, PWM
import time

# Configure PWM pin GP16
servo = PWM(Pin(16), freq=50)

def set_servo_angle(angle, max_angle=180):
  # Map 0° -> max_angle to 0.5ms -> 2.5ms
  pulse_ms = 0.5 + (angle / max_angle) * 2.0
  period_ms = 1000.0 / 50
  # Pulse: 1.50 ms / Period: 20.0 ms
  duty = int((pulse_ms / period_ms) * 65535)
  servo.duty_u16(4915)

# Command current target
set_servo_angle(90, 180)
📝 Concept Check Quiz
Why does a standard servo motor care about the absolute pulse width (e.g. 1.5ms) rather than the raw duty cycle percentage when determining its angle?