An Adom molecule LED nameplate. Evan's name is spelled out by 66 green 0603 LEDs on a 5 × 7 dot-matrix grid, powered from a USB-C receptacle on the east edge. Plug it into a phone charger and it lights up.
The viewer loads when it scrolls into view, about 15 MB. The guided walkthrough starts on its own, seven steps, and the PCB / Schematic / Parts tabs are live. Open it full screen.
| Board | 96 × 44 mm nominal, 96.4 × 44.4 mm real (nominal wing adds 0.2 mm per side), 2 layer |
|---|---|
| Molecule | type="4pin", MachinePinMediumStandard, absolute sizing, rounded edges |
| Letters | 66 LEDs, 5 × 7 glyphs, 3 mm pixel pitch, 3 mm letter gap, 69 mm of text |
| Power in | USB-C on the east edge, mouth 0.4 mm proud of the board edge |
| Draw | ~400 mA at 5 V, 2.0 W, all 66 LEDs lit |
| Components | 141 total: 66 LEDs, 68 resistors, 2 capacitors, 1 connector, 4 machine pins |
| DRC | Zero errors in circuit.json. adom-tsci lint: routing, CAD models and USB-C geometry all pass; the one open item is the four machine-pin symbols, see below. |
Every line is an Adom Basic Part, so the whole board builds off reels already loaded on the PnP line.
| Refdes | Qty | Part | Package | Notes |
|---|---|---|---|---|
| D0–D65 | 66 | IN-S63BTG Inolux | 0603 | Green InGaN, 527 nm dominant, Vf 3.2 V typ @ 20 mA, 560 mcd, 25 mA max |
| R0–R65 | 66 | CR0402-FX-3300GLF Bourns | 0402 | 330 Ω 1%, one per LED, sets ~6 mA |
| J1 | 1 | TYPE-C-31-M-12 | SMD 16P | LCSC C165948. Adom part page |
| R_CC1, R_CC2 | 2 | CR0402-FX-4701GLF Bourns | 0402 | 4.7 kΩ Rd pulldowns, tell the charger to enable VBUS |
| C_BULK | 1 | CL21A106KOQNNNG Samsung | 0805 | 10 µF X5R, inrush when 66 LEDs light at once |
| C_HF | 1 | 0402B104J160CT Walsin | 0402 | 100 nF X7R, high frequency decoupling |
| MP1–MP4 | 4 | MachinePinMediumStandard | — | Workcell fixturing, mechanical only, no electrical function |
FONT in src/lib/index.tsx holds one 5 × 7 glyph per character
and TEXT = "EVAN" selects them. A generator walks each glyph's lit pixels and
emits one <led> plus one <resistor> per pixel. Changing
the name is a one-line change; a longer name needs BOARD_W grown to keep the
16 mm USB-C reservation on the east edge.
IN-S63BTG is an InGaN part: Vf 3.2 V typ at 20 mA, dropping to about 3.0 V
at single-digit mA. From a 5 V rail:
(5 V − 3.0 V) / 330 Ω = 6.1 mA per LED
66 LEDs × 6.1 mA = ~400 mA, 2.0 W
That is inside what a source advertising Default USB Power will hand out, so it runs off a phone charger without negotiation. At 560 mcd @ 20 mA these are bright parts, so 6 mA is a comfortable desk brightness rather than a dim one.
There is deliberately no power LED. The letters are the power indicator: lit means 5 V is present. And because each LED is fused by its own resistor, one LED dying does not affect the others. Replace the LED and its 330 Ω pair.
Worth recording, because it bit this build and will bite the next one.
The wrapper this board inherited placed the receptacle's 3D body 2.09 mm forward of its
own pad row, hanging 2.5 mm off the board edge. The cause is that tscircuit anchors
cadModel.positionOffset at pcb_component.center, which is the
bounding box of pads and holes, not the pad row. Every hole in this footprint sits on
the mouth side, so that centre is 2.7366 mm forward of the pads and the offset inherits the
error.
adom-tsci lint does not catch it. It derives the mouth vector from
cad.rotation.z, so the error cancels out of its own check and it reports a
healthy body_fwd.
The constants are re-derived in src/lib/UsbCReceptacle.tsx as
BODY_FORWARD_MAG = MODEL_ORIGIN_TO_BACK − FOOTPRINT_CENTER_FROM_PADS
USB_C_MOUTH_FROM_PADS = MODEL_ORIGIN_TO_BACK + MODEL_ORIGIN_TO_MOUTH
with the model numbers measured off the J1 node of a built 3d.glb, the
artifact that actually gets rendered, so it cannot disagree with what you see. The result:
shell back face exactly on the pad row, mouth 0.4 mm proud, easternmost copper 1.68 mm
inside the edge.
src/scripts/check-usbc.mjs re-runs that measurement against the GLB and exits
non-zero if either lands outside tolerance. Step 2 of the walkthrough above flies the camera
to the receptacle so you can see the seating for yourself.
Full vector versions: schematic.svg (141 symbols) and pcb.svg. Both are also tabs inside the interactive viewer above.
size="96x44 absolute" gives a real outer edge of 96.4 × 44.4 mm.MachinePinMediumStandard, fixture the board
into the standard Adom workcell. No electrical function.circuit.json for
pcb_pad_pad_clearance_error.traces: 208 routed / 210 declared is not a failure. The autorouter merges
some net members into shared routes without emitting a per-source-trace row. Every port still
lands on copper of the right net, so verify geometrically rather than by counting.schX/schY on only some parts. Giving J1 explicit
schematic coordinates disabled tscircuit's auto-layout for everything else and stacked all
141 symbols at the origin. Either place every part or place none.localStorage read. The wiki serves this content under a CSP sandbox with no allow-same-origin, so the document has a null origin and any storage access throws a SecurityError. The viewer reads storage during init, and because Adom3DViewer.init() is not awaited, that throw became an unhandled rejection that abandoned everything after it: no light rig, no .env IBL, no render loop, no camera framing, and a getCamera() returning null, which in turn made every walkthrough camera fly bail on its first guard. Nothing was logged and engine.getFps() still reported 60. An in-memory storage shim ahead of the bundle fixes all of it at once. Two genuine CSP limits remain and are handled separately: GLB textures ship as data: URIs because blob: is refused, and the 13 MB bundle ships as parts because render/ 413s over ~4 MB. Full writeup in the export skill.schX/schY slot, but the machine pins are
emitted by <Molecule> as
jsx(MachinePin, {type, name, pcbX, pcbY}), and
MachinePinOrContact in @tsci/adom-inc.library destructures only
{portHints, pcbX, pcbY, name}, dropping any schematic coordinates passed in. So
they stack at the origin and adom-tsci lint reports four overlapping symbols
that no caller can fix. Cosmetic on a board where the pins carry no net. Filed against the
molecule and library packages.circuit-json
under @tscircuit/cli produced Export named
'getRotationBetweenPcbPin1Locations' not found. The fix is a clean
rm -rf node_modules bun.lock && bun install, not a patch.TEXT plus the glyphs in FONT are the whole
design. Another four-letter name is a one-line change.LED_MPN for another Adom 0603 LED:
IN-S63BTA amber, IN-S63BT5B blue, IN-S63BTR red,
IN-S63BT5UW white. Re-derive R_VALUE for that part's forward voltage.
Red and amber are roughly 2.0 V parts and want about 470 Ω, not 330 Ω.tar xzf evan-led-nameplate-source.tar.gz
cd src && bun install
bunx tsci build lib/index.tsx --glbs --svgs --3d-png --pcb-png
node scripts/check-usbc.mjs # USB-C geometry, measured off the GLB
adom-tsci lint # DRC, routing, schematic overlap
adom-tsci start . --texture-resolution 4096
adom-tsci stop # when done, so tsci dev processes do not leak
Source, to recreate the molecule
plan.md, the original brief, every refinement, and what was deliberately left outevan-led-nameplate-source.tar.gz, full project source: lib/, scripts/, configs, walkthroughBuild outputs
board.glb, 3D model with a 4096 px baked board texturepcb.svg, copper, silkscreen and drill layersschematic.svg, full schematic, 141 symbolsviewer/, the self-contained interactive viewer embedded aboveAuthored in tscircuit (TSX) with
adom-tsci, autorouted by the tscircuit
autorouter. @tsci/adom-inc.molecule 1.1.15,
@tsci/adom-inc.library 1.2.1, tscircuit 0.0.2375. Walkthrough generated by
adom-tsci walkthrough-gen from circuit.json. Part of the Adom LED
nameplate family alongside
brianna-led-nameplate and
alex-nameplate.
Designed by Adom in Fort Worth, Texas. 2026-08-20.