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-usb-resistor-placement.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 dpPortIds = new Set(["pcb_port_36", "pcb_port_37"])
const dmPortIds = new Set(["pcb_port_34", "pcb_port_35"])

const transformEndpoint = (trace, portIds, transform) => ({
  ...trace,
  route: trace.route.map((point) => (
    portIds.has(point.start_pcb_port_id) || portIds.has(point.end_pcb_port_id)
      ? { ...point, ...transform(point.x, point.y) }
      : point
  )),
})

const candidateAt = (dmX, dmY) => original.map((element) => {
  if (element.type === "pcb_trace") {
    const dpShifted = transformEndpoint(element, dpPortIds, (x, y) => ({ x: x - 0.6, y }))
    return transformEndpoint(dpShifted, dmPortIds, (x, y) => ({
      x: dmX - (y - 2.5),
      y: dmY + (x + 1.5),
    }))
  }
  if (element.pcb_component_id === "pcb_component_6" && typeof element.x === "number") {
    return { ...element, x: element.x - 0.6 }
  }
  if (element.type === "pcb_component" && element.pcb_component_id === "pcb_component_6") {
    return { ...element, center: { ...element.center, x: element.center.x - 0.6 } }
  }
  if (element.pcb_component_id === "pcb_component_5" && typeof element.x === "number") {
    return {
      ...element,
      x: dmX - (element.y - 2.5),
      y: dmY + (element.x + 1.5),
      ...(typeof element.width === "number" ? { width: element.height, height: element.width } : {}),
      ...(typeof element.rotation === "number" ? { rotation: element.rotation + 90 } : {}),
    }
  }
  if (element.type === "pcb_component" && element.pcb_component_id === "pcb_component_5") {
    return { ...element, center: { ...element.center, x: dmX, y: dmY }, rotation: (element.rotation ?? 0) + 90 }
  }
  return element
})

const before = await runAllRoutingChecks(original)
let best = { count: before.length, x: -1.5, y: 2.5, errors: before }
console.log(`start\t${before.length}`)
for (let x = -2.2; x <= -1.0 + 1e-6; x += 0.1) {
  for (let y = 1.2; y <= 3.8 + 1e-6; y += 0.1) {
    const errors = await runAllRoutingChecks(candidateAt(Number(x.toFixed(2)), Number(y.toFixed(2))))
    if (errors.length < best.count) {
      best = { count: errors.length, x, y, errors }
      console.log(`best\t${best.count}\t${x.toFixed(2)},${y.toFixed(2)}`)
    }
  }
}
console.log(`winner\t${best.count}\t${best.x.toFixed(2)},${best.y.toFixed(2)}`)
console.log(best.errors.map((error) => error.message).join("\n"))