Servo

Drive up to 8 PWM hobby servos from the browser — with smooth sweeps, timed moves, and angle read-back.

Requires <PardaloteServo.h> in the sketch (plus the ESP32Servo library on ESP32). Register instances before connecting; examples assume:

JS
arduino.add('pan', new Servo());

Alternatively, the sketch can create the servo — PardaloteServo.attach("pan", 9) on the Arduino — and arduino.pan appears automatically, no add() needed: a full Servo instance, identical to the above, present before 'ready' fires. See The Arduino sketch.

attach()

Attaches the servo to a pin. Call inside on('ready').

arduino.pan.attach(pin, [minPulse], [maxPulse])
Parameter Type Description
pin number | string PWM-capable pin the servo signal wire is on.
minPulse number Optional. Pulse width at 0°, in µs (default 544).
maxPulse number Optional. Pulse width at 180°, in µs (default 2400).
JS
Example — attach a servo
arduino.pan.attach(9);
arduino.pan.attach(9, 544, 2400);   // custom pulse range

detach()

Releases the pin.

arduino.pan.detach()

write()

Moves the servo to an angle. Cancels any in-progress sweep or timed move.

arduino.pan.write(angle)
Parameter Type Description
angle number Target angle, 0–180 degrees.

writeMicroseconds()

Fine-grained control via raw pulse width.

arduino.pan.writeMicroseconds(us)
Parameter Type Description
us number Pulse width in microseconds, typically 544–2400.

center() / min() / max()

Shorthand moves.

arduino.pan.center() · arduino.pan.min() · arduino.pan.max()

Move to 90°, 0°, and 180° respectively.

read()

Reads the servo's angle. Same poll-and-cache pattern as analogRead(): the first call starts a poll, later calls return the cached value. The board runs the poll (per-browser interval and threshold) and only transmits changes of threshold+ degrees.

arduino.pan.read([interval], [threshold])
Parameter Type Description
interval number Optional. Poll interval in ms. Pass END to stop.
threshold number Optional. Minimum change worth transmitting, in degrees (0 = default: 1). Also settable via setReadInterval(ms) / setReadThreshold(degrees).

Returns the cached angle in degrees.

What the Arduino reports depends on the platform:

  • UNO R4 WiFi: the last commanded angle (the Arduino Servo library's read() is just a getter).
  • ESP32: the angle decoded from the LEDC PWM duty register. Usually matches the commanded angle, but the hardware round-trip can return values slightly off, and a write() during a read() can briefly return a transitional value.

If you just want "what did I tell the servo to do?" — use the angle property (locally cached, updated on every write()).

sweep()

Sweeps between two angles over a duration, streaming intermediate writes. Returns a promise. Any write() cancels it.

await arduino.pan.sweep(from, to, duration, [steps])
Parameter Type Description
from number Start angle.
to number End angle.
duration number Sweep time in ms.
steps number Optional. Number of intermediate writes (default 50). More = smoother.
JS
Example — smooth sweep
await arduino.pan.sweep(0, 180, 2000);

writeTimed()

Moves to an angle over a set time — the Arduino interpolates on-board (smooth, no WiFi streaming) and fires done on arrival. The modern replacement for sweep(), and what lets PWM servos arrive together inside a group.

arduino.pan.writeTimed(angle, duration)
Parameter Type Description
angle number Target angle, 0–180.
duration number Move time in ms.
JS
Example — timed move with a done event
arduino.pan.writeTimed(120, 1500);   // move to 120° over 1.5 s
arduino.pan.on('done', ({ angle }) => { /* arrived */ });

An immediate write() cancels an in-progress timed move.

gesture()

Plays an authored segment schedule — an ordered list of eased moves the Arduino runs back-to-back on its own clock (on-board, no WiFi streaming). Where writeTimed() is one eased move, a gesture is many: the primitive for expressive motion — anticipation, overshoot, holds, follow-through. Fires done (resolves whenDone()) when the last segment lands. Timing follows the shared gesture timing rules: segments start on schedule, and the last key is landed or given up on 2 s after its expected arrival.

arduino.pan.gesture(segments, [opts])

Each segment is an object with a duration, a curve, and a displacement expressed either relatively (by) or absolutely (to):

Field Type Description
dur number Segment duration in ms.
curve string Easing: 'linear', 'easeIn', 'easeOut', 'easeInOut', or 'back' (overshoot). Default 'linear'.
by number Relative displacement in degrees — the default, portable frame.
to number Absolute target angle — use in place of by.

The reference frame is inferred (to → absolute, by → relative) or forced with opts.absolute. Relative is the default: the board captures the start angle at each segment, so a gesture needs no absolute position truth. Up to 16 segments (extras dropped with a warning); a back overshoot is re-clamped to the servo range / setLimits().

JS
Example — a nod with follow-through
arduino.pan.gesture([
    { by:  25, dur: 250, curve: 'easeOut'   },
    { by: -25, dur: 400, curve: 'easeInOut' },
    { by:   6, dur: 180, curve: 'back'      },   // small overshoot settle
]);
await arduino.pan.gesture([ /* … */ ]).whenDone();

To play coordinated gestures across several actuators at once, see group.gesture().

whenDone()

Promise for the most recent timed move — resolves true on the servo's done (or immediately if no move is pending), false if it didn't arrive (a gesture that gave up, or the safety timeout — default max(duration × 2, 10000) ms; pass { timeout } or a bare number to override, 0 to wait forever). The same method exists on steppers, bus servos, and groups.

await arduino.pan.whenDone([{ timeout }])
JS
Example — sequence timed moves
await arduino.pan.writeTimed(120, 1500).whenDone();
await arduino.pan.writeTimed(60,  1500).whenDone();

stop()

Cancels a timed move and holds the current angle.

arduino.pan.stop()

setLimits() / clearLimits()

Soft angle limits, enforced on the Arduino — every commanded angle (browser write, sketch write, timed or group move) is clamped to the range before it reaches the servo. Same shape as setLimits on the stepper and bus servo.

arduino.pan.setLimits(min, max) · arduino.pan.clearLimits()
Parameter Type Description
min, max number Allowed angle range, 0–180.

setHome() / home()

setHome(angle) declares the home angle — no-arg means "the current angle is home". home() snaps there; home(duration) glides there over duration ms. Default home is 90 (centre). Same pair as the stepper and bus servo.

arduino.pan.setHome([angle]) · arduino.pan.home([duration])
JS
Example — ease home
arduino.pan.setHome(45);
await arduino.pan.home(1000).whenDone();

attached()

Asks the board whether this servo is attached. Resolves true/false (false after a 2 s timeout — dead link or unresponsive board). Query → promise, like busServo.ping(); for the cached mirror, read arduino.pan.isAttached.

await arduino.pan.attached()
JS
Example — preflight check
if (await arduino.pan.attached()) beginSequence();
else showError('pan servo not responding');

Events

arduino.pan.on(event, handler)
Event Payload Fires when
'change' { angle } The angle changed by at least the threshold.
'write' { angle } A write is issued.
'gesture' { segments, absolute, duration } This browser sends a gesture (local echo).
'gesturestart' {} The board starts playing a schedule on this servo — any origin (this browser, another, or the sketch).
'gestureend' {} …that schedule ends — completion or a superseding write.
'done' { angle, arrived } A timed move or gesture finishes. arrived is false only for a gesture that gave up.

Shorthand: onChange(fn), onWrite(fn), onDone(fn), onGestureStart(fn), onGestureEnd(fn). The board reports whether a schedule is playing (any origin) via the isGesturing property; a browser that connects mid-gesture learns it on sync.

setWriteThrottle() / setWriteThreshold()

Rate-limits outgoing writes — useful when driving the servo from mouse movement or a draw loop.

arduino.pan.setWriteThrottle(ms) · arduino.pan.setWriteThreshold(degrees)

The write family paces what you send (min ms between writes; skip deltas under degrees); the setRead* family gates what you hear.

Parameter Type Description
ms number Minimum ms between writes (default 20).
degrees number Minimum change in degrees to send (default 1).

Properties and state

Property Description
arduino.pan.angle Locally cached snapshot, updated on every write().
arduino.pan.isGesturing true while the board is playing a segment schedule on this servo (any origin).
arduino.pan.getState()

Returns a snapshot of all servo state.

See also: Groups · Bus servo · Servo example