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/search-cumulative-vias.mjs
import fs from "node:fs"
import { runAllRoutingChecks } from "@tscircuit/checks"
let circuit = JSON.parse(
fs.readFileSync("frozen-global-router-baseline.json", "utf8"),
).filter((element) => !String(element.type).endsWith("error"))
const accepted = [
["source_net_30", 0.3165170373, 2.4681926742, 0.1165, 2.3682],
["source_net_26", -4.9635288614, 0.8009878988, -5.2635, 0.601],
["source_net_26", -1.0149987646, -4.722238758, -1.215, -4.7222],
["source_net_22", -5.975494, -3.367, -6.2755, -3.567],
["source_net_22", 1.9745212144, 2.375001, 1.6745, 2.875],
["source_net_21", 1.6, -3.9750010113, 1.6, -3.775],
]
const targets = [
["source_net_30", 0.1165, 2.3682],
["source_net_26", -5.2635, 0.601],
["source_net_22", 1.6745, 2.875],
["source_net_21", -3.2397362534, -2.7668353546],
["source_net_20", -4.3972237089, -1.6200715176],
["source_net_23", -3.9238737059, -2.7701900181],
["source_net_23", -3.0264205132, -3.6563618696],
["source_net_16", -3.6537511544, -3.7702748294],
["source_net_7", -2.2608049598, -3.9417301825],
["source_net_15", -2.5563157055, 0.4729727559],
]
const samePoint = (point, x, y) =>
Math.abs(point.x - x) < 1e-5 && Math.abs(point.y - y) < 1e-5
const applyMove = (input, [connectionName, oldX, oldY, newX, newY]) => input.map((element) => {
if (element.type === "pcb_via" && element.pcb_trace_id?.startsWith(connectionName) &&
samePoint(element, oldX, oldY)) {
return { ...element, x: newX, y: newY }
}
if (element.type === "pcb_trace" && element.connection_name === connectionName) {
return {
...element,
route: element.route.map((point) => samePoint(point, oldX, oldY)
? { ...point, x: newX, y: newY }
: point),
}
}
return element
})
for (const move of accepted) circuit = applyMove(circuit, move)
let currentErrors = await runAllRoutingChecks(circuit)
console.log(`start\t${currentErrors.length}`)
for (const [connectionName, oldX, oldY] of targets) {
let best = { count: currentErrors.length, x: oldX, y: oldY, circuit, errors: currentErrors }
const radius = 0.5
const step = 0.1
for (let dx = -radius; dx <= radius + 1e-6; dx += step) {
for (let dy = -radius; dy <= radius + 1e-6; dy += step) {
if (Math.abs(dx) < 1e-6 && Math.abs(dy) < 1e-6) continue
const x = Number((oldX + dx).toFixed(4))
const y = Number((oldY + dy).toFixed(4))
const candidate = applyMove(circuit, [connectionName, oldX, oldY, x, y])
let errors
try {
errors = await runAllRoutingChecks(candidate)
} catch {
continue
}
if (errors.length < best.count) best = { count: errors.length, x, y, circuit: candidate, errors }
}
}
circuit = best.circuit
currentErrors = best.errors
console.log(`${connectionName}@${oldX},${oldY}\t${best.count}\t${best.x},${best.y}`)
}
console.log(Object.entries(Object.groupBy(currentErrors, (error) => error.type))
.map(([kind, errors]) => `${kind}\t${errors.length}`)
.join("\n"))
console.log(currentErrors.map((error) => error.message).join("\n"))