ShiboSoftwareDev/nema8-20mm-dual-usbc-stepper-controller
A compact 4-layer USB‑C PD stepper-motor controller PCB using a CH32X035 MCU, TMC2209 driver, dual USB‑C ports, power protection/regulation, ESD/TVS diodes, current-sense resistors, and NEMA‑8 motor connector.
- Version
- 1.0.13
- License
- unset
- Stars
- 0
scripts/inspect-via-dogleg.mjs
import fs from "node:fs"
import { runAllRoutingChecks } from "@tscircuit/checks"
const original = JSON.parse(fs.readFileSync("dist/index/circuit.json", "utf8"))
.filter((element) => !String(element.type).endsWith("error"))
const samePoint = (point, x, y) => Math.abs(point.x - x) < 1e-5 && Math.abs(point.y - y) < 1e-5
const doglegVia = (input, viaId, newX, newY) => {
const via = input.find((element) => element.type === "pcb_via" && element.pcb_via_id === viaId)
const trace = input.find((element) => element.type === "pcb_trace" && element.pcb_trace_id === via.pcb_trace_id)
return input.map((element) => {
if (element.type === "pcb_via" && element.pcb_via_id === viaId) return { ...element, x: newX, y: newY }
if (element.type !== "pcb_trace" || element.pcb_trace_id !== trace.pcb_trace_id) return element
const route = []
for (let index = 0; index < element.route.length; index += 1) {
const point = element.route[index]
if (point.route_type !== "via" || !samePoint(point, via.x, via.y)) {
route.push(point)
continue
}
const previous = route.at(-1)
const next = element.route[index + 1]
route.push({ ...previous, x: newX, y: newY })
route.push({ ...point, x: newX, y: newY })
route.push({ ...next, x: newX, y: newY })
route.push(next)
index += 1
}
return { ...element, route }
})
}
const moveVia = (input, viaId, newX, newY) => {
const via = input.find((element) => element.type === "pcb_via" && element.pcb_via_id === viaId)
const trace = input.find((element) => element.type === "pcb_trace" && element.pcb_trace_id === via.pcb_trace_id)
return input.map((element) => {
if (element.type === "pcb_via" && element.pcb_via_id === viaId) return { ...element, x: newX, y: newY }
if (element.type !== "pcb_trace" || element.connection_name !== trace.connection_name) return element
return { ...element, route: element.route.map((point) => samePoint(point, via.x, via.y) ? { ...point, x: newX, y: newY } : point) }
})
}
const before = await runAllRoutingChecks(original)
for (const [dx, dy] of [[0.4, 0], [-0.4, 0], [0, 0.4], [0, -0.4], [0.4, 0.4], [-0.4, -0.4]]) {
const via = original.find((element) => element.type === "pcb_via" && element.pcb_via_id === "pcb_via_9")
const after = await runAllRoutingChecks(doglegVia(original, "pcb_via_9", via.x + dx, via.y + dy))
const beforeMessages = new Set(before.map((error) => error.message))
const afterMessages = new Set(after.map((error) => error.message))
console.log(`candidate ${dx},${dy}: ${after.length}`)
console.log("removed:", [...beforeMessages].filter((message) => !afterMessages.has(message)))
console.log("added:", [...afterMessages].filter((message) => !beforeMessages.has(message)))
}
for (const [x, y] of [[-1.3310562395555143, 4.09176341935478], [-1.33, 3.7], [-0.8, 3.5], [0.8, 3.7]]) {
const after = await runAllRoutingChecks(moveVia(original, "pcb_via_9", x, y))
const beforeMessages = new Set(before.map((error) => error.message))
const afterMessages = new Set(after.map((error) => error.message))
console.log(`move ${x},${y}: ${after.length}`)
console.log("removed:", [...beforeMessages].filter((message) => !afterMessages.has(message)))
console.log("added:", [...afterMessages].filter((message) => !beforeMessages.has(message)))
}