ShiboSoftwareDev/nema8-20mm-dual-usbc-stepper-controller

A compact 4-layer USB‑C PD/data controller board using a CH32X035 MCU and TMC2209 driver to power and control a NEMA‑8 stepper motor, with 3.3‑V regulation, USB ESD/reverse-polarity/TVS protection, current sensing, and boot control.

Version
1.0.12
License
unset
Stars
0

scripts/search-component-shifts.mjs

import fs from "node:fs"
import { runAllRoutingChecks } from "@tscircuit/checks"

let circuit = JSON.parse(fs.readFileSync("dist/index/circuit.json", "utf8"))
  .filter((element) => !String(element.type).endsWith("error"))

const shiftComponent = (input, componentId, dx, dy) => {
  const portIds = new Set(input
    .filter((element) => element.type === "pcb_port" && element.pcb_component_id === componentId)
    .map((element) => element.pcb_port_id))

  return input.map((element) => {
    if (element.pcb_component_id === componentId && typeof element.x === "number" && typeof element.y === "number") {
      return { ...element, x: element.x + dx, y: element.y + dy }
    }
    if (element.type === "pcb_component" && element.pcb_component_id === componentId) {
      return { ...element, center: { ...element.center, x: element.center.x + dx, y: element.center.y + dy } }
    }
    if (element.type !== "pcb_trace") return element
    return {
      ...element,
      route: element.route.map((point) => (
        portIds.has(point.start_pcb_port_id) || portIds.has(point.end_pcb_port_id)
          ? { ...point, x: point.x + dx, y: point.y + dy }
          : point
      )),
    }
  })
}

let errors = await runAllRoutingChecks(circuit)
console.log(`start\t${errors.length}`)
const componentId = "pcb_component_6"
let best = { count: errors.length, dx: 0, dy: 0, circuit, errors }
for (const dx of [-0.8, -0.7, -0.6, -0.5, -0.4, 0.4, 0.5, 0.6, 0.7, 0.8]) {
  for (const dy of [-1.4, -1.3, -1.2, -1.1, 1.1, 1.2, 1.3, 1.4]) {
    if (Math.abs(dx) < 1e-6 && Math.abs(dy) < 1e-6) continue
    const candidate = shiftComponent(circuit, componentId, Number(dx.toFixed(2)), Number(dy.toFixed(2)))
    const candidateErrors = await runAllRoutingChecks(candidate)
    if (candidateErrors.length < best.count) {
      best = { count: candidateErrors.length, dx, dy, circuit: candidate, errors: candidateErrors }
      console.log(`best\t${best.count}\t${dx.toFixed(2)},${dy.toFixed(2)}`)
    }
    if (candidateErrors.length <= 18) console.log(`candidate\t${candidateErrors.length}\t${dx.toFixed(2)},${dy.toFixed(2)}`)
  }
}
console.log(`winner\t${best.count}\t${best.dx.toFixed(2)},${best.dy.toFixed(2)}`)
console.log(best.errors.map((error) => error.message).join("\n"))