abse/isv57t090-motion-controller
A 36 V-powered RP2040 motion-controller PCB that regulates 5 V, drives isolated STEP/DIR servo inputs, monitors alarms, temperature, limits and E-stop signals, and provides protected safety/field connectors.
- Version
- 0.0.67
- License
- unset
- Stars
- 0
examples/ISV57T090MotionController/ISV57T090MotionController.circuit.tsx
PCB
Schematic
import type { ChipProps, ConnectorProps } from "@tscircuit/props"
import { XL_1608SURC_06 } from "../../imports/XL_1608SURC_06"
import { Microcontroller_RP2040 } from "../../lib/Microcontroller_RP2040/Microcontroller_RP2040.circuit"
import { MMBT3904_RANGE_100_300_ } from "../../lib/PowerBoost_MT3608/imports/MMBT3904_RANGE_100_300_"
import { TMP117AIDRVR } from "../../imports/TMP117AIDRVR"
import { TPS54360DDAR } from "../../imports/TPS54360DDAR"
import { B560C_13_F } from "../../imports/B560C_13_F"
import { MWSA0603S_8R2MT } from "../../imports/MWSA0603S_8R2MT"
import { MURS160T3G } from "../../imports/MURS160T3G"
import { SMBJ36A_13_F } from "../../imports/SMBJ36A_13_F"
import { PESD3V3U1UL } from "../../imports/PESD3V3U1UL"
import { B5819W_SL } from "../../lib/Microcontroller_RP2040/imports/B5819W_SL"
/*
* Motion controller for the StepperOnline iSV57T-090 integrated servo.
*
* The motor contains its own 6 A BLDC drive and position encoder. This board
* deliberately does not attempt to reproduce that high-energy inverter. It
* supplies a deterministic 5 V, open-collector STEP/DIR interface, reads the
* isolated alarm contact, and provides the safety/limit interface around it.
*/
const fieldTrace = { thickness: "1.5mm" } as const
const powerTrace = { thickness: "0.6mm" } as const
const signalTrace = { thickness: "0.2mm" } as const
const tb2Pins = { pin1: ["pin1"], pin2: ["pin2"] } as const
const tb6Pins = {
pin1: ["PUL_P"],
pin2: ["PUL_N"],
pin3: ["DIR_P"],
pin4: ["DIR_N"],
pin5: ["ALM_P"],
pin6: ["ALM_N"],
} as const
const io6Pins = {
pin1: ["LIM_POS"],
pin2: ["LIM_NEG"],
pin3: ["ESTOP"],
pin4: ["ESTOP_RET"],
pin5: ["NTC_REMOTE"],
pin6: ["GND"],
} as const
const safe2Pins = { pin1: ["SAFE_5V"], pin2: ["SAFE_RETURN"] } as const
const swd5Pins = {
pin1: ["V3V3"],
pin2: ["SWDIO"],
pin3: ["SWCLK"],
pin4: ["GND"],
pin5: ["RUN"],
} as const
const buckPins = { pin1: ["VIN"], pin2: ["GND"], pin3: ["VOUT"] } as const
const mcuPins = {
pin1: ["VBUS"],
pin2: ["GND"],
pin3: ["V3V3"],
pin4: ["GPIO2"],
pin5: ["GPIO3"],
pin6: ["GPIO4"],
pin7: ["GPIO5"],
pin8: ["GPIO6"],
pin9: ["GPIO7"],
pin10: ["SWDIO"],
pin11: ["SWCLK"],
pin12: ["RUN"],
pin13: ["GPIO8"],
pin14: ["GPIO9"],
pin15: ["GPIO10"],
pin16: ["GPIO11"],
pin17: ["GPIO12"],
pin18: ["GPIO13"],
} as const
/** 5.08 mm-pitch 2-position power terminal, drill sized for 14 AWG. */
const PowerTerminal = (props: ConnectorProps) => (
<connector
pinLabels={tb2Pins}
manufacturerPartNumber="DG301-5.08-02P"
footprint={
<footprint insertionDirection="from_above">
<platedhole
portHints={["pin1"]}
shape="circle"
pcbX="-2.54mm"
pcbY="0mm"
outerDiameter="3.8mm"
holeDiameter="2.1mm"
/>
<platedhole
portHints={["pin2"]}
shape="circle"
pcbX="2.54mm"
pcbY="0mm"
outerDiameter="3.8mm"
holeDiameter="2.1mm"
/>
</footprint>
}
{...props}
/>
)
/** 3.5 mm-pitch pluggable field terminal for the iSV57T control connector. */
const ServoTerminal = (props: ConnectorProps) => (
<connector
pinLabels={tb6Pins}
manufacturerPartNumber="KF2EDG-3.5-06P"
footprint={
<footprint insertionDirection="from_above">
<platedhole
portHints={["pin1"]}
shape="circle"
pcbX="-8.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin2"]}
shape="circle"
pcbX="-5.25mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin3"]}
shape="circle"
pcbX="-1.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin4"]}
shape="circle"
pcbX="1.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin5"]}
shape="circle"
pcbX="5.25mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin6"]}
shape="circle"
pcbX="8.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
</footprint>
}
{...props}
/>
)
const IOTerminal = (props: ConnectorProps) => (
<connector
pinLabels={io6Pins}
manufacturerPartNumber="KF2EDG-3.5-06P"
footprint={
<footprint insertionDirection="from_above">
<platedhole
portHints={["pin1"]}
shape="circle"
pcbX="-8.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin2"]}
shape="circle"
pcbX="-5.25mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin3"]}
shape="circle"
pcbX="-1.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin4"]}
shape="circle"
pcbX="1.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin5"]}
shape="circle"
pcbX="5.25mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
<platedhole
portHints={["pin6"]}
shape="circle"
pcbX="8.75mm"
pcbY="0mm"
outerDiameter="2.7mm"
holeDiameter="1.3mm"
/>
</footprint>
}
{...props}
/>
)
/** Fail-safe, low-side driver terminal for an external contactor or safety relay.
It is intentionally not used to switch the servo's supply current directly. */
const SafetyTerminal = (props: ConnectorProps) => (
<connector
pinLabels={safe2Pins}
manufacturerPartNumber="KF2EDG-3.5-02P"
footprint={
<footprint insertionDirection="from_above">
<platedhole portHints={["pin1"]} shape="circle" pcbX="-1.75mm" outerDiameter="2.7mm" holeDiameter="1.3mm" />
<platedhole portHints={["pin2"]} shape="circle" pcbX="1.75mm" outerDiameter="2.7mm" holeDiameter="1.3mm" />
<courtyardrect width="6mm" height="4mm" />
</footprint>
}
{...props}
/>
)
const SwdHeader = (props: ConnectorProps) => (
<connector
pinLabels={swd5Pins}
manufacturerPartNumber="HDR-1x05-2.54"
footprint={
<footprint>
<platedhole
portHints={["pin1"]}
shape="circle"
pcbX="0mm"
pcbY="-5.08mm"
outerDiameter="2.2mm"
holeDiameter="1mm"
/>
<platedhole
portHints={["pin2"]}
shape="circle"
pcbX="0mm"
pcbY="-2.54mm"
outerDiameter="2.2mm"
holeDiameter="1mm"
/>
<platedhole
portHints={["pin3"]}
shape="circle"
pcbX="0mm"
pcbY="0mm"
outerDiameter="2.2mm"
holeDiameter="1mm"
/>
<platedhole
portHints={["pin4"]}
shape="circle"
pcbX="0mm"
pcbY="2.54mm"
outerDiameter="2.2mm"
holeDiameter="1mm"
/>
<platedhole
portHints={["pin5"]}
shape="circle"
pcbX="0mm"
pcbY="5.08mm"
outerDiameter="2.2mm"
holeDiameter="1mm"
/>
</footprint>
}
{...props}
/>
)
/** RECOM R-78HB5.0-0.5: 9-72 V input, regulated 5 V / 0.5 A output. */
const WideInputBuck = (props: ChipProps<typeof buckPins>) => (
<chip
pinLabels={buckPins}
manufacturerPartNumber="R-78HB5.0-0.5"
footprint={
<footprint>
<platedhole
portHints={["VIN"]}
shape="circle"
pcbX="-7.62mm"
pcbY="0mm"
outerDiameter="2.8mm"
holeDiameter="1.2mm"
/>
<platedhole
portHints={["GND"]}
shape="circle"
pcbX="0mm"
pcbY="0mm"
outerDiameter="2.8mm"
holeDiameter="1.2mm"
/>
<platedhole
portHints={["VOUT"]}
shape="circle"
pcbX="7.62mm"
pcbY="0mm"
outerDiameter="2.8mm"
holeDiameter="1.2mm"
/>
</footprint>
}
{...props}
/>
)
/** Socket footprint for an RP2040-Zero style controller module. */
const RP2040ZeroModule = (props: ChipProps<typeof mcuPins>) => (
<chip
pinLabels={mcuPins}
manufacturerPartNumber="Waveshare-RP2040-Zero"
footprint={
<footprint insertionDirection="from_above">
{[-10.16, -7.62, -5.08, -2.54, 0, 2.54, 5.08, 7.62, 10.16].map(
(pcbY, index) => (
<platedhole
key={`L${index}`}
portHints={[`pin${index + 1}`]}
shape="circle"
pcbX="-7.62mm"
pcbY={`${pcbY}mm`}
outerDiameter="2.2mm"
holeDiameter="1mm"
/>
),
)}
{[-10.16, -7.62, -5.08, -2.54, 0, 2.54, 5.08, 7.62, 10.16].map(
(pcbY, index) => (
<platedhole
key={`R${index}`}
portHints={[`pin${index + 10}`]}
shape="circle"
pcbX="7.62mm"
pcbY={`${pcbY}mm`}
outerDiameter="2.2mm"
holeDiameter="1mm"
/>
),
)}
</footprint>
}
{...props}
/>
)
export default function ISV57T090MotionController() {
return (
<board
width="78mm"
height="76mm"
title="iSV57T-090 Motion Controller"
layers={4}
thickness="1.6mm"
solderMaskColor="black"
silkscreenColor="white"
autorouter="auto_local"
autorouterEffortLevel="2x"
autorouterVersion="beta_pipeline9"
minViaHoleDiameter="0.2mm"
minViaPadDiameter="0.45mm"
>
<net name="GND" isGroundNet />
<net name="V_SERVO" isPowerNet />
<net name="V5" isPowerNet />
<net name="VSYS" isPowerNet />
<net name="V3V3" isPowerNet />
<net name="PULSE_3V3" connectsTo=".MCU > .U1 > .GPIO2" />
<net name="DIR_3V3" connectsTo=".MCU > .U1 > .GPIO3" />
<net name="ESTOP_3V3" connectsTo=".MCU > .U1 > .GPIO4" />
<net name="ALARM_3V3" connectsTo=".MCU > .U1 > .GPIO5" />
<net name="LIMIT_POS" connectsTo=".MCU > .U1 > .GPIO6" />
<net name="LIMIT_NEG" connectsTo=".MCU > .U1 > .GPIO7" />
<net name="TEMP_SDA" connectsTo=".MCU > .U1 > .GPIO8" />
<net name="TEMP_SCL" connectsTo=".MCU > .U1 > .GPIO9" />
<net name="NTC_REMOTE" connectsTo=".MCU > .U1 > .GPIO26_ADC0" />
<net name="V_SW" />
<net name="V_FB" />
<net name="V_COMP" />
<net name="V_EN" />
{/* Ground is explicitly routed by the autorouter and also receives
top- and bottom-layer copper pours after routing, including the
plated M5 mounting rings. No hand-authored PCB paths or route
hints are used. */}
<schematicsheet
name="power"
displayName="36 V Input & Control Power"
sheetIndex={1}
/>
<schematicsheet
name="motion"
displayName="iSV57T Motion Interface"
sheetIndex={2}
/>
<schematicsheet
name="controller"
displayName="RP2040 Controller & Safety"
sheetIndex={3}
/>
<PowerTerminal
name="J_PWR"
pcbX={-34}
pcbY={0}
pcbRotation={90}
schX={-9}
schY={2}
schSheetName="power"
/>
<B5819W_SL name="D_BUCK_CTRL" pcbX={3} pcbY={19} pcbRotation={90} schX={12} schY={7} schSheetName="power" />
<trace name="BUCK_CTRL_A" from="net.V5" to=".D_BUCK_CTRL > .anode" {...powerTrace} />
<trace name="BUCK_CTRL_K" from=".D_BUCK_CTRL > .cathode" to="net.VSYS" {...powerTrace} />
<fuse
name="F1"
currentRating="1.10A hold"
voltageRating="60V"
manufacturerPartNumber="1812L110/60DR"
footprint="1812"
pcbX={-27}
pcbY={4}
schX={-6.5}
schY={2}
schSheetName="power"
/>
<MURS160T3G
name="D_REV"
pcbX={-19}
pcbY={4}
pcbRotation={180}
schX={-4}
schY={2}
schSheetName="power"
/>
<SMBJ36A_13_F
name="D_TVS"
pcbX={-27}
pcbY={-4}
pcbRotation={90}
schX={0}
schY={0}
schSheetName="power"
/>
<capacitor
name="C_IN1"
capacitance="10uF"
footprint="1210"
pcbX={-21}
pcbY={-5}
schX={0}
schY={3}
schSheetName="power"
/>
<capacitor
name="C_IN2"
capacitance="100nF"
footprint="0603"
pcbX={-19}
pcbY={-8}
schX={0}
schY={5}
schSheetName="power"
/>
<TPS54360DDAR
name="U_BUCK"
pcbX={-27}
pcbY={-12}
schX={5}
schY={2}
schSheetName="power"
/>
<capacitor
name="C_5V1"
capacitance="22uF"
footprint="1210"
pcbX={-16}
pcbY={-13}
schX={10}
schY={0}
schSheetName="power"
/>
<capacitor
name="C_5V2"
capacitance="100nF"
footprint="0603"
pcbX={-11}
pcbY={-12}
schX={10}
schY={4}
schSheetName="power"
/>
{/* TI TPS54360 36 V-to-5 V buck: component values follow TI's 5 V
reference application (Figure 34); power components are JLC imports. */}
<MWSA0603S_8R2MT
name="L_BUCK"
pcbX={-17}
pcbY={-18}
pcbRotation={90}
schX={8}
schY={-2}
schSheetName="power"
/>
<B560C_13_F
name="D_BUCK"
pcbX={-34}
pcbY={-16}
pcbRotation={90}
schX={5}
schY={-3}
schSheetName="power"
/>
<capacitor name="C_BOOT" capacitance="100nF" footprint="0603" pcbX={-22} pcbY={-10} schX={2} schY={-3} schSheetName="power" />
<resistor name="R_FB_TOP" resistance="53.6k" footprint="0603" pcbX={-9} pcbY={-19} pcbRotation={90} schX={11} schY={-3} schSheetName="power" />
<resistor name="R_FB_BOT" resistance="10.2k" footprint="0603" pcbX={-9} pcbY={-23} pcbRotation={90} schX={11} schY={-5} schSheetName="power" />
<resistor name="R_COMP" resistance="13k" footprint="0603" pcbX={-5} pcbY={-25} pcbRotation={90} schX={5} schY={-6} schSheetName="power" />
<capacitor name="C_COMP" capacitance="6.8nF" footprint="0603" pcbX={-5} pcbY={-29} pcbRotation={90} schX={5} schY={-8} schSheetName="power" />
<capacitor name="C_COMP_HF" capacitance="39pF" footprint="0603" pcbX={-1} pcbY={-25} pcbRotation={90} schX={7} schY={-6} schSheetName="power" />
<resistor name="R_EN_TOP" resistance="523k" footprint="0603" pcbX={-31} pcbY={-25} pcbRotation={90} schX={0} schY={-6} schSheetName="power" />
<resistor name="R_EN_BOT" resistance="84.5k" footprint="0603" pcbX={-31} pcbY={-29} pcbRotation={90} schX={0} schY={-8} schSheetName="power" />
<resistor name="R_RT" resistance="162k" footprint="0603" pcbX={-25} pcbY={-29} pcbRotation={90} schX={3} schY={-8} schSheetName="power" />
<trace from=".J_PWR > .pin1" to=".F1 > .pin1" {...fieldTrace} />
<trace from=".F1 > .pin2" to=".D_REV > .anode" {...fieldTrace} />
<trace from=".D_REV > .cathode" to="net.V_SERVO" {...fieldTrace} />
<trace from=".J_PWR > .pin2" to="net.GND" {...fieldTrace} />
{/* Unidirectional TVS: cathode to positive input, anode to ground. */}
<trace from="net.V_SERVO" to=".D_TVS > .C" {...powerTrace} />
<trace from=".D_TVS > .A" to="net.GND" {...powerTrace} />
<trace from="net.V_SERVO" to=".C_IN1 > .pin1" {...powerTrace} />
<trace from=".C_IN1 > .pin2" to="net.GND" {...powerTrace} />
<trace from="net.V_SERVO" to=".C_IN2 > .pin1" {...powerTrace} />
<trace from=".C_IN2 > .pin2" to="net.GND" {...powerTrace} />
<trace name="BUCK_VIN" from="net.V_SERVO" to=".U_BUCK > .VIN" {...fieldTrace} />
<trace name="BUCK_GND" from=".U_BUCK > .GND" to="net.GND" {...powerTrace} />
<trace name="BUCK_EP" from=".U_BUCK > .EP" to="net.GND" {...powerTrace} />
<trace name="BUCK_SW" from=".U_BUCK > .SW" to="net.V_SW" {...powerTrace} />
<trace name="BUCK_DIODE_K" from="net.V_SW" to=".D_BUCK > .cathode" {...powerTrace} />
<trace name="BUCK_DIODE_A" from=".D_BUCK > .anode" to="net.GND" {...powerTrace} />
<trace name="BUCK_L" from="net.V_SW" to=".L_BUCK > .pin1" {...powerTrace} />
<trace name="BUCK_OUT" from=".L_BUCK > .pin2" to="net.V5" {...powerTrace} />
<trace name="BUCK_BOOT" from=".U_BUCK > .BOOT" to=".C_BOOT > .pin1" {...signalTrace} />
<trace name="BUCK_BOOT_SW" from=".C_BOOT > .pin2" to="net.V_SW" {...signalTrace} />
<trace name="BUCK_FB" from=".U_BUCK > .FB" to="net.V_FB" {...signalTrace} />
<trace name="BUCK_FB_TOP" from="net.V5" to=".R_FB_TOP > .pin1" {...signalTrace} />
<trace name="BUCK_FB_SENSE" from=".R_FB_TOP > .pin2" to="net.V_FB" {...signalTrace} />
<trace name="BUCK_FB_BOT" from="net.V_FB" to=".R_FB_BOT > .pin1" {...signalTrace} />
<trace name="BUCK_FB_GND" from=".R_FB_BOT > .pin2" to="net.GND" {...signalTrace} />
<trace name="BUCK_COMP" from=".U_BUCK > .COMP" to="net.V_COMP" {...signalTrace} />
<trace name="BUCK_COMP_R" from="net.V_COMP" to=".R_COMP > .pin1" {...signalTrace} />
<trace name="BUCK_COMP_C" from=".R_COMP > .pin2" to=".C_COMP > .pin1" {...signalTrace} />
<trace name="BUCK_COMP_GND" from=".C_COMP > .pin2" to="net.GND" {...signalTrace} />
<trace name="BUCK_COMP_HF" from="net.V_COMP" to=".C_COMP_HF > .pin1" {...signalTrace} />
<trace name="BUCK_COMP_HF_GND" from=".C_COMP_HF > .pin2" to="net.GND" {...signalTrace} />
<trace name="BUCK_EN_TOP" from="net.V_SERVO" to=".R_EN_TOP > .pin1" {...signalTrace} />
<trace name="BUCK_EN_DIV" from=".R_EN_TOP > .pin2" to="net.V_EN" {...signalTrace} />
<trace name="BUCK_EN" from="net.V_EN" to=".U_BUCK > .EN" {...signalTrace} />
<trace name="BUCK_EN_BOT" from="net.V_EN" to=".R_EN_BOT > .pin1" {...signalTrace} />
<trace name="BUCK_EN_GND" from=".R_EN_BOT > .pin2" to="net.GND" {...signalTrace} />
<trace name="BUCK_RT" from=".U_BUCK > .pin4" to=".R_RT > .pin1" {...signalTrace} />
<trace name="BUCK_RT_GND" from=".R_RT > .pin2" to="net.GND" {...signalTrace} />
<trace from="net.V5" to=".C_5V1 > .pin1" {...powerTrace} />
<trace from=".C_5V1 > .pin2" to="net.GND" {...powerTrace} />
<trace from="net.V5" to=".C_5V2 > .pin1" {...powerTrace} />
<trace from=".C_5V2 > .pin2" to="net.GND" {...powerTrace} />
<Microcontroller_RP2040
name="MCU"
pcbX={0}
pcbY={0}
schX={0}
schY={0}
schSheetName="controller"
exposedNets={["VBUS", "VSYS", "V5", "GND", "V3V3"]}
/>
<trace name="MCU_VSYS_INPUT" from="net.VSYS" to=".MCU > .U3 > .IN" {...powerTrace} />
{/* Board temperature monitor: TMP117 at I2C address 0x48. */}
<TMP117AIDRVR
name="U_TEMP"
pcbX={-13}
pcbY={10}
schX={8}
schY={9}
schSheetName="controller"
/>
<capacitor
name="C_TEMP"
capacitance="100nF"
footprint="0402"
pcbX={-16}
pcbY={10}
schX={10}
schY={9}
schSheetName="controller"
/>
<resistor
name="R_TEMP_SDA"
resistance="4.7k"
footprint="0402"
supplierPartNumbers={{ jlcpcb: ["C25900"] }}
pcbX={-16}
pcbY={14}
schX={8}
schY={7}
schSheetName="controller"
/>
<resistor
name="R_TEMP_SCL"
resistance="4.7k"
footprint="0402"
supplierPartNumbers={{ jlcpcb: ["C25900"] }}
pcbX={-12}
pcbY={14}
schX={10}
schY={7}
schSheetName="controller"
/>
<trace name="TEMP_3V3" from=".C_TEMP > .pin1" to=".U_TEMP > .V_POS" maxLength="15mm" {...signalTrace} />
<trace name="TEMP_GND" from=".U_TEMP > .GND" to=".C_TEMP > .pin2" maxLength="10mm" {...signalTrace} />
<trace name="TEMP_ADDR" from=".U_TEMP > .ADD0" to="net.GND" {...signalTrace} />
<trace name="TEMP_SDA_NET" from="net.TEMP_SDA" to=".U_TEMP > .SDA" {...signalTrace} />
<trace name="TEMP_SCL_NET" from="net.TEMP_SCL" to=".U_TEMP > .SCL" {...signalTrace} />
{/* TMP117 is polled through the routed I²C bus. ALERT is intentionally
left NC: firmware applies the temperature threshold/debounce policy. */}
<trace name="TEMP_DECOUPLE_P" from=".C_TEMP > .pin1" to="net.V3V3" maxLength="10mm" {...signalTrace} />
<trace name="TEMP_DECOUPLE_G" from=".C_TEMP > .pin2" to="net.GND" maxLength="10mm" {...signalTrace} />
<trace name="TEMP_SDA_PULLUP" from=".R_TEMP_SDA > .pin1" to="net.TEMP_SDA" {...signalTrace} />
<trace name="TEMP_SDA_PULLUP_3V3" from=".R_TEMP_SDA > .pin2" to="net.V3V3" {...signalTrace} />
<trace name="TEMP_SCL_PULLUP" from=".R_TEMP_SCL > .pin1" to="net.TEMP_SCL" {...signalTrace} />
<trace name="TEMP_SCL_PULLUP_3V3" from=".R_TEMP_SCL > .pin2" to="net.V3V3" {...signalTrace} />
<testpoint
name="TP_5V"
footprintVariant="pad"
padShape="circle"
padDiameter="2mm"
pcbX={-30}
pcbY={-32}
schX={-8}
schY={7}
schSheetName="power"
/>
<testpoint
name="TP_3V3"
footprintVariant="pad"
padShape="circle"
padDiameter="2mm"
pcbX={-23}
pcbY={-32}
schX={-5}
schY={7}
schSheetName="controller"
/>
<testpoint
name="TP_GND"
footprintVariant="pad"
padShape="circle"
padDiameter="2mm"
pcbX={-16}
pcbY={-32}
schX={-2}
schY={7}
schSheetName="power"
/>
<testpoint
name="TP_STEP"
footprintVariant="pad"
padShape="circle"
padDiameter="2mm"
pcbX={20}
pcbY={6}
schX={-2}
schY={7}
schSheetName="motion"
/>
<testpoint
name="TP_DIR"
footprintVariant="pad"
padShape="circle"
padDiameter="2mm"
pcbX={20}
pcbY={2}
schX={1}
schY={7}
schSheetName="motion"
/>
<testpoint
name="TP_ALARM"
footprintVariant="pad"
padShape="circle"
padDiameter="2mm"
pcbX={20}
pcbY={-2}
schX={4}
schY={7}
schSheetName="motion"
/>
<trace
name="TP_5V_NET"
from=".TP_5V > .pin1"
to="net.V5"
{...signalTrace}
/>
<trace
name="TP_3V3_NET"
from=".TP_3V3 > .pin1"
to="net.V3V3"
{...signalTrace}
/>
<trace
name="TP_GND_NET"
from=".TP_GND > .pin1"
to="net.GND"
{...signalTrace}
/>
<trace
name="TP_STEP_NET"
from=".TP_STEP > .pin1"
to="net.PULSE_3V3"
{...signalTrace}
/>
<trace
name="TP_DIR_NET"
from=".TP_DIR > .pin1"
to="net.DIR_3V3"
{...signalTrace}
/>
<trace
name="TP_ALARM_NET"
from=".TP_ALARM > .pin1"
to="net.ALARM_3V3"
{...signalTrace}
/>
<ServoTerminal
name="J_SERVO"
pcbX={34}
pcbY={10}
pcbRotation={90}
schX={8}
schY={0}
schSheetName="motion"
/>
<MMBT3904_RANGE_100_300_
name="Q_PULSE"
pcbX={24}
pcbY={15}
schX={2}
schY={2}
schSheetName="motion"
/>
<MMBT3904_RANGE_100_300_
name="Q_DIR"
pcbX={24}
pcbY={9}
schX={4}
schY={2}
schSheetName="motion"
/>
<resistor
name="R_PULSE_B"
resistance="1k"
footprint="0603"
pcbX={19}
pcbY={15}
pcbRotation={90}
schX={0}
schY={2}
schSheetName="motion"
/>
<resistor
name="R_DIR_B"
resistance="1k"
footprint="0603"
pcbX={19}
pcbY={9}
pcbRotation={90}
schX={0}
schY={4}
schSheetName="motion"
/>
<resistor
name="R_PULSE_OFF"
resistance="100k"
footprint="0603"
pcbX={17}
pcbY={18}
pcbRotation={90}
schX={0}
schY={0}
schSheetName="motion"
/>
<resistor
name="R_DIR_OFF"
resistance="100k"
footprint="0603"
pcbX={15}
pcbY={6}
pcbRotation={90}
schX={4}
schY={0}
schSheetName="motion"
/>
<resistor
name="R_ALARM_PU"
resistance="10k"
footprint="0603"
pcbX={24}
pcbY={2}
pcbRotation={90}
schX={10}
schY={2}
schSheetName="motion"
/>
<resistor
name="R_ALARM_DIV"
resistance="1k"
footprint="0603"
pcbX={28}
pcbY={2}
pcbRotation={90}
schX={12}
schY={2}
schSheetName="motion"
/>
<resistor
name="R_ALARM_PD"
resistance="100k"
footprint="0603"
pcbX={28}
pcbY={-2}
pcbRotation={90}
schX={12}
schY={0}
schSheetName="motion"
/>
<capacitor
name="C_ALARM"
capacitance="1nF"
footprint="0603"
pcbX={29}
pcbY={-5}
pcbRotation={90}
schX={10}
schY={0}
schSheetName="motion"
/>
<trace from="net.V5" to=".J_SERVO > .pin1" {...powerTrace} />
<trace
from=".Q_PULSE > .collector"
to=".J_SERVO > .pin2"
{...signalTrace}
/>
<trace from=".Q_PULSE > .emitter" to="net.GND" {...signalTrace} />
<trace from="net.PULSE_3V3" to=".R_PULSE_B > .pin1" {...signalTrace} />
<trace from=".R_PULSE_B > .pin2" to=".Q_PULSE > .base" {...signalTrace} />
<trace
from=".Q_PULSE > .base"
to=".R_PULSE_OFF > .pin1"
{...signalTrace}
/>
<trace from=".R_PULSE_OFF > .pin2" to="net.GND" {...signalTrace} />
<trace from="net.V5" to=".J_SERVO > .pin3" {...powerTrace} />
<trace
from=".Q_DIR > .collector"
to=".J_SERVO > .pin4"
{...signalTrace}
/>
<trace from=".Q_DIR > .emitter" to="net.GND" {...signalTrace} />
<trace from="net.DIR_3V3" to=".R_DIR_B > .pin1" {...signalTrace} />
<trace from=".R_DIR_B > .pin2" to=".Q_DIR > .base" {...signalTrace} />
<trace from=".Q_DIR > .base" to=".R_DIR_OFF > .pin1" {...signalTrace} />
<trace from=".R_DIR_OFF > .pin2" to="net.GND" {...signalTrace} />
<trace from=".J_SERVO > .pin6" to="net.GND" {...signalTrace} />
<trace from="net.V3V3" to=".R_ALARM_PU > .pin1" {...signalTrace} />
<trace
from=".R_ALARM_PU > .pin2"
to=".J_SERVO > .pin5"
{...signalTrace}
/>
<trace
from=".J_SERVO > .pin5"
to=".R_ALARM_DIV > .pin1"
{...signalTrace}
/>
<trace from=".R_ALARM_DIV > .pin2" to="net.ALARM_3V3" {...signalTrace} />
<trace from="net.ALARM_3V3" to=".R_ALARM_PD > .pin1" {...signalTrace} />
<trace from=".R_ALARM_PD > .pin2" to="net.GND" {...signalTrace} />
<trace from="net.ALARM_3V3" to=".C_ALARM > .pin1" {...signalTrace} />
<trace from=".C_ALARM > .pin2" to="net.GND" {...signalTrace} />
<IOTerminal
name="J_IO"
pcbX={34}
pcbY={-12}
pcbRotation={90}
schX={8}
schY={-5}
schSheetName="controller"
/>
<resistor
name="R_LIM_POS"
resistance="10k"
footprint="0603"
pcbX={23}
pcbY={-10}
pcbRotation={90}
schX={2}
schY={-5}
schSheetName="controller"
/>
<resistor
name="R_LIM_NEG"
resistance="10k"
footprint="0603"
pcbX={27}
pcbY={-10}
pcbRotation={90}
schX={4}
schY={-5}
schSheetName="controller"
/>
<resistor
name="R_ESTOP"
resistance="10k"
footprint="0603"
pcbX={31}
pcbY={-10}
pcbRotation={90}
schX={6}
schY={-5}
schSheetName="controller"
/>
<capacitor
name="C_LIM_POS"
capacitance="10nF"
footprint="0603"
pcbX={23}
pcbY={-14}
pcbRotation={90}
schX={2}
schY={-8}
schSheetName="controller"
/>
<capacitor
name="C_LIM_NEG"
capacitance="10nF"
footprint="0603"
pcbX={27}
pcbY={-14}
pcbRotation={90}
schX={4}
schY={-8}
schSheetName="controller"
/>
<capacitor
name="C_ESTOP"
capacitance="10nF"
footprint="0603"
pcbX={31}
pcbY={-14}
pcbRotation={90}
schX={6}
schY={-8}
schSheetName="controller"
/>
<PESD3V3U1UL
name="D_LIM_POS_ESD"
pcbX={29}
pcbY={-22}
pcbRotation={180}
schX={1}
schY={-10}
schSheetName="controller"
/>
<PESD3V3U1UL
name="D_LIM_NEG_ESD"
pcbX={27}
pcbY={-18}
schX={3}
schY={-10}
schSheetName="controller"
/>
<PESD3V3U1UL
name="D_ESTOP_ESD"
pcbX={31}
pcbY={-18}
schX={5}
schY={-10}
schSheetName="controller"
/>
{/* Remote 10 kΩ NTC input: a second temperature channel mounted at the
motor or enclosure, with pull-up, RC filtering and ESD clamp. */}
<resistor
name="R_NTC_PULL"
resistance="10k"
footprint="0603"
pcbX={18}
pcbY={-10}
pcbRotation={90}
schX={8}
schY={-5}
schSheetName="controller"
/>
<capacitor
name="C_NTC_FILTER"
capacitance="10nF"
footprint="0603"
pcbX={18}
pcbY={-14}
pcbRotation={90}
schX={8}
schY={-8}
schSheetName="controller"
/>
<PESD3V3U1UL
name="D_NTC_ESD"
pcbX={33}
pcbY={-26}
schX={8}
schY={-10}
schSheetName="controller"
/>
<trace from=".J_IO > .pin1" to="net.LIMIT_POS" {...signalTrace} />
<trace from=".J_IO > .pin2" to="net.LIMIT_NEG" {...signalTrace} />
<trace from=".J_IO > .pin3" to="net.ESTOP_3V3" {...signalTrace} />
<trace from=".J_IO > .pin4" to="net.GND" {...signalTrace} />
<trace name="NTC_INPUT" from=".J_IO > .pin5" to="net.NTC_REMOTE" {...signalTrace} />
<trace from=".J_IO > .pin6" to="net.GND" {...signalTrace} />
<trace from="net.V3V3" to=".R_LIM_POS > .pin1" {...signalTrace} />
<trace from=".R_LIM_POS > .pin2" to="net.LIMIT_POS" {...signalTrace} />
<trace from="net.LIMIT_POS" to=".C_LIM_POS > .pin1" {...signalTrace} />
<trace from=".C_LIM_POS > .pin2" to="net.GND" {...signalTrace} />
<trace
from="net.LIMIT_POS"
to=".D_LIM_POS_ESD > .pin1"
{...signalTrace}
/>
<trace from=".D_LIM_POS_ESD > .pin2" to="net.GND" {...signalTrace} />
<trace from="net.V3V3" to=".R_LIM_NEG > .pin1" {...signalTrace} />
<trace from=".R_LIM_NEG > .pin2" to="net.LIMIT_NEG" {...signalTrace} />
<trace from="net.LIMIT_NEG" to=".C_LIM_NEG > .pin1" {...signalTrace} />
<trace from=".C_LIM_NEG > .pin2" to="net.GND" {...signalTrace} />
<trace
from="net.LIMIT_NEG"
to=".D_LIM_NEG_ESD > .pin1"
{...signalTrace}
/>
<trace from=".D_LIM_NEG_ESD > .pin2" to="net.GND" {...signalTrace} />
<trace from="net.V3V3" to=".R_ESTOP > .pin1" {...signalTrace} />
<trace from=".R_ESTOP > .pin2" to="net.ESTOP_3V3" {...signalTrace} />
<trace from="net.ESTOP_3V3" to=".C_ESTOP > .pin1" {...signalTrace} />
<trace from=".C_ESTOP > .pin2" to="net.GND" {...signalTrace} />
<trace
from="net.ESTOP_3V3"
to=".D_ESTOP_ESD > .pin1"
{...signalTrace}
/>
<trace from=".D_ESTOP_ESD > .pin2" to="net.GND" {...signalTrace} />
<trace name="NTC_PULLUP" from="net.V3V3" to=".R_NTC_PULL > .pin1" {...signalTrace} />
<trace name="NTC_SENSE" from=".R_NTC_PULL > .pin2" to="net.NTC_REMOTE" {...signalTrace} />
<trace name="NTC_FILTER" from="net.NTC_REMOTE" to=".C_NTC_FILTER > .pin1" {...signalTrace} />
<trace name="NTC_FILTER_GND" from=".C_NTC_FILTER > .pin2" to="net.GND" {...signalTrace} />
<trace name="NTC_ESD" from="net.NTC_REMOTE" to=".D_NTC_ESD > .pin1" {...signalTrace} />
<trace name="NTC_ESD_GND" from=".D_NTC_ESD > .pin2" to="net.GND" {...signalTrace} />
<XL_1608SURC_06
name="LED_5V"
pcbX={-36}
pcbY={17}
schX={-8}
schY={-8}
schSheetName="controller"
/>
<resistor
name="R_LED_5V"
resistance="1k"
footprint="0603"
pcbX={-32}
pcbY={17}
pcbRotation={90}
schX={-10}
schY={-8}
schSheetName="controller"
/>
<trace from="net.V5" to=".R_LED_5V > .pin1" {...signalTrace} />
<trace from=".R_LED_5V > .pin2" to=".LED_5V > .anode" {...signalTrace} />
<trace from=".LED_5V > .cathode" to="net.GND" {...signalTrace} />
{/* NEMA-23 face pattern: 47.14 mm square, M5 clearance, grounded PTH. */}
{[-23.57, 23.57].flatMap((x) =>
[-23.57, 23.57].map((y) => (
<chip
key={`${x}:${y}`}
name={`MH_${x}_${y}`}
pcbX={x}
pcbY={y}
pinLabels={{ pin1: ["GND"] }}
connections={{ pin1: "net.GND" }}
footprint={
<footprint>
<platedhole
portHints={["pin1"]}
shape="circle"
holeDiameter="5.3mm"
outerDiameter="7.5mm"
/>
</footprint>
}
/>
)),
)}
{/* Fabrication copper: grounded top and bottom planes. The grounded
NEMA mounting holes tie into these pours; non-GND nets keep the
same 0.20 mm isolation on pads and traces. */}
<copperpour
name="GND_TOP"
layer="top"
connectsTo="net.GND"
clearance="0.2mm"
padMargin="0.2mm"
traceMargin="0.2mm"
boardEdgeMargin="0.3mm"
coveredWithSolderMask
/>
<copperpour
name="GND_BOTTOM"
layer="bottom"
connectsTo="net.GND"
clearance="0.2mm"
padMargin="0.2mm"
traceMargin="0.2mm"
boardEdgeMargin="0.3mm"
coveredWithSolderMask
/>
<silkscreentext
text="iSV57T-090 SERVO CTRL"
pcbX={-13}
pcbY={30}
fontSize="1.5mm"
/>
<silkscreenpath
route={[
{ x: -10, y: -14 },
{ x: 10, y: -14 },
{ x: 10, y: 14 },
{ x: -10, y: 14 },
{ x: -10, y: -14 },
]}
/>
<silkscreentext text="RP2040 / 12MHz XO" pcbX={0} pcbY={-16} fontSize="1.2mm" />
<silkscreentext text="36V IN" pcbX={-34} pcbY={-8} fontSize="1.5mm" />
<silkscreentext
text="SERVO I/O"
pcbX={32}
pcbY={23}
fontSize="1mm"
/>
<silkscreentext
text="LIMIT / ESTOP"
pcbX={32}
pcbY={-27}
fontSize="1mm"
/>
<silkscreentext
text="USB-C / SWD"
pcbX={-32}
pcbY={-25}
fontSize="1mm"
/>
</board>
)
}