Three.js ConfBack to the 3D assemblyAssembly

THREEJS.PARIS BADGE · WORKSHOP

Assembly
& soldering guide.

Pin-by-pin wiring and the complete assembly order, from the bare shell to a closed, flashed badge. Applies to the Medium (66 × 134) enclosure — identical for Short/Long, only the battery model and its placement change.

ESP32-S3 DevKitC N16R8GC9B72 2.1″ 360×360 SPI displayTP4056 + boost 5 V USB-CLiPo 505060 · 2000 mAh3 × 6×6×5 switches

0 · Materials & tools

AWG 28-30 silicone wire — lengths PER ROUTE (build feedback: uniform 10-12 cm = impossible to close!): display→ESP 5-6 cm · stripboard→ESP 7-8 cm · TP OUT→ESP 6-7 cm · battery→TP 5 cm · buttons→stripboard 3-4 cm. Close it “like a book”, hinge on the cable-window side; NOTHING runs over the ESP; bundle wires by destination (kapton every 3 cm). 4 × 100 kΩ resistors, 4 × M2 brass inserts, 4 × M2×12 countersunk screws (12 mm required since the front was thickened to 8.75 — M2×10 only bites ~1.2 mm into the insert), Ø3 × 29.4 mm steel rod (strap), thin double-sided tape (battery), CA glue (caps). Tools: iron + fine tip, solder, Ø1.5-2 heat-shrink, wire stripper, hobby knife (membranes), iron for inserts.

1 · Wiring — overview

USB-C ──▶ TP4056 ──B+/B−──▶ LiPo battery (505060) │ └──OUT+ ──▶ DevKit 5V pin OUT− ──▶ GND │ └─(on-board regulator)─▶ 3V3 ─▶ display VCC
USB-C charging TP4056 + boost 5 V B+ B− OUT+ OUT− LiPo battery 505060 tabs pointing UP red = B+ · black = B− ESP32-S3 DevKit red → 5V pin · black → GND IN+ pad (on the BACK) → stripboard strip 5 (blue)
Fig. 1 — Power: the OUT+/OUT− pair goes straight to the DevKit 5V/GND pins (power return), never through the stripboard.

⚠ Never do this

Never plug in the DevKit’s native USB: GPIO 19/20 (D−/D+) are used as buttons. All flashing goes through Wi-Fi OTA.

Never wire B+ straight to a GPIO: 4.2 V > 3.6 V absolute maximum. Always through the 100 k / 100 k divider.

• Respect battery polarity at the TP4056 (B+ / B−) — a reversal destroys the protection circuit.

Available wire palette: red black yellow green blue. Duplicates get a black marker ring near each end (dashed on the diagrams). Display: 10-way 1.27 mm pitch rainbow ribbon (QWORK) soldered as one piece — every signal has its own colour, no rings needed (see Fig. 2).

GC9B72 display (4-wire SPI) — 10-way ribbon

The ribbon is soldered whole and in the module’s pad order (it stays flat, no crossing). Only the white wire (SDO) is left loose — it lands right in front of GPIO 46 (pin left empty): cut it flush. On the ESP side the GPIOs are chosen so the ribbon covers header rows 13 to 20, contiguous and uncrossed; brown continues 2 rows down to GND (skipping 5V), only red goes back up to 3V3 at the top of the header. ⚠ Badges wired before 14/08: old mapping SCLK 12 / MOSI 11 / DC 13 / RST 14 → rework those 4 wires on the ESP side to the new standard (single firmware).

Display pad (module order)ESP32-S3Ribbon wireNote
GNDGNDbrown
VCC3V3reddisplay logic supply
SCL (= SCLK)GPIO 14orangeSPI 40 MHz
SDA (= MOSI)GPIO 13yellow
RSTGPIO 12green
DCGPIO 11blue
CSGPIO 10purple
BLGPIO 9greybacklight — switched off in sleep, not tied to 3V3 directly · badges 1-3 wired to GPIO 4, still supported (both pins are driven)
SDO— not wiredwhiteunused SPI output (display is write-only)
TEGPIO 3blacktearing sync (59.5 Hz)
GC9B72 DISPLAY ESP32-S3 GNDGNDVCC3V3SCL (SCLK)GPIO 14SDA (MOSI)GPIO 13RSTGPIO 12DCGPIO 11CSGPIO 10BLGPIO 9SDOnot wiredTEGPIO 3
Fig. 2 — Display: 10-way rainbow ribbon soldered in the module’s pad order (brown → black). Dashed = SDO (white), not wired on the ESP side. Cut length: 6 cm.

Buttons (6×6×5 switches) — 4 wires

ButtonESP32-S3ColourRole
Up (prev)GPIO 20blueprevious · held at power-on = OTA mode
Down (next)GPIO 19greennext
CentreGPIO 21yellowshort = menu/action · 2 s hold = power off · wake
Common ×3GNDblackone wire per switch to the stripboard GND strip (internal pull-ups)

The other leg of each switch goes to its GPIO. The wires exit through the upper-left cable window of the ESP wall.

Power / charging — TP4056

TP4056ToColourNote
B+Battery +redbattery tabs pointing up
B−Battery −black
OUT+DevKit 5Vred5 V boost output
OUT−GNDblack

Battery gauge (optional but recommended) — 4 × 100 kΩ

SignalCircuitESP32-S3Note
Battery levelB+ → 100 k → midpoint → 100 k → GNDGPIO 1 at the midpointdivides 4.2 V max down to 2.1 V
Charge detectionTP4056 VBUS (5 V USB) → 100 k → midpoint → 100 k → GNDGPIO 2 at the midpointshows the charging bolt

Without these dividers the badge still works and simply shows --% in the menu.

Stripboard tab — GND bus + divider networks

Cut 5 strips × 8 holes (12.7 × 20.3 mm) from the Rademacher board (paper-based: score with a knife along the holes, snaps cleanly). It sits in the lipped seat at the bottom right of the front shell (dab of glue or friction fit). The 4 resistors are soldered lying flat (~4 mm tall), straddling neighbouring strips — upright (~11 mm) they exceed the 5.4 mm available under the back (build feedback 2026-08-13). Nothing floats loose in the enclosure anymore.

StripNetWhat gets soldered there
1Battery B+wire from TP4056 B+ · R1 leg
2Midpoint 1wire to GPIO 1 · R1 and R2 legs
3GND (common bus)wire to ESP GND · GND of the 3 buttons · display GND · R2 and R4 legs
4Midpoint 2wire to GPIO 2 · R3 and R4 legs
5TP4056 VBUSwire from the TP4056 IN+ pad — on the back of the board · R3 leg. ⚠ NOT “VO+” (boost output, always live). Test: 0 V unplugged / ~5 V with USB plugged in
UPDOWNCENTRE ESP32-S3 GPIO 20 GPIO 19 GPIO 21 GPIO 1 GPIO 2 GND 1 · B+2 · GPIO 13 · GND (bus)4 · GPIO 25 · VBUS R1R2R3R4 ← B+ (TP4056) ← VBUS (TP4056) stripboard 5 strips × 8 holes — resistors soldered then laid flat
Fig. 3 — Buttons and stripboard: one black wire per switch joins the GND strip; the divider networks live on the stripboard, only two sense wires (yellow/green) go up to the ESP. (Capacitors removed from the BOM: ADC filtering is done in software.)

R1 = R2 = R3 = R4 = 100 kΩ, straddling neighbouring strips then laid flat. (No capacitors: filtering is done in software — validated on the first 2 badges.) The GND strip in the middle: everything surrounds it and only ever hops one strip. Wires exit through the notches in the sides of the seat.

2 · Assembly order

  1. Prepare the shells

    Punch out the 7 sacrificial membranes of the front with a knife/fine screwdriver: 3 button counterbores + 4 screw seats. Set the 4 M2 inserts with the iron (~200 °C) into the bosses of the back — straight and flush.

  2. Prepare the wires

    Cut and tin all the wires (10-12 cm). Cut the 5 strips × 8 holes stripboard tab, solder the 4 resistors then lay their bodies flat (total height ~4 mm: the enclosure layer is 5.4 mm), solder the wires (see dedicated table), then clip/glue it into its seat. Tin the display and TP4056 pads.

  3. Fit the switches

    Insert each switch from the outside through its Ø8.8 hole in the front, plunger facing forward, into its cradle. Fold the legs backwards: they come out through the slots of the support plates. Solder after insertion: the common GND wire daisy-chains all three, then one signal wire per switch. Route the bundle to the upper-left window

    solder here, AFTER insertion (both legs) support ceiling + pillars cradle walls switch 6×6 plunger down inserted from the OUTSIDE through the Ø8.8 hole front shell (printed face down) cap glued on the plunger (outside)
    Fig. 4 — Section through a button station: the switch enters through the front, its folded legs pass through the ceiling slots and are soldered on the inside.
  4. Seat the display

    Present the display in its ring, connector tab pointing down (the ring notch is made for it). It rests on the lower stop on both sides. Solder the ribbon (10 wires in pad order, white not wired) and pass it through the windows of the ESP walls.

  5. Install the TP4056

    Slide the board into its pocket at the bottom of the front, USB-C connector in the edge opening. It rests on the support wall and locks under the two retainers. Solder B+/B−/OUT+/OUT− (access window in the middle, between the retainers).

  6. Place the battery (back shell)

    Battery lying landscape on its shelf, above the screw bosses, tabs pointing up. Fix it with double-sided tape. Route the wires to the TP4056 through the space above the battery.

  7. Seat the ESP32 (back shell)

    The DevKit sits between its two walls, wedged at the top under the band. Connect in order: common GND, 5V (from OUT+), display, buttons, gauge dividers. Check that no wire crosses the mating plane.

  8. Test before closing

    See the checklist below — everything is tested with the enclosure open.

  9. Close the enclosure

    Drop the Ø3 steel rod into its strap cradle (straddling both half-shells). Bring the shells together tucking the wires in, drive the 4 × M2×10 countersunk screws. Thread the strap through the slot and around the bar.

  10. Finishing

    Glue the 4 screw caps into their counterbores (CA, hollow square visible). Glue the 3 button caps onto the plungers (dab of CA inside the sleeve recess). Check the click of every button.

3 · Pre-closing checklist

4 · Flashing (no cable)

Menu → OTA flash mode (or hold “up” at power-on). Connect to the Wi-Fi badge-threejs / threejs2026 then:

pio run -e ota -t upload # IP 192.168.4.1

Leave flash mode without flashing: long press on the centre button.

Quick reminders — battery: 5 mm thick max; the speaker’s photo/menu pairing is set in the firmware (tools/photo2header.py); ~8-10 h runtime with the 505060, ~2 h 30 recharge at 1 A.