Learn
Controlling an SG90 Micro Servo with a Raspberry Pi 4B
Wire an SG90 micro servo to a Raspberry Pi 4B GPIO pin and sweep it through a range of angles with real PWM in Python — no hardware required.
Note: the SG90 Micro Servo is a Premium-tier component in the simulator — you’ll need a Premium or VIP plan to use it there.
Try this directly in the free Raspberry Pi 4B simulator — no hardware or signup required. New to the GPIO header? Start with the interactive pinout guide.
What you’ll need
- Raspberry Pi 4B
- SG90 Micro Servo
Step by step
- Drag Raspberry Pi 4B onto the Canvas.
- Drag the SG90 Micro Servo onto the Canvas (it won't mount into a breadboard — that's expected, real servos connect via loose wires, not legs).
- Hover over the servo's 3 pins to confirm their labels: Signal, V+, GND.
- Wire it up: Servo V+ → Pi's 5V pin. Servo GND → Pi's GND pin. Servo Signal → a GPIO pin (e.g. pin 37).
- Go to the Code tab and write a test script that sweeps through a few angles:
import RPi.GPIO as GPIOimport asyncio signalPin = 37 GPIO.setmode(GPIO.BOARD)GPIO.setup(signalPin, GPIO.OUT) pwm = GPIO.PWM(signalPin, 50) # 50Hz, standard for servospwm.start(0) def angle_to_duty(angle): # Converts a 0-180 degree angle into the duty cycle percentage the servo expects return 2.5 + (angle / 180) * 10 # roughly 2.5% (0°) to 12.5% (180°) async def move_to(angle): print(f"Moving to {angle} degrees") pwm.ChangeDutyCycle(angle_to_duty(angle)) await asyncio.sleep(1) await move_to(0)await move_to(90)await move_to(180)await move_to(90) pwm.stop()GPIO.cleanup()- Click Start. You should see the servo horn visually rotate: starting near one end, sweeping to center, continuing to the other end, then returning to center — each position held for about a second before moving to the next.
What you'll see in the Console:
Moving to 0 degreesMoving to 90 degreesMoving to 180 degreesMoving to 90 degreesEach line should print right as the servo visually starts moving toward that position — that's your confirmation the script's intent and the servo's actual motion are in sync, not just coincidentally similar.
One extra check worth doing: if the print appears but the servo doesn't move (or moves to a clearly wrong position), that tells you the script → PWM channel path is working correctly, but the PWM channel → visual rotation path is where the problem actually is. Worth mentioning that distinction if you ever need to report a bug, since it narrows down which half of the pipeline to look at first.
What “working correctly” looks like
- The servo horn visually rotates: starting near one end, sweeping to center, continuing to the other end, then returning to center — each position held for about a second before moving to the next.
- Each Console line (“Moving to N degrees”) prints right as the servo visually starts moving toward that position, not noticeably before or after.
If something’s wrong
- The servo stays at the center (about 90°) and never moves → its Signal pin is not wired to a Pi GPIO pin, or the script has not called GPIO.PWM(...) and pwm.start(...). A stopped PWM channel also sends the servo back to center, so a servo that returns to center after pwm.stop() is normal.
- The servo goes to the wrong angle → the simulator maps duty cycle to angle in a straight line: 2.5% is 0°, 7.5% is 90° and 12.5% is 180°. A duty cycle outside 2.5% to 12.5% stops at 0° or 180°.
- The Console prints "Moving to…" but the servo does not move → check the Signal wire first. The script is running, so the problem is between the Signal pin and the servo.
- The servo will not snap into the breadboard → that is expected. The SG90 connects with drawn wires, like a real servo with its loose cable.
- In the simulator the servo moves from the Signal wire's PWM alone. Wire V+ and GND anyway, because a real servo needs them.