Build guide

Breathe

A 96 × 66 × 46 mm black desk block with an orange button. When something needs you, a servo opens the front flap, an orange band shows and an LED stick glows behind it, and a buzzer chimes. Press the button to answer. ESP32-C3 inside. Bring your own firmware.

Breathe with the flap open

Your kit contains the printed parts, electronics, screws, hinge pins, servo arm and fastener, bus pins, leads, connectors and insulation. Start with the checklist below; you do not need a 3D printer. Firmware is up to you: see Make it yours.

At a glance

Printed parts
8
Difficulty
Intermediate: some soldering
Build time
about 2 h

Parts checklist

Printed parts

Body

Lid and internal supports

Button

All 8 printed parts

Electronics

Fasteners

SizeQtyWhere
M2 × 4–6 pan head4C3 frame, into the posts beside the board
Supplied hinge pins, 1.75 mm × ~7.5 mm2Flap hinge pins, push fit in the back half

No screws for the servo, no inserts or magnets. A drop of super glue holds the horn tip; hot glue holds the buzzer and the bus pins.

Tools and consumables

Wiring

The C3 SuperMini has one 5V and one GND pin, so a small printed power bus next to it shares them. None of these pins are strapping pins (2, 8, 9) or UART0 (20, 21).

PartPinGoes to
SG90 servosignalGPIO 10
+bus 5V
−bus GND
WS2812 LED stickDINGPIO 4
5Vbus 5V
GNDbus GND
MX switchleg 1GPIO 3 (internal pull-up)
leg 2GPIO 6 (drive LOW: its ground)
Passive buzzer+GPIO 5
−bus GND
Power bus5V rowC3 5V (one jumper)
GND rowC3 GND (one jumper)
Note Power. The servo and the LEDs run from USB 5V (VBUS). Move the servo slowly (about 2 s per move) and detach it when it’s still: it draws far less and stays silent.
Tip The stick sits behind 1 mm of orange. A moderate brightness is plenty, and it keeps the 5V draw low.

Assembly

Exploded view
Base, top (back half and flap) and the orange button.
  1. 1Prepare the electronics

    • Solder header pins on the C3, long side up.
    • Solder wires to the LED stick (DIN, 5V, GND) before it goes in.
    • If the supplied power bus is already assembled, inspect its insulated rows and pin retention and skip this assembly step. Otherwise build it using the supplied pins and leads: push 10 Dupont male pins up into the holder from below until they stop (5V row at the back, GND at the front, both engraved). Twist and solder each row’s wires together, insulate them, and add a little hot glue under the holder so the pins can’t slide down.
    • Solder wires with Dupont ends to the MX switch and the buzzer, long enough to reach the bus and the C3.
    Tip Flash your firmware now (see below) and test the servo, LEDs, buzzer and switch on the bench before building them in.
  2. 2LED stick and buzzer

    LED stick and buzzer

    Fasteners hot glue

    • Drop the LED stick into its channel on the ledge behind the front collar, LEDs facing out, between the two end posts. Run its wires from the back of its ends, over the posts and down the wall.
    • Drop the bare buzzer into its cradle on the left wall from above, top face to the wall, legs pointing inward one above the other. Add a dab of hot glue: the cradle is loose on purpose.

    The base with the C3 frame, power bus, servo cradle and horn tip in place (electronics not drawn).

  3. 3C3 and power bus

    Fasteners 4× M2 pan head

    • Tilt the C3 USB-first into the window in the back wall.
    • Lay the C3 frame over it and screw it down with 4× M2 into the posts beside the board. Its slots hold the Dupont plugs straight; the pin names are engraved next to them.
    • Drop the power bus holder into its slot next to the C3. Jumper the C3’s 5V and GND to one pin of each row.
  4. 4Servo

    Fasteners no screws

    • Drop the servo cradle in between the two screw posts.
    • Set the SG90 on it, tabs in front of the posts. No screws: a driver can’t reach them past the front wall.
    • Plug the servo, LED stick, buzzer and switch wires onto the bus and the C3 (wiring table).
    • Power up once so the firmware drives the servo to its closed position. Then fit the long horn at the closed angle: pointing toward the hinge side, a little down.
    • Slide the horn tip over the end of the horn’s arm and fix it with a drop of super glue. Lifted, the horn stands 5° past vertical against the stop post, so pressing the flap can’t turn the servo back.
    Tip Find the closed and open pulse widths once with a small test sketch (or ESPHome’s servo slider) and store them in your firmware.
  5. 5Top, flap and button

    Fasteners 2× supplied hinge pins

    • Clip the MX switch into the plate at the bottom of the well in the top’s back half.
    • Press the orange button onto the switch stem. Its rim lands on the top just after the switch clicks.
    • Set the flap’s knuckles between the back half’s cheeks and push one supplied hinge pin in at each side. They are a push fit in the back half; the flap swings loose on them.
    • Clip the back half onto the base’s top edge (inner lip, four small bumps).
    Finished, closed
    Closed. When something needs you, the flap lifts about 21° and the orange band glows.

Make it yours: firmware

Breathe ships without firmware. The hardware is a standard ESP32-C3 with a servo, a WS2812 stick, a button and a passive buzzer, so you decide what makes it open. Two ways:

Option A: ESPHome + Home Assistant (no code)

  1. Install ESPHome: the ESPHome Device Builder add-on in Home Assistant, or pip install esphome on a computer.
  2. Create a new ESP32-C3 device and replace its YAML with the skeleton below. Keep Wi-Fi passwords and keys in ESPHome’s secrets.yaml, never in a file you share.
  3. Flash over USB first (the C3’s USB-C), then update over Wi-Fi.
  4. In Home Assistant, adopt the device under Settings › Devices & services › ESPHome with its API key.
  5. Calibrate: move the Flap slider until the horn rests closed, then until the flap is fully open, and note both values.
  6. Automate: open the flap, light the glow and play a short RTTTL tune when something needs you; close it when the Button is pressed.

Minimal skeleton, written for this guide. Adjust it and check the ESPHome docs for your version. If the servo jitters while the buzzer plays, move the buzzer to another LEDC timer (they share frequency per timer).

esphome:
  name: breathe
  on_boot:
    priority: 800
    then:
      - output.turn_off: key_gnd   # the switch's second leg acts as ground

esp32:
  board: esp32-c3-devkitm-1
  framework:
    type: esp-idf

logger:
api:
  encryption:
    key: !secret api_key
ota:
  - platform: esphome
    password: !secret ota_password
wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

output:
  - platform: gpio
    id: key_gnd
    pin: GPIO6
  - platform: ledc
    id: servo_pwm
    pin: GPIO10
    frequency: 50 Hz
  - platform: ledc
    id: buzzer_pwm
    pin: GPIO5

servo:
  - id: flap
    output: servo_pwm
    transition_length: 2s      # slow moves draw less current
    auto_detach_time: 1s       # limp and silent when still

number:
  - platform: template
    name: Flap
    min_value: -100
    max_value: 100
    step: 1
    optimistic: true
    set_action:
      - servo.write:
          id: flap
          level: !lambda 'return x / 100.0;'

rtttl:
  output: buzzer_pwm

light:
  - platform: esp32_rmt_led_strip
    name: Glow
    pin: GPIO4
    num_leds: 8
    rgb_order: GRB
    chipset: WS2812
    color_correct: [35%, 35%, 35%]   # it glows through 1 mm of orange

binary_sensor:
  - platform: gpio
    name: Button
    pin: { number: GPIO3, mode: INPUT_PULLUP, inverted: true }
    filters:
      - delayed_on: 15ms

Option B: build it with an AI coding assistant

Any AI coding assistant can draft firmware (ESPHome YAML, Arduino or ESP-IDF) from a clear hardware description. Paste this and change the “Write firmware that” part:

I built a desk notifier on an ESP32-C3 SuperMini (USB-C, 3.3 V logic).
Hardware and pins:
- SG90 servo: signal GPIO10, powered from USB 5V.
  It opens a hinged flap. Move it slowly (~2 s per move) and detach it when still.
- WS2812 LED stick, 8 LEDs: DIN GPIO4, 5V. It glows through 1 mm of orange plastic.
- MX switch (the button): one leg GPIO3 with internal pull-up, the other leg GPIO6
  driven LOW as its ground.
- Passive 12 mm buzzer: GPIO5 to GND (needs a PWM tone, not just on/off).
Avoid GPIO 2, 8, 9 (strapping) and 20, 21 (UART0).
Write firmware that: opens the flap and breathes a colour on the LEDs when an event
arrives over Wi-Fi (e.g. a webhook or MQTT message), chimes on the buzzer, closes the
flap when I tap the button, snoozes on a double tap and mutes on a long hold.
Include a way to calibrate the closed and open servo positions and store them.
Keep Wi-Fi and keys in a separate secrets file.
Tip Flash over USB first, then use over-the-air updates. Test one part at a time: Wi-Fi and logs, then the button, the LEDs, the buzzer and last the servo (with the horn off). Check pin numbers against the wiring table.
Note Keep Wi-Fi passwords, API keys and tokens out of code you share. Use a secrets file.

Ideas

  • AI assistant notifier: open when a coding agent or chat assistant is waiting for your reply; press to dismiss.
  • Doorbell or parcel alert from Home Assistant.
  • Meeting reminder: open five minutes before a calendar event, colour by calendar.
  • Build or CI status: green glow on success, red on failure.
  • Pomodoro: open with a chime when the break starts, press to start the next session.
  • Message waiting: a colour per person or app.
For print-file buyers

Skip this section if you bought the kit: the printed parts are supplied. If you bought the digital files, follow the settings supplied with your download. The plate layout below describes the pictured reference print.

Print time
2h 28m
Filament
84 g PLA+
Plates
3 (one colour swap)

Print time is the slicer estimate for a Bambu Lab P1S; Bambu Studio's GUI may show more. No AMS needed: the base's colour change is a manual pause.

Bambu Lab P1S, 0.4 mm nozzle · 0.20 mm layers · 2 walls · 4 top / 3 bottom · 20 % cubic · no supports · auto brim · Textured PEI · eSUN PLA+, black and orange (#FF6A13).

Plate 1

Plate 1 · Black, then orange

1h 20m45.6 g1 part

Base

Colour swap at layer 146 (z 29.2 mm) The printer pauses before layer 146. Unload the black, load the orange, purge until it runs clean, then resume. Only the collar’s upper part is above the swap, and the first orange layer is inside the collar, so a purge smear stays hidden.
Plate 2

Plate 2 · Black

1h 02m36.0 g6 parts

Split top flap, Split top back, Horn tip, C3 frame, Servo cradle, Power bus holder

Plate 3

Plate 3 · Orange

6m2.1 g1 part

Button

Orange, the same as the base’s band. Prints top down.