molecule
Steven's Nameplate: three revisions
Public Made by Adomby adom
A USB-C desk nameplate for Steven Moss (Astera Institute), built three ways and published as open experiments: a 3x5 LED board, a 5x7 LED board, and a laser-ablated silkscreen plate. Source, fab files, negative results, reproduce steps.
main
John Lauer
Three revisions with per-experiment write-ups, inline 3D viewers, sources, fab files, open-science scorecard
091a7c9
12d ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
import { Molecule } from "@tsci/adom-inc.molecule"
import { UsbCReceptacle } from "./UsbCReceptacle"
// "STEVEN" desk nameplate molecule, 5 x 7 dot-matrix edition.
// USB-C powered from the EAST (right) edge, one white 0603 LED per lit pixel,
// each with its own 470 ohm resistor (~4.3 mA, keeps the whole board under the 500 mA a USB-C source gives without negotiation). Four corner machine pins fixture it into
// the Adom workcell.
//
// Every part is an Adom Basic Part (wiki.adom.inc/adom/adom-basic-parts):
// LED IN-S63BT5UW white 0603, Inolux
// R CR0402-FX-4700GLF 470 ohm 1% 0402, Bourns
// R_CC CR0402-FX-4701GLF 4.7 kohm 1% 0402, Bourns (USB-C Rd)
// C_BULK CL21A106KOQNNNG 10 uF X5R 0805, Samsung
// C_HF 0402B104J160CT 100 nF X7R 0402, Walsin
// J1 TYPE-C-31-M-12 LCSC C165948 (wrapper copied verbatim from the adom-usbc guide)
// 5x7 font. 1 = LED. Row 0 is the top row. Five columns, not three, so N gets
// a real diagonal: a 3-wide N degenerates into a blob that reads as H.
const FONT: Record<string, string[]> = {
S: ["01111", "10000", "10000", "01110", "00001", "00001", "11110"],
T: ["11111", "00100", "00100", "00100", "00100", "00100", "00100"],
E: ["11111", "10000", "10000", "11110", "10000", "10000", "11111"],
V: ["10001", "10001", "10001", "10001", "10001", "01010", "00100"],
// The diagonal walks column 1 to 2 to 3 down the glyph.
N: ["10001", "11001", "11001", "10101", "10011", "10011", "10001"],
L: ["10000", "10000", "10000", "10000", "10000", "10000", "11111"],
A: ["00100", "01010", "10001", "10001", "11111", "10001", "10001"],
I: ["11111", "00100", "00100", "00100", "00100", "00100", "11111"],
}
const TEXT = "STEVEN"
const COLS = 5
const ROWS = 7
const PITCH = 3.0
const LETTER_GAP = 3.0
const LETTER_W = COLS * PITCH
const TEXT_WIDTH = TEXT.length * LETTER_W + (TEXT.length - 1) * LETTER_GAP
// Board: text + a left margin + ~20 mm reserved on the east edge for the
// USB-C receptacle, its CC resistors and decoupling.
const BOARD_W = Math.ceil((TEXT_WIDTH + 30) / 2) * 2
const BOARD_H = 44
const TEXT_LEFT_X = -BOARD_W / 2 + 8
const TEXT_CENTER_Y = 1
// adom-usbc guide: W/2 - 4 for a nominal-size molecule. This one is ABSOLUTE
// sized, so the real edge is 1 mm further out (W/2 + 0.2 wing, measured); W/2 - 5
// lands the guide reference numbers: overhang 2.3, hole gap 1.8, pad gap 7.0.
const USB_X = BOARD_W / 2 - 5
const PARTS_X = USB_X - 9
const R_OFFSET = 1.6 // resistor sits this far below its LED
type Pixel = { x: number; y: number; idx: number }
const PIXELS: Pixel[] = (() => {
const out: Pixel[] = []
let idx = 0
for (let li = 0; li < TEXT.length; li++) {
const g = FONT[TEXT[li]]
const x0 = TEXT_LEFT_X + li * (LETTER_W + LETTER_GAP)
for (let row = 0; row < ROWS; row++)
for (let col = 0; col < COLS; col++) {
if (g[row][col] !== "1") continue
out.push({ x: x0 + col * PITCH + PITCH / 2, y: TEXT_CENTER_Y + (3 - row) * PITCH, idx: idx++ })
}
}
return out
})()
const N = PIXELS.length
// Schematic: every symbol gets explicit coordinates. Placing SOME parts turns
// tscircuit's auto-layout off for the rest, so it is all or nothing.
const SCH_COLS = 10
const schSlot = (i: number) => ({ x: -40 + (i % SCH_COLS) * 8, y: 40 - Math.floor(i / SCH_COLS) * 3 })
export default () => (
<Molecule
type="4pin"
size={`${BOARD_W}x${BOARD_H} absolute`}
pinType="MachinePinMediumStandard"
wing="nominal"
roundEdges={true}
>
<silkscreentext text="S T E V E N" fontSize={1.3} pcbX={TEXT_LEFT_X + TEXT_WIDTH / 2} pcbY={17} layer="top" />
<silkscreentext text="Steven Moss * Astera Institute" fontSize={0.6} pcbX={TEXT_LEFT_X + TEXT_WIDTH / 2} pcbY={15.4} layer="top" />
<silkscreentext text="ADOM * FORT WORTH TEXAS" fontSize={0.5} pcbX={TEXT_LEFT_X + TEXT_WIDTH / 2} pcbY={-15} layer="top" />
<silkscreentext text="5V IN" fontSize={0.8} pcbX={PARTS_X + 2} pcbY={13.5} layer="top" />
<silkscreentext text="USB-C >>" fontSize={0.55} pcbX={PARTS_X + 2} pcbY={12.2} layer="top" />
<silkscreentext layer="bottom" text="STEVEN NAMEPLATE v2" fontSize={1.4} pcbX={0} pcbY={10} />
<silkscreentext layer="bottom" text={`${N} white 0603 LEDs * 5x7 dot matrix * one 470R per LED`} fontSize={0.55} pcbX={0} pcbY={7.5} />
<silkscreentext layer="bottom" text="Plug any USB-C phone charger into the RIGHT edge" fontSize={0.55} pcbX={0} pcbY={6} />
<silkscreentext layer="bottom" text="Designed by AI with adom-tsci * wiki.adom.inc/adom/steven-led-nameplate" fontSize={0.5} pcbX={0} pcbY={3.5} />
<silkscreentext layer="bottom" text="Adom Industries * Fort Worth, Texas * 2026" fontSize={0.5} pcbX={0} pcbY={2} />
<UsbCReceptacle name="J1" pcbX={USB_X} pcbY={0} mount="east" schX={-30} schY={-12} />
<resistor name="R_CC1" resistance="4.7k" footprint="0402" manufacturerPartNumber="CR0402-FX-4701GLF" pcbX={PARTS_X} pcbY={6} schX={-14} schY={-9} />
<resistor name="R_CC2" resistance="4.7k" footprint="0402" manufacturerPartNumber="CR0402-FX-4701GLF" pcbX={PARTS_X} pcbY={-6} schX={-14} schY={-15} />
<capacitor name="C_BULK" capacitance="10uF" footprint="0805" manufacturerPartNumber="CL21A106KOQNNNG" pcbX={PARTS_X} pcbY={0} schX={-4} schY={-12} />
<capacitor name="C_HF" capacitance="100nF" footprint="0402" manufacturerPartNumber="0402B104J160CT" pcbX={PARTS_X + 3.5} pcbY={0} schX={2} schY={-12} />
<net name="VBUS" />
<net name="GND" />
<trace from="J1.VBUS1" to="net.VBUS" />
<trace from="J1.VBUS2" to="net.VBUS" />
<trace from="J1.GND1" to="net.GND" />
<trace from="J1.GND2" to="net.GND" />
<trace from="R_CC1.pin1" to="J1.CC1" />
<trace from="R_CC1.pin2" to="net.GND" />
<trace from="R_CC2.pin1" to="J1.CC2" />
<trace from="R_CC2.pin2" to="net.GND" />
<trace from="C_BULK.pin1" to="net.VBUS" />
<trace from="C_BULK.pin2" to="net.GND" />
<trace from="C_HF.pin1" to="net.VBUS" />
<trace from="C_HF.pin2" to="net.GND" />
{PIXELS.map((p) => (
<resistor key={`R${p.idx}`} name={`R${p.idx + 1}`} resistance="470" footprint="0402"
manufacturerPartNumber="CR0402-FX-4700GLF" pcbX={p.x} pcbY={p.y - R_OFFSET} pcbRotation={180}
schX={schSlot(p.idx).x} schY={schSlot(p.idx).y} />
))}
{PIXELS.map((p) => (
<led key={`D${p.idx}`} name={`D${p.idx + 1}`} color="white" footprint="0603"
manufacturerPartNumber="IN-S63BT5UW" pcbX={p.x} pcbY={p.y}
schX={schSlot(p.idx).x + 3} schY={schSlot(p.idx).y} />
))}
{PIXELS.map((p) => <trace key={`tv${p.idx}`} from={`R${p.idx + 1}.pin1`} to="net.VBUS" />)}
{PIXELS.map((p) => <trace key={`tr${p.idx}`} from={`R${p.idx + 1}.pin2`} to={`D${p.idx + 1}.anode`} />)}
{PIXELS.map((p) => <trace key={`tg${p.idx}`} from={`D${p.idx + 1}.cathode`} to="net.GND" />)}
</Molecule>
)