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.42
- 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");
}
}
