imrishabh18/rp2040-motor-controller

An RP2040-based NEMA17 stepper-motor controller with USB-C programming and PD motor-power negotiation, DRV8825 dual H-bridge drive, current/temperature telemetry, protected power filtering, status RGB LED, buzzer alarm, and optional magnetic encoder.

Version
1.0.41
License
unset
Stars
3

tests/helpers/assertUsb20v.ts

import { expect } from "bun:test";
import type { CircuitJson } from "circuit-json";

/** Physical contact order, drill geometry, and supplier identity at both ports. */
export function assertUsb20v(json: CircuitJson) {
  const sc = json.filter(e => e.type === "source_component");
  expect(sc.filter(e => e.supplier_part_numbers?.jlcpcb?.includes("C2765186"))).toHaveLength(0);
  for (const [name, x] of [["J_USB", -6], ["J_MOTOR_USB", 7]] as const) {
    const source = sc.find(e => e.name === name)!;
    expect(source.manufacturer_part_number).toBe("TYPE-C-31-M-12");
    expect(source.supplier_part_numbers?.jlcpcb).toEqual(["C165948"]);
    const pcb = json.find(e => e.type === "pcb_component" && e.source_component_id === source.source_component_id)!;
    if (pcb.type !== "pcb_component") throw new Error("Missing USB placement");
    expect(pcb.rotation).toBe(180);
    const pads = json.filter(e => e.type === "pcb_smtpad" && e.pcb_component_id === pcb.pcb_component_id);
    expect(pads).toHaveLength(12);
    const contacts = [
      ["A1B12", -3.1999555], ["A4B9", -2.3999571], ["B8", -1.75006],
      ["A5", -1.249934], ["B7", -.750062], ["A6", -.249936],
      ["A7", .249936], ["B6", .750062], ["A8", 1.24968],
      ["B5", 1.75006], ["B4A9", 2.4001603], ["B1A12", 3.2000063],
    ] as const;
    for (const [alias, localX] of contacts) {
      const port = json.find(e => e.type === "source_port" && e.source_component_id === source.source_component_id && e.name === alias)!;
      if (port.type !== "source_port") throw new Error("Missing USB contact");
      const landPort = json.find(e => e.type === "pcb_port" && e.source_port_id === port.source_port_id)!;
      if (landPort.type !== "pcb_port") throw new Error("Missing USB land");
      expect(landPort.x).toBeCloseTo(x - localX, 4);
      expect(landPort.y).toBeCloseTo(16.7 - 2.1740432, 3);
    }
    const slots = json.filter(e => e.type === "pcb_plated_hole" && e.pcb_component_id === pcb.pcb_component_id);
    expect(slots).toHaveLength(4);
    for (const s of slots) if (s.type === "pcb_plated_hole" && s.shape === "pill") {
      expect(s.hole_width).toBeCloseTo(.8, 5);
      expect([1.4, 1.6].some(h => Math.abs(s.hole_height - h) < 1e-5)).toBe(true);
    } else throw new Error("Supplier USB shell slot lost");
    const holes = json.filter(e => e.type === "pcb_hole" && e.pcb_component_id === pcb.pcb_component_id);
    expect(holes).toHaveLength(2);
    for (const h of holes) if (h.type === "pcb_hole" && h.hole_shape === "circle") {
      expect(h.hole_diameter).toBeCloseTo(.6, 5);
      expect(Math.abs(h.x - x)).toBeCloseTo(2.899918, 5);
      expect(h.y).toBeCloseTo(16.7 - .9055672, 5);
    } else throw new Error("Supplier USB locator hole lost");
  }
}