MustafaMulla29/rp2040-bldc-motor-controller-new

73×72 mm 4-layer USB‑C PD (5/9/15/20 V) RP2040 controller PCB with protected power switching, MCT8329A sensorless BLDC three-phase MOSFET bridge, USB data/programming, onboard controls, and three motor outputs feeding a 2212 motor through rigid bullet adapters.

Version
0.3.100
License
unset
Stars
0

assembly/vendor/jscad-electronics-wire-end.patch

--- a/lib/cables/types.ts
+++ b/lib/cables/types.ts
@@ -20,6 +20,8 @@
         pitch: number
       }
     | { kind: "nema_5_15p" | "iec_c13" }
+    // No connector geometry; bodyDepth=0, width/height match the jacket.
+    | { kind: "wire_end"; pinCount: 1 }
     | {
         kind: "bullet_male" | "bullet_female"
         diameter: number
--- a/lib/cables/create-cable-meshes.ts
+++ b/lib/cables/create-cable-meshes.ts
@@ -26,6 +26,14 @@
 
 function validateCableDefinition(definition: CableGeometryDefinition) {
   for (const connector of [definition.connectorA, definition.connectorB]) {
+    if (connector.kind === "wire_end") {
+      const crossSection = definition.crossSection
+      if (connector.bodyDepth !== 0 || connector.pinCount !== 1 ||
+        crossSection.kind !== "round_jacket" ||
+        connector.bodyWidth !== crossSection.diameter || connector.bodyHeight !== crossSection.diameter)
+        throw new Error("Wire ends require zero depth and the single wire diameter")
+      continue
+    }
     const dimensions = [
       connector.bodyWidth,
       connector.bodyHeight,
--- a/lib/cables/connector-meshes.ts
+++ b/lib/cables/connector-meshes.ts
@@ -295,6 +295,8 @@
   connector,
   jacketDiameter,
 }: { connector: CableConnectorSpec; jacketDiameter?: number }): CableMesh[] {
+  // A fixed lead starts at its authored wire exit, with no fabricated plug.
+  if (connector.kind === "wire_end") return []
   const meshes =
     connector.kind === "usb_c_plug"
       ? createUsbMeshes(connector)
--- /dev/null
+++ b/tests/snapshots/fixed-wire-ends.test.ts
@@ -0,0 +1,32 @@
+import { expect, test } from "bun:test"
+import { createCableMeshes, type CableGeometryDefinition } from "../../lib/cables"
+import { renderModelSnapshot } from "../fixtures/render-model-snapshot"
+import { expectPngSnapshot } from "../fixtures/expect-png-snapshot"
+
+for (const gender of ["male", "female"] as const) {
+  test(`fixed motor lead / ${gender} bullet / four views`, async () => {
+    const definition: CableGeometryDefinition = {
+      connectorA:{kind:"wire_end",pinCount:1,bodyWidth:2.4,bodyHeight:2.4,bodyDepth:0},
+      connectorB:{kind:`bullet_${gender}`,diameter:3.5,contactDepth:7,pinCount:1,pitch:5.5,
+        bodyWidth:gender==="male"?4.1:4.5,bodyHeight:gender==="male"?4.1:4.5,bodyDepth:12.25},
+      crossSection:{kind:"round_jacket",diameter:2.4,color:"#263449"},
+    }
+    const meshes=createCableMeshes({definition,path:[[0,0,0],[0,0,10],[0,0,50]]})
+    expect(meshes.some(m=>m.name.startsWith("A-"))).toBe(false)
+    expect(meshes.some(m=>m.name==="jacket")).toBe(true)
+    expect(meshes.some(m=>m.name===(gender==="male"?"B-bullet-pin":"B-bullet-socket"))).toBe(true)
+    expect(() => createCableMeshes({definition:{...definition,connectorA:{...definition.connectorA,bodyDepth:1}},path:[[0,0,0],[0,0,20]]})).toThrow()
+    const positions:number[]=[],indices:number[]=[]
+    for(const mesh of meshes){const offset=positions.length/3;positions.push(...mesh.positions);indices.push(...mesh.indices.map(i=>i+offset))}
+    const target:[number,number,number]=[0,0,28],span=85
+    const png=await renderModelSnapshot({mesh:{positions,indices},title:`Fixed motor lead / ${gender} bullet`,
+      modelString:`adaptercable_a(wire_end_d2.4mm)_b(bullet1_d3.5mm_g${gender})`,
+      views:[
+        {name:"ISOMETRIC",detail:"one fixed wire end, one bullet",eye:[80,-80,110],target,span},
+        {name:"TOP",detail:"wire end: no fabricated connector",eye:[0,0,180],target,span},
+        {name:"FRONT",detail:"2.4 mm wire, 3.5 mm contact",eye:[0,-150,28],target,span},
+        {name:"SIDE",detail:"native cable and contact meshes",eye:[150,0,28],target,span}],
+      footer:"World mm / +Z up / generic dimensions for visualization"})
+    await expectPngSnapshot(png,import.meta.path.replace(".test.ts",`-${gender}.test.ts`))
+  },30000)
+}