imrishabh18/nema-23-stepper-controller
A 57 mm four-layer RP2040 NEMA23 stepper-controller PCB with USB‑C/USB‑PD power input, protected motor rail, DRV8452 dual-winding driver, bidirectional current sensing, temperature/enable interlock, optional magnetic encoder, RGB LED and buzzer status indicators, and motor/test connectors.
- Version
- 1.2.3
- License
- unset
- Stars
- 0
power-copper.tsx
type Point = string | {x:number,y:number}
type BoardTraceProps = { name:string; from:string; to:string; thickness:number; pcbPath:Point[] }
function BoardTrace(props: BoardTraceProps) {
const port = props.from.replace(/ /g, "")
let xy: [number,number] | undefined
const pin = port.match(/^\.DRIVER>\.pin(\d+)$/)
if (pin) {
xy = [8,-9]
}
for (const o of outputs) if(port.startsWith(".BUS_"+o.net+">")) xy=[o.x,-15.2]
for (const v of powerVias) if(port.startsWith("."+v.name+">")) xy=[v.x,v.y]
const fixed: Record<string,[number,number]> = {
".VM_IN>.bottom":[24,16],
".F1>.pin2":[10.5,17],
".USB_IN_L>.bottom":[6.6,19.7],
".USB_IN_R>.bottom":[11.4,19.7],
".USB_FUSE_IN>.top":[9.0375,18.2],
".EF_IN>.top":[10,13.5],
".EF_OUT>.top":[16,13.5],
".D_REVERSE>.cathode":[20,16],
".D_TVS>.cathode":[22,8],
".B_PLUS_CROSS>.bottom":[16,-19.4],
".A_PLUS_CROSS>.bottom":[-3.1788,-19.4],
".R_PHASE_A>.pin2":[-1.7,-18],
".R_PHASE_B>.pin2":[14,-17.4],
}
if(port.startsWith(".J_USB_POWER>")) xy=[9,22.9]
if(port.startsWith(".U_EFUSE>")) xy=[13,12.5]
xy ??= fixed[port]
if(!xy) throw new Error("Missing board coordinate for "+props.from)
const [x,y]=xy
return <trace {...props} pcbPathRelativeTo={props.from}
pcbPath={props.pcbPath.map(p=>typeof p==="string"?p:port.startsWith(".J_USB_POWER")||port.startsWith(".D_REVERSE")||port.startsWith(".R_PHASE_A")?{x:x-p.x,y:y-p.y}:port.startsWith(".D_TVS")?{x:-(p.y-y),y:p.x-x}:{x:p.x-x,y:p.y-y})} />
}
// High-current paths are explicit. Fine-pitch escapes share current between
// all three output pins; 1.2 mm trunks require a 2 oz outer-copper stackup.
const outputs = [
{net:"A_DRIVE",pins:[4,5,6],x:3.8725,to:".R_PHASE_A > .pin1",tx:2},
{net:"A_MINUS",pins:[7,8,9],x:5.7775,to:".J_MOTOR > .pin2",tx:6.750066},
{net:"B_MINUS",pins:[14,15,16],x:10.2225,to:".J_MOTOR > .pin4",tx:10.2225},
{net:"B_DRIVE",pins:[17,18,19],x:12.1275,to:".R_PHASE_B > .pin1",tx:12.1275},
]
const powerVias = [
{name:"VM_LEFT",x:1.9675,y:-14.4,pins:[2]},
{name:"VM_MID",x:8,y:-15,pins:[11,12]},
{name:"VM_RIGHT",x:14.0325,y:-14.4,pins:[21]},
]
export function PowerCopper() { return <>
{outputs.map(o=><group key={o.net} pcbX={0} pcbY={0}>
<via name={`BUS_${o.net}`} pcbX={o.x} pcbY={-15.2} holeDiameter={0.4} outerDiameter={1}
fromLayer="top" toLayer="bottom" connectsTo={`net.${o.net}`} />
{o.pins.map((p,i)=><BoardTrace key={String(p)} name={`${o.net}_${p}`} from={`.DRIVER > .pin${p}`} to={`.BUS_${o.net} > .top`}
thickness={0.28} pcbPath={[{x:o.x+(i-1)*0.635,y:-14.1},{x:o.x,y:-15.2}]} />)}
<BoardTrace name={`${o.net}_TRUNK`} from={`.BUS_${o.net} > .top`} to={o.to} thickness={1.2}
pcbPath={o.net==="B_DRIVE"||o.net==="A_DRIVE"?[o.to]:[{x:o.x,y:-16.2},{x:o.tx,y:-20},o.to]} />
</group>)}
{powerVias.map(v=><group key={v.name} pcbX={0} pcbY={0}>
<via name={v.name} pcbX={v.x} pcbY={v.y} holeDiameter={0.6} outerDiameter={1.1}
fromLayer="top" toLayer="bottom" connectsTo="net.VM" />
{v.pins.map(p=><BoardTrace key={String(p)} name={`${v.name}_${p}`} from={`.DRIVER > .pin${p}`} to={`.${v.name} > .top`}
thickness={0.28} pcbPath={[`.${v.name} > .top`]} />)}
</group>)}
<BoardTrace name="VM_LEFT_BUS" from=".VM_LEFT > .bottom" to=".VM_MID > .bottom" thickness={1.5}
pcbPath={[{x:1.9675,y:-17.5},{x:8,y:-17.5},".VM_MID > .bottom"]} />
<BoardTrace name="VM_RIGHT_BUS" from=".VM_MID > .bottom" to=".VM_RIGHT > .bottom" thickness={1.5}
pcbPath={[{x:8,y:-17.5},{x:14.0325,y:-17.5},".VM_RIGHT > .bottom"]} />
<via name="VM_IN" pcbX={24} pcbY={16} holeDiameter={0.8} outerDiameter={1.6}
fromLayer="top" toLayer="bottom" connectsTo="net.VM" />
<BoardTrace name="VM_MAIN" from=".VM_RIGHT > .bottom" to=".VM_IN > .bottom" thickness={2}
pcbPath={[{x:14.0325,y:-17.5},{x:24,y:-17.5},".VM_IN > .bottom"]} />
<BoardTrace name="VM_BULK" from=".VM_IN > .bottom" to=".C_BULK > .pin1" thickness={2}
pcbPath={[{x:24,y:9.5},{x:18.5,y:9.5},{x:18.5,y:6.5},{x:10.5,y:6.5},".C_BULK > .pin1"]} />
<via name="USB_IN_L" pcbX={6.6} pcbY={19.7} holeDiameter={0.6} outerDiameter={1.1} fromLayer="top" toLayer="bottom" connectsTo="net.VIN" />
<via name="USB_IN_R" pcbX={11.4} pcbY={19.7} holeDiameter={0.6} outerDiameter={1.1} fromLayer="top" toLayer="bottom" connectsTo="net.VIN" />
<via name="USB_FUSE_IN" pcbX={9.0375} pcbY={18.2} holeDiameter={0.6} outerDiameter={1.1} fromLayer="top" toLayer="bottom" connectsTo="net.VIN" />
{[7,8,17,18].map(p=><BoardTrace key={p} name={`USB_VBUS_${p}`} from={`.J_USB_POWER > .pin${p}`}
to={p<10?".USB_IN_L > .top":".USB_IN_R > .top"} thickness={0.28}
pcbPath={[p<10?".USB_IN_L > .top":".USB_IN_R > .top"]} />)}
<BoardTrace name="USB_VIN_L" from=".USB_IN_L > .bottom" to=".USB_FUSE_IN > .bottom" thickness={1.2} pcbPath={[".USB_FUSE_IN > .bottom"]} />
<BoardTrace name="USB_VIN_R" from=".USB_IN_R > .bottom" to=".USB_FUSE_IN > .bottom" thickness={1.2} pcbPath={[".USB_FUSE_IN > .bottom"]} />
<BoardTrace name="VIN_FUSE" from=".USB_FUSE_IN > .top" to=".F1 > .pin1" thickness={1.5} pcbPath={[".F1 > .pin1"]} />
<via name="EF_IN" pcbX={10} pcbY={13.5} holeDiameter={0.6} outerDiameter={1.1} fromLayer="top" toLayer="bottom" connectsTo="net.VFUSED" />
<via name="EF_OUT" pcbX={16} pcbY={13.5} holeDiameter={0.6} outerDiameter={1.1} fromLayer="top" toLayer="bottom" connectsTo="net.VSWITCHED" />
{[1,2].map(p=><BoardTrace key={p} name={`EF_INPUT_${p}`} from={`.U_EFUSE > .pin${p}`} to=".EF_IN > .top" thickness={0.25} pcbPath={[".EF_IN > .top"]} />)}
{[17,18].map(p=><BoardTrace key={p} name={`EF_OUTPUT_${p}`} from={`.U_EFUSE > .pin${p}`} to=".EF_OUT > .top" thickness={0.25} pcbPath={[".EF_OUT > .top"]} />)}
<BoardTrace name="FUSE_EFUSE" from=".F1 > .pin2" to=".EF_IN > .top" thickness={1.2} pcbPath={[{x:12,y:15.5},{x:10,y:15.5},".EF_IN > .top"]} />
<BoardTrace name="EFUSE_DIODE" from=".EF_OUT > .top" to=".D_REVERSE > .anode" thickness={1.2} pcbPath={[{x:16,y:16},".D_REVERSE > .anode"]} />
<BoardTrace name="DIODE_VM" from=".D_REVERSE > .cathode" to=".VM_IN > .top" thickness={2}
pcbPath={[".VM_IN > .top"]} />
<BoardTrace name="TVS_VM" from=".D_TVS > .cathode" to=".VM_IN > .top" thickness={1.5}
pcbPath={[{x:24,y:10.15},".VM_IN > .top"]} />
{[3,10,13,20].map(p=>{
const x=1.3325+(p-1)*0.635
return <group key={`pgnd${p}`} pcbX={0} pcbY={0}>
<via name={`PGND_${p}`} pcbX={x} pcbY={-11.2} holeDiameter={0.4} outerDiameter={0.8}
fromLayer="top" toLayer="bottom" connectsTo="net.GND" />
<BoardTrace name={`PGND_ESCAPE_${p}`} from={`.DRIVER > .pin${p}`} to={`.PGND_${p} > .top`} thickness={0.28}
pcbPath={[`.PGND_${p} > .top`]} />
</group>
})}
{/* Bottom-layer crossover preserves the reference A+, A-, B+, B- pin order. */}
<via name="B_PLUS_CROSS" pcbX={16} pcbY={-19.4} holeDiameter={0.6} outerDiameter={1.1}
fromLayer="top" toLayer="bottom" connectsTo="net.B_PLUS" />
<via name="A_PLUS_CROSS" pcbX={-3.1788} pcbY={-19.4} holeDiameter={0.6} outerDiameter={1.1} fromLayer="top" toLayer="bottom" connectsTo="net.A_PLUS" />
<BoardTrace name="A_SHUNT_TO_CROSS" from=".R_PHASE_A > .pin2" to=".A_PLUS_CROSS > .top" thickness={1.2} pcbPath={[".A_PLUS_CROSS > .top"]} />
<BoardTrace name="A_SHUNT_TO_JST" from=".A_PLUS_CROSS > .bottom" to=".J_MOTOR > .pin1" thickness={1.2} pcbPath={[".J_MOTOR > .pin1"]} />
<BoardTrace name="B_SHUNT_TO_CROSS" from=".R_PHASE_B > .pin2" to=".B_PLUS_CROSS > .top" thickness={1.2} pcbPath={[".B_PLUS_CROSS > .top"]} />
<BoardTrace name="B_PLUS_TO_JST" from=".B_PLUS_CROSS > .bottom" to=".J_MOTOR > .pin3" thickness={1.2}
pcbPath={[{x:9.249934,y:-19.4},".J_MOTOR > .pin3"]} />
{[5,6,19,20].map(p=><BoardTrace key={p} name={`USB_GND_${p}`} from={`.J_USB_POWER > .pin${p}`}
to={p<10?".J_USB_POWER > .pin2":".J_USB_POWER > .pin1"} thickness={0.28}
pcbPath={[p<10?".J_USB_POWER > .pin2":".J_USB_POWER > .pin1"]} />)}
<BoardTrace name="MOTOR_GROUND_RETURN" from=".J_USB_POWER > .pin1" to=".C_BULK > .pin2" thickness={1.95}
pcbPath={[{x:15.5,y:21},{x:18.5,y:18.3},{x:26.5,y:18.3},{x:26.5,y:7},".C_BULK > .pin2"]} />
</> }