Build guide

Buddybox

A 77 mm ESP32-S3 desk box with a record knob and a tonearm: the tonearm is a push button, the knob a rotary encoder, with a mic, a speaker and an LED glow inside. Bring your own firmware.

Buddybox assembled

Your kit contains the printed parts, electronics, screws, pivot pin, four feet, headers, jumpers, wire and heat-shrink. 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
13
Difficulty
Intermediate: basic soldering
Build time
about 2 h

Parts checklist

Printed parts

Housing and brackets

Turntable controls

Light plinth

All 13 printed parts

Electronics

Fasteners

SizeQtyWhere
M3 × 64Base, into the body from the sides
M3 × 62Encoder bracket, from the top of the lid
M3 × 84Lid corners
M3 × 102Hinge, from inside the lid
M3 × 52Switch bracket, from the top of the lid
M3 nut1Tonearm weight, already embedded in the supplied part
M2 × 4–62Microphone posts
M2 × 4–62Amplifier posts
Supplied pivot pin, 1.75 mm × ~15 mm1Tonearm pivot pin
Small self-adhesive rubber feet, about 8–10 mm4Under the plinth

Screws thread straight into printed pilot holes. Use socket head screws. No inserts, magnets or glue.

Supplied wire and buyer tools

Wiring

Every module goes straight to the S3, no breadboard. Check your board’s silkscreen first, because some clones swap the header rows.

ModulePinESP32-S3Wire
INMP441 micSCKGPIO 4Dupont
WSGPIO 5
SDGPIO 6
L/RGPIO 7 (drive LOW)
VDD3V3 · never 5 V
GNDGND
MAX98357A ampBCLKGPIO 15Dupont
LRCGPIO 16
DINGPIO 17
VIN5V (check USB power path)
GNDGND
GAIN, SDnot connected
+ / −speaker, screw terminal
KY-040 encoderCLK (A)GPIO 10Dupont
DT (B)GPIO 11
SWGPIO 12
+3V3
GNDGND
MX switchleg 1GPIO 13soldered
leg 2GPIO 14 (drive LOW)
8x8 WS2812DINGPIO 8soldered
5V5V (USB 5Vin)
GNDGND
Note Power. The amplifier and matrix use USB 5V. Check the power path for your exact S3 board: some versions require an IN-OUT solder jumper to expose USB power on 5Vin. Only change a jumper after identifying it in that board’s documentation. Don’t feed 5V from another supply while USB is plugged in.
Tip The matrix uses GPIO8 for data and USB 5V for power. Start at low brightness. Use the supplied panel and wiring. If the panel or connector labels differ from this guide, contact the shop before powering it. Never connect an S3 GPIO directly to 5V.

Assembly

Exploded view
The full stack, from the plinth up to the knob and tonearm.
  1. 1Prepare the electronics

    • Identify the USB-to-5Vin power path for your exact S3 board before changing any jumper. Keep USB disconnected while soldering or wiring.
    • Solder header pins on the mic and amp if needed, so they take Dupont jumpers.
    • The KY-040 has header pins: it plugs in with Dupont jumpers, no soldering.
    • Solder wires to both MX switch legs and the matrix input (DIN, 5V, GND). Cut them to fit, about 10–15 cm, long enough to reach the S3 with the lid off.
    • Screw the speaker leads into the amp’s + / − terminal.
    Tip Flash your firmware now (see below) and test everything on the bench before closing the box.
  2. 2Speaker, deck and modules

    Speaker, deck and modules

    Screws 2× M2 (amp)

    • Lay the 40 mm speaker cone down on the base over the hole field and drop the speaker ring over it.
    • Put the S3 on its back in the deck, pins and plugs up, USB-C toward the back slot.
    • Screw the amp onto its two deck posts.
    • Set the deck on the base posts.

    Electronics are drawn as simple blocks: green = boards. The speaker is hidden under the deck.

  3. 3Microphone and body

    Screws 2× M2×4–6 (mic) · 4× M3×6 (base)

    • Screw the mic onto its two posts behind the front grille, inside the body. The mic hole faces the grille.
    • Lower the body over the base and deck. Fix the base with 4× M3×6 from the sides.
    • Plug the mic and amp jumpers onto the S3.
  4. 4Lid underside: switch, encoder, hinge

    Lid underside: switch, encoder, hinge

    Screws 2× M3×5 · 2× M3×6 · 2× M3×10

    • Clip the MX switch into the switch bracket, clips facing left and right. Screw it on from the top of the lid with 2× M3×5. The tonearm hides these screws.
    • Put the KY-040 in the encoder bracket, shaft up, and clamp it with its own nut. Screw it on from the top with 2× M3×6, under where the knob goes.
    • Screw the hinge onto the top of the lid with 2× M3×10, from inside the lid up into the lugs.

    Blue = KY-040, grey = MX switch.

  5. 5Close the box

    Screws 4× M3×8

    • Plug the encoder jumpers onto the S3 and wire the switch. Route the matrix cable through the plinth’s rear notch and USB slot and connect it while the lid is open.
    • Check every connection against the wiring table. Confirm the lid holes align, the cable has enough slack and no lead is trapped. Set the lid on the body and screw it down at the corners.
  6. 6Stem cap, tonearm, ring and knob

    Stem cap, tonearm, ring and knob

    Screws supplied pivot pin

    • Press the stem cap onto the MX switch stem.
    • Set the tonearm between the hinge lugs, headshell over the stem cap. Push the supplied pivot pin through the outer lug and the hub into the tight far lug until seated.
    • Drop the grooved ring over the encoder shaft onto the lid.
    • Push the record knob onto the D-shaft.
    Tonearm on the hinge
    The tonearm on its pivot, its headshell over the stem cap.
  7. 7Plinth and feet

    Plinth and feet

    Screws 4× rubber feet

    • Lay the 8x8 matrix in the plinth, LEDs facing down. It rests on the inner ledges, 6 mm above the floor; no glue or tape needed.
    • Seat the cable in the rear notch using the route prepared before closing the lid. Check that it is not stretched or pinched.
    • Stick the feet under the plinth and stand the box in the plinth’s collar.
    Finished, top view

Make it yours: firmware

Buddybox ships without firmware. The hardware is a standard ESP32-S3 with an I2S mic, an I2S amp, a rotary encoder, a button (the tonearm switch) and the supplied LED matrix, so you can write your own. 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-S3 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 S3’s native USB-C port), then update over Wi-Fi.
  4. In Home Assistant, adopt the device under Settings › Devices & services › ESPHome with its API key.
  5. Voice: under Settings › Voice assistants, create an Assist pipeline and select it on the device. The tonearm starts listening.
  6. Controls: the knob and buttons appear as entities. Use them in automations for volume, scenes or media.

Minimal skeleton, written for this guide. Adjust it and check the ESPHome docs for your version. Add a media_player (speaker platform) to play music or announcements on it.

esphome:
  name: buddybox
  on_boot:
    priority: 800
    then:
      - output.turn_off: mic_lr      # mic L/R must be LOW (left channel)
      - output.turn_off: button_gnd  # the switch's second leg acts as ground

esp32:
  board: esp32-s3-devkitc-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: mic_lr
    pin: GPIO7
  - platform: gpio
    id: button_gnd
    pin: GPIO14

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO5
    i2s_bclk_pin: GPIO4
  - id: i2s_out
    i2s_lrclk_pin: GPIO16
    i2s_bclk_pin: GPIO15

microphone:
  - platform: i2s_audio
    id: mic
    i2s_audio_id: i2s_in
    i2s_din_pin: GPIO6
    adc_type: external
    channel: left

speaker:
  - platform: i2s_audio
    id: amp
    i2s_audio_id: i2s_out
    i2s_dout_pin: GPIO17
    dac_type: external

voice_assistant:
  microphone: mic
  speaker: amp

sensor:
  - platform: rotary_encoder
    name: Knob
    pin_a: { number: GPIO10, mode: INPUT_PULLUP }
    pin_b: { number: GPIO11, mode: INPUT_PULLUP }

binary_sensor:
  - platform: gpio
    name: Knob button
    pin: { number: GPIO12, mode: INPUT_PULLUP, inverted: true }
  - platform: gpio
    name: Tonearm
    pin: { number: GPIO13, mode: INPUT_PULLUP, inverted: true }
    on_press:
      - voice_assistant.start:
    on_release:
      - voice_assistant.stop:

light:
  - platform: esp32_rmt_led_strip
    name: Glow
    pin: GPIO8
    num_leds: 64
    rgb_order: GRB
    chipset: WS2812
    color_correct: [10%, 10%, 10%]   # start with a low brightness

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 adapt the last paragraph:

I built a desk device on an ESP32-S3 DevKitC-1 (N16R8, 16 MB flash, octal PSRAM).
Hardware and pins:
- INMP441 I2S microphone: SCK GPIO4, WS GPIO5, SD GPIO6, L/R on GPIO7 (drive LOW), VDD 3V3
- MAX98357A I2S amplifier: BCLK GPIO15, LRC GPIO16, DIN GPIO17, VIN 5V; 40 mm speaker
- KY-040 rotary encoder: CLK GPIO10, DT GPIO11, SW GPIO12 (push button), + 3V3
- Push button (MX switch): one leg GPIO13, the other leg GPIO14 (drive LOW as ground)
- 8x8 WS2812 LED matrix: DIN GPIO8, powered from USB 5V (start with low brightness; match the panel’s data-level requirements)
Mic and amp are on separate I2S buses.
Write ESPHome YAML for Home Assistant: hold the button to talk to the voice assistant,
turn the knob for volume, click it to play/pause, and show a colour on the matrix
while listening. Keep Wi-Fi and keys in secrets.yaml.
Tip Flash over USB first, then use over-the-air updates. Test one module at a time: Wi-Fi and logs, then the button, the encoder, the LEDs, the speaker (a test tone), the mic. 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

  • Push-to-talk voice assistant for Home Assistant: lights, timers, questions.
  • Music remote: knob for volume, click to play/pause, double click to skip.
  • Scene dial: turn to pick a scene, click to apply; the glow shows the colour.
  • Timer: turn to set minutes, click to start, a chime when it ends.
  • Status light: the plinth glows for the doorbell, a finished washing machine or a calendar event.
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
3h 52m
Filament
121 g PLA+
Plates
3, one colour each

Print time is the slicer estimate for a Bambu Lab P1S; Bambu Studio's GUI may show more.

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+.

Plate 1

Plate 1 · Black

2h 37m89.2 g9 parts

Body, Lid, Base, Deck, Speaker ring, Hinge, Switch (key) bracket, Encoder bracket, Stem cap

Plate 2

Plate 2 · White

26m6.7 g3 parts

Record knob, Record ring (grooved), Tonearm

Pause at 3.8 mm The print stops after the 3.8 mm layer. Drop one M3 nut flat into the hex pocket in the tonearm’s headshell, then resume. The roof seals it in. The knob pauses too, which is harmless.
Plate 3

Plate 3 · Clear

49m25.2 g1 parts

Light plinth