Back to projects
๐Ÿ’ก

Servo Light Switch

C++ESP32HomeKitSource

Servo Light Switch

A light switch across the room and a strong disinclination to walk over to it. This is a tiny robot finger that flips the switch when you ask Siri nicely.

A XIAO ESP32S3 advertises itself on WiFi as an Apple HomeKit light. Siri sends the on/off command, the board swings an MG90S servo, and the servo arm flips the rocker paddle โ€” up for on, down for off. That's the whole trick.

"Hey Siri, turn on the light."

demolight.mp4

New to a soldering iron? Start with SOLDERING.md โ€” it walks the three joints in this build from zero.

Hardware

Wiring

Servo wire XIAO ESP32S3 pad GPIO
Red (V+) 5V โ€”
Brown (GND) GND โ€”
Orange (PWM) D1 GPIO2

Coming from the C3? D1 is the same physical pad, but on the S3 it's GPIO2, not GPIO3 โ€” so SERVO_PIN in the sketch is 2, not 3. Also note the servo's red wire now goes to 5V (not 3.3V) for more torque. If you've got the capacitor, its legs go to the same 5V and GND pads (mind the polarity โ€” the stripe is the negative leg, to GND).

The PWM signal is 3.3 V logic, which the MG90S reads fine even while powered from 5 V.

Mounting

The arm swings from a center rest position to press one half of the paddle:

        โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
ON  โ—„โ”€โ”€ โ”‚  โ–ฒ    โ”‚   arm swings up,   presses TOP half
        โ”‚โ”ˆโ”ˆโ”ˆโ”ˆโ”ˆโ”ˆโ”ˆโ”‚   arm rests center, clear of paddle
OFF โ—„โ”€โ”€ โ”‚    โ–ผ  โ”‚   arm swings down, presses BOTTOM half
        โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Mount the servo beside the switch plate so the horn's pivot sits roughly level with the paddle's middle and a stiff arm/horn can reach across to either half. Stick the whole thing down so the arm has firm leverage against the paddle. Then tune the angles below.

Software

Arduino IDE, with the esp32 board package (3.0.0+). Libraries:

Board settings that matter

If the board doesn't show up as a serial port for flashing, put it in bootloader mode: hold BOOT, tap RESET, release BOOT.

First-time setup

  1. Flash the sketch.
  2. Open Serial Monitor at 115200, line-ending = Newline.
  3. Type W to give it WiFi credentials. Must be 2.4 GHz โ€” the S3 has no 5 GHz radio.
  4. Note the HomeKit setup code (default: 466-37-726).
  5. iPhone โ†’ Home app โ†’ Add Accessory โ†’ pick "Wall Light" โ†’ enter the code. Ignore the "Uncertified Accessory" warning; that's normal for DIY.

Calibration

Tune these constants at the top of the sketch to your particular switch and how the servo is mounted:

Constant Value Does what
SERVO_REST_ANGLE 90ยฐ Arm centered, clear of the paddle
SERVO_ON_ANGLE 130ยฐ Arm position that presses the top half
SERVO_OFF_ANGLE 50ยฐ Arm position that presses the bottom half
PRESS_HOLD_MS 250 How long it holds the paddle
SERVO_PIN 2 GPIO2 (D1 on the silkscreen)

Start by finding SERVO_REST_ANGLE where the arm sits clear of the paddle, then bump SERVO_ON_ANGLE / SERVO_OFF_ANGLE out from there until each press flips the rocker cleanly. If the servo slams and buzzes against the paddle, back the angle off toward rest. If it doesn't fully flip the switch, push the angle further or hold longer.

On/off reversed? If "turn on" turns it off, just swap the values of SERVO_ON_ANGLE and SERVO_OFF_ANGLE โ€” it depends on which way round the servo is mounted.

How it behaves

Your rocker has two real, stable states, so HomeKit treats it as a normal light:

One limitation: if you flip the switch by hand, the board doesn't know. HomeKit still thinks it's in the old state, and because it thinks so, Siri may swallow the next same-direction command ("it's already on"). Just give the opposite command, or toggle twice. (The Sense version's camera could one day watch the room and detect manual flips โ€” that's a future upgrade, not part of this build.)

WiFi watchdog

If WiFi is down for 60 seconds, the board reboots itself. This dodges the "stuck unavailable" state the Home app sometimes lands in after a network hiccup.