This part has a page of its own, with a note on using it and a circuit to try: the part page.
Servo (hobby, SG90 style)
The nine-gram hobby servo, SG90 style: three wires, and a horn that walks to the angle a pulse width tells it.
The signal on PWM is not PWM in the dimming sense; the duty cycle means nothing.
It is a pulse width: about 1 ms puts the horn at one end of its travel, 2 ms the
other, 1.5 ms the middle, repeated fifty times a second.
Pins
| Pin | What it does |
|---|---|
GND |
Ground, brown wire. |
VCC |
Supply, red wire. |
PWM |
Signal, orange wire: a pulse width, not a duty cycle. |
Properties
min_pulse / max_pulse: the pulse widths for the two ends of travel, 1000 and
2000 microseconds by default. range: degrees of travel, 180 by default.
speed: how fast the horn moves towards a new angle, 600 degrees per second.
What the model gets right
The part is a stopwatch on one pin and a horn that walks towards the angle the
stopwatch names: a rising edge starts the clock, a falling edge stops it, a width
outside the min_pulse–max_pulse window is treated as noise and ignored, and with
no pulses at all the horn stays exactly where it is, the way a real servo does when
its signal wire falls off. speed matches the datasheet's 0.1 seconds per sixty
degrees. A servo that only sweeps 120 degrees, or one that wants the Arduino
library's default 544–2400 us window, is those three numbers changed and nothing
else.
What it does not model
Current. A real SG90 pulls a quarter of an amp when it stalls and can brown out the
board driving it (the single most common reason a servo project misbehaves on the
bench), but Mokxi's supply rails have no impedance to sag, so a sag here would be a
lie about something that cannot happen in this simulator. VCC/GND are read for
one thing only: below 4 V the servo does not move at all.
No torque, no load and no overshoot. The horn walks to its target at a constant 600 degrees a second and stops dead. There is no acceleration, no settling, no hunting around the target, no dead band (a real SG90 ignores changes under about 5 microseconds of pulse width) and no gear backlash, so a commanded angle is always reached exactly. The 0.1 seconds per sixty degrees is the datasheet's unloaded figure and applies here whatever is on the horn, because there is nothing on the horn.
The stopwatch is also more forgiving than a real servo's: the horn is updated every 20 ms whatever the pulse rate is, a pulse longer than 3 ms is discarded rather than treated as a fault, and a gap in the pulse train is simply held rather than released.
Code
The Arduino library's own calls work as they are on every board that compiles in the browser:
#include <Servo.h>
Servo myservo;
void setup() {
myservo.attach(9);
}
void loop() {
for (int pos = 0; pos <= 180; pos++) {
myservo.write(pos);
delay(15);
}
}
Servo.h is Mokxi's own, on the same driver as mokxi_servo.h, and two things
are different from the upstream library. attach(pin) with no widths uses 1000
to 2000 microseconds, this part's window, where the upstream library uses 544 to
2400; attach(pin, 544, 2400) sends exactly those, and the part ignores a pulse
outside its window. And each write() sends one pulse rather than starting a
timer that pulses for ever: the part holds the last width it was sent, as a real
servo does with nothing pushing on the horn. On the bench, under load, call
myservo.refresh() from loop() to keep the frame coming. ESP32Servo.h is
the same class, for ESP32 tutorials.
Continuous rotation
Set mode to continuous and the part is the other servo in the parts bin, the
FS90R kind: the same case and wires, with the end stops removed and the position
sensor replaced by a fixed middle. A pulse now names a speed. The middle of the
window, 1500 microseconds, is stopped; the ends are full speed one way and the
other, rpm (110 by default, the FS90R's figure at 4.8 V); in between is in
proportion. Within 10 microseconds of the middle it reads as stopped, which is the
small dead band that makes write(90) stop it. A wider pulse turns it
anticlockwise. The probe is then the speed in rpm, positive anticlockwise, and the
horn spins on the canvas.
A real one stops within a frame or two when the pulses stop. This one keeps the
last speed it was sent, because Mokxi's Servo library sends one pulse per
write(), and write(180); delay(2000); means two seconds of turning. The dead
band and the full-speed pulse width vary from servo to servo on the bench, which is
why some have a trimmer; here they are exact.
Common mistakes
Driving it from a pin that also drives something power-hungry and expecting no interaction. Because current sag is not modeled, a circuit that would brown out on a real board runs cleanly here, which is worth knowing before trusting the simulation for a power budget.
See it in action
Servo fader drives the horn from a slide potentiometer. Open it at /templates.