Hello friends, I hope you all are doing great. Today, I am going to share the new SG90 Servo Motor Library for Proteus V1.0. The little blue SG90 is the first servo almost everyone meets: it comes in every Arduino starter kit, it moves the arms of small robots, the rudders of paper planes and the pointers of a hundred weather gauges. Until now it was only a part of our servo driver library; from today it is a library of its own, with a horn that turns on your schematic and a pop-up window that tells you what the servo gets and what it does.

Updates

SG90 Servo Motor Library for Proteus

Latest version: V1.0 (October 2026, this tutorial)

Other motors: TT Gear Motor · 28BYJ-48 Stepper · NEMA 17 Stepper · MG996R Servo · N20 Encoder Motor · JGA25-370 Encoder Motor · FS90R 360 Servo · 130 DC Motor · A2212 Brushless · X27.168 Gauge · Analog Panel Meter · DC Tachogenerator · LM393 Speed Sensor · MG90S Servo · DS3218 Servo · L12 Linear Servo · JGB37-520 Motor · RS-775 Motor · JGY-370 Worm Motor · 12V Linear Actuator · Coin Vibration Motor · Mini Submersible Water Pump · 12V Peristaltic Pump · 4-Pin PC Fan · 12V Push-Pull Solenoid · NEMA 23 Stepper Motor · Micro Linear Stepper · TYJ50 Synchronous Motor · Quartz Clock Movement · Air-Core Gauge · Electromechanical Counter · Split-Flap Display · Electric Bell · Wind Turbine · 8520 Coreless Motor · Car Wiper Motor · Car Door Lock Actuator · 12V Solenoid Water Valve · 12V Holding Electromagnet

Motor drivers: L298 · L9110S · TB6612FNG · BTS7960 · A4988 / DRV8825 · 28BYJ-48 + ULN2003 · PCA9685 Servo · Relay Module · 30A Brushless ESC · TB6600 Stepper Driver

Helping Tools

The model is not a picture on top of a rotating symbol. It reads the pulses on its signal wire like the real servo, runs the position loop of an analog servo, drives a DC motor through a gearbox and draws its current from the supply in your circuit. So the horn takes as long to reach its angle as a real SG90, it stops short under a load, and it stalls against its end stop if you ask for too much. The demo runs on our Arduino UNO V4.0 with the standard Servo.h library and a potentiometer as the knob.

NOTICE: a servo in a simulator is only useful if it moves like a servo. So we did not just rotate a drawing, we built the physics: the pulse decoder, the position loop, the motor, the gears and the current. It took our team a lot of hard work. Your feedback is the fuel that keeps us going, so please tell us what you think in the comments below or in the Motor Driver board of our forum. And if our free libraries help you, you can buy us a coffee. So, let's get started with the SG90 Servo Motor Library for Proteus V1.0:

Figure: The SG90 Servo Motor Library for Proteus: the Arduino UNO V4.0 sends 1936 us pulses on D9 and the SG90 holds its horn at 135 degrees, with its PWR and SIG LEDs lit.

What is the SG90 Servo Motor?

A hobby servo is a small motor that goes to an angle and stays there. Open one and you find four things in a plastic case: a tiny DC motor, a train of gears that slows it down and multiplies its torque, a potentiometer on the output shaft that measures the angle, and a control board that compares the angle it measures with the angle it is asked for. If they differ, the board drives the motor until they agree. That loop is why a servo needs only one signal wire to hold a position.

The SG90 from TowerPro is the smallest and cheapest of the common servos. It weighs 9 grams, turns its horn through about 180 degrees and runs from 4.8 to 6 V. Its three wires are brown for GND, red for the supply and orange for the signal. The plastic gears limit it to light jobs, but for pointers, small arms, flaps and camera tilts it is all you need.

The SG90 at a glance
TowerPro SG90 micro servo
Supply4.8 - 6 V (the red wire)
Signalone pulse every 20 ms (50 Hz); the pulse width sets the angle
Rangeabout 180 degrees
Speed0.1 s for 60 degrees at 4.8 V (no load)
Stall torque1.8 kg.cm at 4.8 V
Currenta few mA at rest, a few hundred mA while it moves, about 0.65 A stalled
Size and weight22.2 x 11.8 x 31 mm, 9 g
Wiresbrown GND, red V+, orange SIG

How a Servo Reads Its Pulses

The signal is a pulse that repeats about 50 times a second. The servo does not care about the frequency much; it measures the width of each pulse. A short pulse means one end of the range, a long pulse the other end, and the middle width the middle. Datasheets often say 1 to 2 ms, but most SG90s use a wider span, and the Arduino Servo library uses 544 us for 0 degrees and 2400 us for 180 degrees. Our model uses the same numbers by default, so write(90) puts the horn at 90 degrees; the properties PULSE_MIN and PULSE_MAX change them for other libraries.

Two more details make a real analog servo behave the way it does. After each pulse its board drives the motor for a short time only, about 20 ms, so a servo that gets no more pulses is no longer driven and holds only by the friction of its gears. And its loop has a small dead band: if the angle is within about half a degree of the target, it does nothing. Both are in the model.

What's New in SG90 Servo Motor Library for Proteus V1.0

  • A part of its own: the SG90 no longer needs our PCA9685 board; wire it to any pin that makes servo pulses.
  • A horn that turns: the white horn on the schematic turns to the simulated angle, and an orange marker on the 0 - 180 degree scale shows the angle the pulses ask for.
  • Real servo timing: the pulse decoder, the position loop with its dead band, the motor, the gearbox, the inertia and the friction - 60 degrees take about 0.15 s, as on the bench.
  • Real current: the servo draws its current from V+ in your circuit, so a probe or an ammeter shows the peaks.
  • Loads and stalls: a LOAD property, load buttons on the pop-up and a brake when you click the horn.
  • A pop-up window with four pages - Servo, Graphs, Event log and Check - in the look of our serial monitor.
  • It names your mistakes: no power, SIG stuck HIGH, analogWrite PWM instead of servo pulses, pulses too fast, a pulse beyond the range, a stall.
  • An A4 demo on our Arduino UNO V4.0 with the Servo library, a potentiometer and serial monitor commands.

The SG90 in Proteus

Figure: The part as the library draws it, running: the horn at 30 degrees, the orange target marker, the PWR and SIG LEDs and the strip with the angle, the pulse and the current.

Search SG90 in Pick Devices; the device SG90SERVOTEP is in TEPSG90.LIB (category Electromechanical, Servo Motors) and its model is TEPSG90.DLL. It is drawn as the real servo seen from the top: the translucent blue body with its two mounting ears, the round boss of the output shaft and the white single-arm horn on it. The brown, red and orange cable runs to the plug at the top right, where the three pins GND, V+ and SIG come out.

Around the servo is a light TEP plate with a 0 - 180 degree scale. The horn points at the angle the model has computed, and the small orange triangle at the edge of the scale points at the angle the pulses ask for. While the horn is on its way you see both: the target first, the horn following it. Two LEDs sit on the plate: PWR (red) lights when V+ is high enough, SIG (amber) lights while pulses arrive. Under the plate is the strip with three readouts - the angle, the last pulse width and the current - and the OPEN PANEL button. The plate, the scale, the LEDs and the strip are TEP additions; a real servo has none of them.

Figure: SERVO1 in the running demo: 135.0 deg, 1936 us and 6 mA on the strip - the servo holds its angle and draws almost nothing.

The Pins and the Properties

The three pins of the SG90
PinWireWhat the model does with it
GNDbrownthe return of the servo's current
V+redthe supply, 4.8 - 6 V: the servo draws its current from it (below 3 V nothing moves)
SIGorangea digital input: every edge is time-stamped; a 300 - 3000 us HIGH is a servo pulse
Double-click the servo to change them; every run starts again from the properties
PropertyDefaultWhat it does
PULSE_MIN544the pulse for 0 degrees, in us (the Servo library's number)
PULSE_MAX2400the pulse for 180 degrees, in us
START90the horn's angle when the simulation starts
LOAD0a constant load on the horn in kg.cm (the SG90 gives 1.8 kg.cm at 4.8 V)

A Click on the Horn: the Brake

Click the horn while the simulation runs and you put a finger on it: a 2.5 kg.cm brake, more than an SG90 can give. An orange ring appears round the hub. Ask for a new angle now and the horn does not move; the motor pushes with all it has, the current jumps to the stall current and a red dot on the hub says STALLED. Click again to let go and the horn moves on.

Download SG90 Servo Motor Library for Proteus

The download link of SG90-Servo-Motor-Library-for-Proteus-v1.0.zip (without the source code) will be added here soon. The zip file will contain:

  • README.txt: installation, the demo, the wiring, the properties, real hardware, troubleshooting and the limits.
  • Proteus Library Files: TEPSG90.LIB and ArduinoV4TEP.LIB from our Arduino Library for Proteus V4.0.
  • Proteus Model Files: TEPSG90.DLL and TEPARDUINO.DLL.
  • Proteus Simulation: SG90-Servo-Motor-ArduinoUnoV4.pdsprj, SG90_Servo_Demo.hex and copies of the two DLLs.
  • Arduino Code: SG90_Servo_Demo.ino (the Servo library comes with the Arduino IDE).

No Proteus yet? Read How to Download and Install Proteus 7 and 8. New to libraries? Follow How to Install a New Library in Proteus.

How to Install SG90 Servo Motor Library for Proteus

  1. Close Proteus and extract the whole zip file, for example to your Desktop.
  2. Copy TEPSG90.LIB and ArduinoV4TEP.LIB from Proteus Library Files into the LIBRARY folder of Proteus (usually C:\Program Files (x86)\Labcenter Electronics\Proteus 8 Professional\LIBRARY).
  3. Copy TEPSG90.DLL and TEPARDUINO.DLL from Proteus Model Files into the MODELS folder. The two Arduino files are the ones of our Arduino Library V4.0; if you have it, they are the same.
  4. Delete TEPSG90.IDX from the LIBRARY folder if it is there.
  5. Start Proteus, press P and search for SG90.

Tip: keep the Proteus Simulation folder together, because the project needs its .hex file and the DLLs beside it. The library is tested in Proteus 8.5; Proteus 7 is not supported.

The Demo Circuit

Figure: The demo project running on its A4 sheet: ARD1, SERVO1 with its horn at 135 degrees and RV1 at 75 %.

Open SG90-Servo-Motor-ArduinoUnoV4.pdsprj. The sheet is A4 and holds three parts. ARD1 is an Arduino UNO V4.0 from our Arduino UNO Library for Proteus V4.0, running SG90_Servo_Demo.hex with its serial monitor built in. SERVO1 is the SG90. RV1 is a 10k potentiometer on A0 that works as the knob. If you know our older Control Servo Motor with Arduino in Proteus tutorial, this is the same idea with a servo that behaves like the real one.

The wiring (the same in Proteus and on a real board)
SG90 wireArduino UNONote
brown (GND)GNDcommon with the supply
red (V+)5Vone SG90 with no load; a real project gives it its own 5 - 6 V supply
orange (SIG)D9any digital pin: the Servo library makes the pulses with Timer1
RV1 wiperA0the ends of the pot on 5V and GND

In Proteus the SIG pin of the servo and D9 of the UNO meet through a net label called SIG, V+ is on the +5V power terminal and GND on a ground terminal. The monitor needs no wires at all, because it is built into the UNO V4.0.

The Arduino Code

The demo uses the Servo library that comes with the Arduino IDE. New to Arduino? Start with Arduino Tutorial for Beginners and Introduction to Arduino UNO. The sketch begins with the library, the two pins and one Servo object:

#include <Servo.h>

const int SERVO_PIN = 9;
const int POT_PIN = A0;

Servo servo;

attach() starts the pulses on D9 at 50 Hz. From then on the library sends a pulse every 20 ms by itself, in the background, whatever the sketch does:

void setup() {
  Serial.begin(9600);
  servo.attach(SERVO_PIN);
  Serial.println(F("SG90 Servo Motor demo - The Engineering Projects"));
  Serial.println(F("Turn the pot on A0, or type an angle."));
  help();
}

The knob is the Arduino's Knob example: read the pot, map 0 - 1023 to 0 - 180 degrees and write the angle. The sketch only writes when the angle has changed by two degrees, so the monitor stays readable:

  if (mode == KNOB) {
    int raw = analogRead(POT_PIN);
    int angle = map(raw, 0, 1023, 0, 180);
    if (lastAngle < 0 || abs(angle - lastAngle) >= 2) {
      servo.write(angle);
      lastAngle = angle;

For each angle it prints the pulse width the library sends. write() maps 0 - 180 degrees onto 544 - 2400 us, and the sketch does the same sum for the monitor:

void report(int angle) {
  Serial.print(F("Angle "));
  Serial.print(angle);
  Serial.print(F(" deg -> pulse "));
  Serial.print(map(angle, 0, 180, 544, 2400));
  Serial.println(F(" us"));
}

One detail of the Servo library deserves a comment, and the sketch has one. writeMicroseconds() is clamped to the limits given to attach(), 544 - 2400 us by default. To try a pulse outside them, the sketch attaches again with wider limits:

// write() maps 0 - 180 deg to the attach() limits (544 - 2400 us by default) and writeMicroseconds() is clamped to them;
// "us" outside them re-attaches with wider limits (400 - 2900 us) so a pulse beyond the servo's range can be tried
bool wide = false;
void ensureAttached(bool wideLimits = false) {
  if (servo.attached() && wide == wideLimits) return;
  if (servo.attached()) servo.detach();
  if (wideLimits) servo.attach(SERVO_PIN, 400, 2900);
  else servo.attach(SERVO_PIN);
  if (!strncmp(s, "us", 2)) {
    int w = atoi(s + 2);
    if (w < 400 || w > 2900) { Serial.println(F("Pulse width: 400 - 2900 us")); return; }
    ensureAttached(w < 544 || w > 2400); mode = FIXED;
    servo.writeMicroseconds(w);

The sweep is the Arduino's Sweep example: one degree every 15 ms, from 0 to 180 and back, without delay() so the monitor keeps working:

  } else if (mode == SWEEP && millis() - sweepAt >= 15) {
    sweepAt = millis();
    servo.write(sweepAngle);

The HEX file is in the package. To change the sketch, open it in the Arduino IDE and export the compiled binary, as in How to get the HEX file from Arduino. It needs 6,646 bytes of flash (20 % of the UNO) and 306 bytes of RAM.

Running the Demo

Press Run. The UNO's serial monitor and the servo's pop-up open over the schematic; move them aside. RV1 starts at 75 %, so the first reading asks for 135 degrees:

SG90 Servo Motor demo - The Engineering Projects
Turn the pot on A0, or type an angle.
Commands: 0-180 = angle, us 1500 = pulse width, sweep, knob, detach, help
Pot 768 -> Angle 135 deg -> pulse 1936 us

The horn swings from its start at 90 degrees to 134.4 degrees in 129 ms and settles at 135.0 degrees. Then it holds, and the strip says 6 mA: a servo at rest only feeds its control board. Click the arrows of RV1 and the orange marker jumps first, the horn follows a moment later.

Figure: ARD1's monitor: the pot at 135 degrees, then 30, knob, 150 and knob typed in the monitor.

Type an angle in the monitor and press Send. The pot is ignored until you type knob:

30
Angle 30 deg -> pulse 853 us
knob
Following the pot on A0
Pot 768 -> Angle 135 deg -> pulse 1936 us

The move from 135 down to 30 degrees takes 230 ms, an average of 453 degrees per second, and the way back after knob 229 ms. That is the SG90's datasheet speed - 0.1 s for 60 degrees at full speed - plus the start and the slow-down at the end that every position loop has.

The commands of the demo sketch
TypeWhat it doesWhat the run showed
0 - 180go to that angle and stay30: 853 us, the horn at 30.4 degrees; 150: 149.5 degrees
us 1500writeMicroseconds(), 400 - 2900 usus 2800: the horn at its end stop, 682 mA, STALLED
sweep0 to 180 to 0 degrees, 1 degree every 15 msthe horn a hair behind the target, 10 mA
knobfollow the pot on A0 againback to 135 degrees in 229 ms
detachstop the pulsesthe horn is no longer driven and holds by friction
helpthe list of commands

Turn RV1 to 50 % and the sketch asks for 90 degrees with 1472 us. The horn stops at 90.4 degrees and stays there: it is inside the dead band, so the loop has nothing to correct. Real servos do exactly this, and it is why two SG90s given the same pulse rarely point in exactly the same direction.

The Pop-Up Window

At Run the servo opens TEP SG90 Servo Motor, a window in the look of our TEP Serial Monitor Advance for Proteus. It has four tabs - Servo, Graphs, Event log and Check - plus Settings and Help behind the gear and question mark icons, and the palette icon that switches the theme. If you close it, the OPEN PANEL button on the strip brings it back; a green dot on the button shows it is open.

Servo

Figure: The Servo page while the servo holds 135 degrees: the green banner, the dial, eight live values and the last pulse against the servo's range.

The banner says what the servo is doing in big letters: HOLDING, MOVING, NO PULSES, STALLED or NO POWER. The dial shows the horn in white and the target in orange. The live values are the target, the angle, the pulse width, the pulse rate, the speed, the current, the supply and the load. At the bottom, The signal on SIG draws one 20 ms frame and the last pulse against the 0, 90 and 180 degree marks, so you see at a glance where 1936 us falls in the range. The toolbar puts a load on the horn - None, 0.5, 1.0, 1.5 or 2.0 kg.cm - or the brake.

Graphs

Figure: Graphs: the horn (blue) follows the target (orange) from 135 to 30 degrees and back; each move shows as a current peak.

Graphs draws the angle of the horn and the target, the supply current and the pulse width over the last 1, 3 or 6 seconds. The current graph is the one to watch: every move starts with a peak of a few hundred milliamps while the motor speeds up, then drops back to a few milliamps. Freeze holds the page for a closer look.

Figure: The Sweep example on the Graphs page: the target climbs one degree every 15 ms and the horn follows just behind it.

During the sweep the target is a staircase of one-degree steps. The servo never catches it exactly, it follows a hair behind, and the current stays near 10 mA because the motor never has to work hard.

Event Log

Figure: The Event log, newest first: power, the first pulses, every target and every move with its time and speed, the brake and the stall.

The Event log keeps the story of the run, newest first: the power, the first pulses ("pulses: 1502 us at 50.0 Hz"), every new target with its pulse width and every finished move with its time and speed, for example "reached 30.5 deg from 135.0 in 230 ms (453 deg/s)". Filter it by moves or warnings, pause it or clear it.

Two Ways to Stall a Servo

A servo that stalls is the most common way to brown out an Arduino, so the library makes stalls visible. There are two classic ways to get one.

A Pulse Beyond the Range

Figure: The Check page after us 2800: the pulse asks for 219 degrees, the horn is stalled at its end stop and draws 682 mA.

Type us 2800. The sketch re-attaches with wide limits and sends 2800 us, which asks for 219 degrees - beyond anything the servo can do. The horn runs to its mechanical end stop at 188 degrees and pushes against it. The banner turns red, and the current stays at 682 mA for as long as the pulse is there. On a real SG90 that is a hot motor and a buzzing gearbox.

The Check page puts every condition in a row with a verdict: green for fine, amber for check, red for wrong. Here the supply and the pulse rate are fine, the pulse widths are amber, and the range and the position are red with the reason in words. Under the rows are the Arduino code and the advice to match PULSE_MIN and PULSE_MAX with the library's numbers.

A Load Above Its Torque

Figure: The brake on and 150 degrees asked: the horn cannot move, the banner says STALLED and the current is at the stall level.

Click the Brake chip on the pop-up, or click the horn on the schematic, and type 150. The horn stays at 135 degrees. The Event log explains why: "STALLED at 134.9 deg - the load (2.5 kg.cm) is above its torque (1.8 kg.cm at 4.8 V), 680 mA". Release the brake and the horn finishes its move. With the smaller loads of the toolbar the servo still moves, a little more slowly, and stops a little short of the target - a real analog servo droops under load too.

How the Model Works

Proteus solves the analog part of a circuit in time steps and runs the digital part, the Arduino with its pulses, before each step. The servo keeps every edge on SIG with its exact time, so it knows the width of each pulse to the microsecond even when an analog step is long. Then it integrates its motor and its horn over the step in 50 us slices: the pulse sets the target, the loop compares it with the angle, the board drives the motor for about 22 ms after each pulse, the motor fights its back-EMF and the load, and the gearbox turns the horn.

The current is part of the circuit, not a number in a window. The model draws it from V+, so a supply that sags under a stall sags in your simulation too, and an ammeter in series with the red wire reads what the pop-up shows. We checked the model on a PC with 26 automatic tests: 60 degrees take 0.149 s at 4.8 V with the settling and 0.125 s at 6 V, the top speed is 587 degrees per second, a stall at 4.8 V draws 655 mA, and the angles of the Servo library land within 0.6 degrees.

Need more servos than an Arduino has timers for? Our PCA9685 Servo Driver Library for Proteus drives sixteen of them over I2C, and its demo moves a whole row of SG90s.

Troubleshooting

  • The horn never moves and the pop-up says NO POWER: V+ is not connected or below 3 V; an SG90 wants 4.8 - 6 V.
  • WAITING FOR PULSES: SIG is on another pin than the one in attach(), or the sketch never calls attach().
  • "SIG stays HIGH" or "pulses under 300 us": digitalWrite() or analogWrite() on the SIG pin - use the Servo library.
  • The horn stops a few degrees short: a load - the LOAD property, a load button or the brake (the orange ring).
  • The horn sits at an end and the current is high: a pulse beyond the range, or PULSE_MIN / PULSE_MAX do not match the library; the Check page shows the widths it saw.
  • No horn, no UNO or no monitor: TEPSG90.DLL or TEPARDUINO.DLL is missing from MODELS and the project folder; a closed monitor opens again with a click on the UNO's USB port.

Things to Know Before Using a Real SG90

  • Power: one SG90 draws up to about 0.65 A when it starts or stalls. More than one servo, or any load, wants its own 5 - 6 V supply for the red wire, with GND common to the Arduino; an Arduino on USB power can reset otherwise.
  • Each servo has its own range: many SG90s turn less than 180 degrees for 544 - 2400 us, or hit their end stop before 2400 us. Find the limits of yours and use attach(pin, min, max); a servo pushing against its stop runs hot.
  • analogWrite() is not a servo signal: it is 490 or 980 Hz PWM. Use the Servo library.
  • The Servo library uses Timer1: on an UNO, analogWrite() on D9 and D10 stops working while a servo is attached.
  • Jitter: a servo that twitches at rest usually has a noisy supply or a long signal wire; a capacitor of a few hundred microfarads across its supply helps.

Limitations of the Simulation

  • The model is the standard 180 degree analog SG90 at 50 Hz; digital servos and continuous rotation servos are other parts.
  • Not modelled: the variation of the range and the dead band from one servo to the next, gear play, heating, and damage from a wrong supply (the model only warns).
  • The plate, the scale, the LEDs, the strip and the brake are TEP additions.
  • The model is our own, written from the typical data of the SG90; this library is not made or endorsed by TowerPro, Arduino or Labcenter.
  • Licences: the demo HEX contains the Arduino Servo library 1.2.2 (LGPL 2.1) and the Arduino AVR core 1.8.6 (LGPL); the sketch is included and the README gives the source links. The potentiometer is Proteus's own POT-HG.
  • Tested in Proteus 8.5 in October 2026 with the demo as shipped: the knob, the angles, the sweep, us 2800, the brake, detach and all four pages of the pop-up. Proteus 7 is not supported.

So, that was all about the SG90 Servo Motor Library for Proteus V1.0. I hope it helps you see what your servo code really asks for - the pulse, the angle, the time it takes and the current it costs - before you wire the first servo on your bench. If you have any questions, ask in the comments and I will help you out. Till the next tutorial, take care and have fun!