project
Adom Custom Electronic Load
Public Made by Adomby adom
Two-layer digitally controlled electronic-load prototype. Compact R11 is under active electrical, cooling and probe-access review; not a manufacturing release.
← Commit history
Reconcile thermal copper specification, recheck routing, and record native copper review
10 files changed
+929−2
design/gate-after-thermal-regions.txt+2design/measure-after-thermal-regions.txt+2design/spec.json+347design/thermal-vias-plan-after-locality-fix.txt+5design/thermal-vias-plan-before-locality-fix.json+545docs/build-clips.md+7docs/clips/thermal-copper-review-poster.jpgdocs/clips/thermal-copper-review.mp4tools/review_local_thermal_plan.py+13videos/inventory.json+8−2design/gate-after-thermal-regions.txtadded+2@@ -0,0 +1,2 @@+OK: gate passed: 0 new DRC errors (0 inherited), 0 unconnected; copper {"copperLengthMm":0.0,"entries":0,"nets":0,"segments":0,"segmentsByWidth":{},"vias":0}+Hint: The plan is empty: the board's own copper already joins every net. Next: adom-aiflow land route (records that nothing needs landing), then pour, land vias, land pours.
design/measure-after-thermal-regions.txtadded+2@@ -0,0 +1,2 @@+OK: copper kept per layer (KiCad's fills): {"B.Cu":2896.57,"F.Cu":2754.33}; coverage {"B.Cu":62.86,"F.Cu":59.77}+Hint: Next: adom-aiflow analyze current, analyze thermal.
design/spec.jsonadded+347@@ -0,0 +1,347 @@+{+ "board": "Adom electronic load R0, 64 x 72 mm, 2 layers; engineering prototype",+ "copperUm": 35,+ "clearance": 0.2,+ "edgeClearance": 0.2,+ "fixedRefs": [+ "MP1",+ "MP2",+ "MP3",+ "MP4",+ "J1",+ "J2",+ "J3",+ "J4",+ "J5",+ "J6",+ "J7"+ ],+ "wideNets": {+ "DUT_POS": [+ 2.0,+ 1.5,+ 1.2+ ],+ "DUT_FUSED": [+ 2.0,+ 1.5,+ 1.2+ ],+ "LOAD_POS": [+ 2.0,+ 1.5,+ 1.2+ ],+ "SHUNT_P": [+ 2.0,+ 1.5,+ 1.2+ ],+ "GND": [+ 2.0,+ 1.5,+ 1.2+ ]+ },+ "midNets": {+ "5V_AUX": [+ 0.5,+ 0.4+ ],+ "V_GATE": [+ 0.3,+ 0.25+ ]+ },+ "kelvin": {+ "U4.10": "RSH1.2",+ "U4.9": "RSH1.3"+ },+ "chains": [+ {+ "refs": [+ "R8",+ "R9",+ "R10"+ ],+ "direction": "down"+ },+ {+ "refs": [+ "R18",+ "R19"+ ],+ "direction": "down"+ },+ {+ "refs": [+ "R22",+ "R23"+ ],+ "direction": "down"+ },+ {+ "refs": [+ "R27",+ "R28"+ ],+ "direction": "down"+ },+ {+ "refs": [+ "R35",+ "R36",+ "R37"+ ],+ "direction": "down"+ }+ ],+ "loads": {+ "DUT_POS": {+ "amps": 3,+ "maxRiseC": 10+ },+ "DUT_FUSED": {+ "amps": 3,+ "maxRiseC": 10+ },+ "LOAD_POS": {+ "amps": 3,+ "maxRiseC": 10+ },+ "SHUNT_P": {+ "amps": 3,+ "maxRiseC": 10+ },+ "GND": {+ "amps": 3,+ "maxRiseC": 10+ },+ "5V_AUX": {+ "amps": 0.3,+ "maxRiseC": 10+ }+ },+ "hot": {+ "Q1": {+ "watts": 25,+ "tabNet": "LOAD_POS",+ "maxRiseC": 15,+ "note": "25 W design-target screen against the 55 C firmware case trip at assumed 40 C ambient. External heatsink unresolved; board-only solver cannot validate cooling."+ },+ "D1": {+ "watts": 1.65,+ "tabNet": "LOAD_POS"+ },+ "RSH1": {+ "watts": 0.18,+ "tabNet": "SHUNT_P"+ }+ },+ "hotMaxRiseC": 35,+ "pours": [+ {+ "net": "GND",+ "layers": [+ "B.Cu"+ ],+ "priority": 0,+ "connection": "solid",+ "name": "Power return and signal reference",+ "polygon": [+ [+ 98.3,+ 30.3+ ],+ [+ 161.7,+ 30.3+ ],+ [+ 161.7,+ 101.7+ ],+ [+ 98.3,+ 101.7+ ]+ ]+ },+ {+ "net": "GND",+ "layers": [+ "F.Cu"+ ],+ "priority": 0,+ "connection": "solid",+ "name": "Top return and shield",+ "polygon": [+ [+ 98.3,+ 30.3+ ],+ [+ 161.7,+ 30.3+ ],+ [+ 161.7,+ 101.7+ ],+ [+ 98.3,+ 101.7+ ]+ ]+ },+ {+ "name": "D1 heat spread front",+ "net": "LOAD_POS",+ "layers": [+ "F.Cu"+ ],+ "polygon": [+ [+ 106.5,+ 87.5+ ],+ [+ 114.5,+ 87.5+ ],+ [+ 114.5,+ 95+ ],+ [+ 106.5,+ 95+ ]+ ],+ "priority": 3,+ "connection": "solid",+ "clearance": 0.2,+ "minThickness": 0.25+ },+ {+ "name": "D1 heat spread back",+ "net": "LOAD_POS",+ "layers": [+ "B.Cu"+ ],+ "polygon": [+ [+ 106.5,+ 87.5+ ],+ [+ 114.5,+ 87.5+ ],+ [+ 114.5,+ 95+ ],+ [+ 106.5,+ 95+ ]+ ],+ "priority": 3,+ "connection": "solid",+ "clearance": 0.2,+ "minThickness": 0.25+ },+ {+ "name": "Shunt positive spread front",+ "net": "SHUNT_P",+ "layers": [+ "F.Cu"+ ],+ "polygon": [+ [+ 134.5,+ 84.7+ ],+ [+ 138,+ 84.7+ ],+ [+ 138,+ 88+ ],+ [+ 134.5,+ 88+ ]+ ],+ "priority": 3,+ "connection": "solid",+ "clearance": 0.2,+ "minThickness": 0.25+ },+ {+ "name": "Shunt positive spread back",+ "net": "SHUNT_P",+ "layers": [+ "B.Cu"+ ],+ "polygon": [+ [+ 134.5,+ 84.7+ ],+ [+ 138,+ 84.7+ ],+ [+ 138,+ 88+ ],+ [+ 134.5,+ 88+ ]+ ],+ "priority": 3,+ "connection": "solid",+ "clearance": 0.2,+ "minThickness": 0.25+ }+ ],+ "notPoured": [+ "BOOST_SW",+ "SERVO_FB",+ "SHUNT_P_SENSE",+ "SHUNT_N_SENSE",+ "I_SET",+ "DAC_OUT",+ "SET_DIV"+ ],+ "fab": {+ "rules": "fab",+ "target": "fab"+ },+ "sourcing": {+ "profile": "fab"+ },+ "molecule": {+ "pin": "medium",+ "gridMm": 2,+ "edgeMarginMm": 2,+ "cornerPinsNet": "GND"+ },+ "requireEvidence": [+ "calcs",+ "simulation"+ ],+ "qualificationNote": "Limits are simultaneous. MOSFET25W plus diode/shunt losses are conservative separate layout screens, not one physical operating point. Heatsink contact, mounted airflow, USB impedance, contact current ratings and prototype tests remain unverified.",+ "planes": {+ "GND": "B.Cu"+ },+ "netClearance": {+ "USB_VBUS": 0.27+ }+}
design/thermal-vias-plan-after-locality-fix.txtadded+5@@ -0,0 +1,5 @@+OK: heatsink via plan (2 vias): aiflow/run/plan-thermal-vias.json+ D1 LOAD_POS target 10 existing 4 planned 0 (room for 4 of 10 vias within 3 mm of D1 and inside both planned LOAD_POS copper regions: review local copper and cooling; native refill/connectivity still required)+ Q1 LOAD_POS target 16 existing 0 planned 0 (room for 0 of 16 vias within 3 mm of Q1 and inside both planned LOAD_POS copper regions: review local copper and cooling; native refill/connectivity still required)+ RSH1 SHUNT_P target 6 existing 0 planned 2 (room for 2 of 6 vias within 3 mm of RSH1 and inside both planned SHUNT_P copper regions: review local copper and cooling; native refill/connectivity still required)+Hint: Review it with the human in one line per part, then `thermal-vias land`. A part with a note needs your call: pour its net on the other layer, move a neighbour, or `--ack REF --why`.
design/thermal-vias-plan-before-locality-fix.jsonadded+545@@ -0,0 +1,545 @@+{+ "engine": "adom-aiflow thermal-vias plan",+ "nets": [+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 111.73255717553582,+ 93.88570862079703+ ],+ {+ "layer": "B.Cu",+ "x": 111.73255717553582,+ "y": 93.88570862079703+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for D1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 110.83166329011792,+ 94.09133177126166+ ],+ {+ "layer": "B.Cu",+ "x": 110.83166329011792,+ "y": 94.09133177126166+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for D1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 109.91018510473542,+ 94.02227652776365+ ],+ {+ "layer": "B.Cu",+ "x": 109.91018510473542,+ "y": 94.02227652776365+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for D1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 114.55,+ 91.0+ ],+ {+ "layer": "B.Cu",+ "x": 114.55,+ "y": 91.0+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for D1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 113.62587555031996,+ 93.53901105826183+ ],+ {+ "layer": "B.Cu",+ "x": 113.62587555031996,+ "y": 93.53901105826183+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for D1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 112.95877643722599,+ 94.16838661138242+ ],+ {+ "layer": "B.Cu",+ "x": 112.95877643722599,+ "y": 94.16838661138242+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for D1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 126.78952567432339,+ 79.64352717422659+ ],+ {+ "layer": "B.Cu",+ "x": 126.78952567432339,+ "y": 79.64352717422659+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 127.68605748068508,+ 79.56045126807716+ ],+ {+ "layer": "B.Cu",+ "x": 127.68605748068508,+ "y": 79.56045126807716+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 129.2705718471906,+ 80.34944567306593+ ],+ {+ "layer": "B.Cu",+ "x": 129.2705718471906,+ "y": 80.34944567306593+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 129.71242537262157,+ 79.5882413178822+ ],+ {+ "layer": "B.Cu",+ "x": 129.71242537262157,+ "y": 79.5882413178822+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 130.2795840350034,+ 80.28537296488307+ ],+ {+ "layer": "B.Cu",+ "x": 130.2795840350034,+ "y": 80.28537296488307+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 124.21539934775767,+ 79.41251732228625+ ],+ {+ "layer": "B.Cu",+ "x": 124.21539934775767,+ "y": 79.41251732228625+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 126.53653812408129,+ 77.95404916444544+ ],+ {+ "layer": "B.Cu",+ "x": 126.53653812408129,+ "y": 77.95404916444544+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 127.46,+ 77.85+ ],+ {+ "layer": "B.Cu",+ "x": 127.46,+ "y": 77.85+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 128.3834618759187,+ 77.95404916444544+ ],+ {+ "layer": "B.Cu",+ "x": 128.3834618759187,+ "y": 77.95404916444544+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 131.19902080179503,+ 80.19938248266213+ ],+ {+ "layer": "B.Cu",+ "x": 131.19902080179503,+ "y": 80.19938248266213+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 131.50595083555456,+ 81.0765381240813+ ],+ {+ "layer": "B.Cu",+ "x": 131.50595083555456,+ "y": 81.0765381240813+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 122.79763885297821,+ 80.19379166906424+ ],+ {+ "layer": "B.Cu",+ "x": 122.79763885297821,+ "y": 80.19379166906424+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 123.20891432135193,+ 79.36783918561322+ ],+ {+ "layer": "B.Cu",+ "x": 123.20891432135193,+ "y": 79.36783918561322+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 125.2313082211173,+ 77.5241835432247+ ],+ {+ "layer": "B.Cu",+ "x": 125.2313082211173,+ "y": 77.5241835432247+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 126.09168504963958,+ 77.19087178413591+ ],+ {+ "layer": "B.Cu",+ "x": 126.09168504963958,+ "y": 77.19087178413591+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "LOAD_POS",+ "paths": [+ [+ [+ 126.99865820268349,+ 77.02132911852483+ ],+ {+ "layer": "B.Cu",+ "x": 126.99865820268349,+ "y": 77.02132911852483+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for Q1",+ "width": 0.6+ },+ {+ "net": "SHUNT_P",+ "paths": [+ [+ [+ 135.43169993329695,+ 86.5669832471314+ ],+ {+ "layer": "B.Cu",+ "x": 135.43169993329695,+ "y": 86.5669832471314+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for RSH1",+ "width": 0.6+ },+ {+ "net": "SHUNT_P",+ "paths": [+ [+ [+ 134.98097673374127,+ 87.34402326625873+ ],+ {+ "layer": "B.Cu",+ "x": 134.98097673374127,+ "y": 87.34402326625873+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for RSH1",+ "width": 0.6+ },+ {+ "net": "SHUNT_P",+ "paths": [+ [+ [+ 134.3,+ 85.7+ ],+ {+ "layer": "B.Cu",+ "x": 134.3,+ "y": 85.7+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for RSH1",+ "width": 0.6+ },+ {+ "net": "SHUNT_P",+ "paths": [+ [+ [+ 138.70418283027627,+ 88.09950489857478+ ],+ {+ "layer": "B.Cu",+ "x": 138.70418283027627,+ "y": 88.09950489857478+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for RSH1",+ "width": 0.6+ },+ {+ "net": "SHUNT_P",+ "paths": [+ [+ [+ 134.54581716972373,+ 88.09950489857478+ ],+ {+ "layer": "B.Cu",+ "x": 134.54581716972373,+ "y": 88.09950489857478+ }+ ]+ ],+ "viaDrill": 0.3,+ "viaSize": 0.6,+ "why": "heatsink via for RSH1",+ "width": 0.6+ }+ ]+}
docs/build-clips.md+7@@ -99,3 +99,10 @@ Three vias visibly land beside the diode. 6.4-second excerpt, normal speed, sour A normal `status` command in AIFlow 0.1.70 opens the electronic-load timeline in Hydrogen without `timeline open`. Native recording, normal speed, 6.8-second excerpt. The page reports the real unfinished stage. Recorder sample-count warning is retained with the raw take. <video width="100%" playsinline controls preload="metadata" poster="docs/clips/aiflow-dashboard-auto-open-poster.jpg" src="docs/clips/aiflow-dashboard-auto-open.mp4"></video>+++## 16. Reviewing the thermal copper++Native inspection of the diode and shunt nets after the saved-board DRC passed. 9.8 seconds, normal speed. This shows selection and framing of the existing layout, not a new copper landing or a temperature measurement. Recorder sample-count warning is retained.++<video width="100%" playsinline controls preload="metadata" poster="docs/clips/thermal-copper-review-poster.jpg" src="docs/clips/thermal-copper-review.mp4"></video>
docs/clips/thermal-copper-review-poster.jpgadded⋯ 1 unchanged line ⋯
docs/clips/thermal-copper-review.mp4added⋯ 1 unchanged line ⋯
tools/review_local_thermal_plan.pyadded+13@@ -0,0 +1,13 @@+"""Native disposable candidate: apply the exact AIFlow thermal plan and refill."""+import pcbnew as k,json,shutil+from pathlib import Path+p=Path(__file__).parent+b=k.LoadBoard(str(p/'source.kicad_pcb'))+plan=json.loads((p/'plan.json').read_text())+for entry in plan['nets']:+ for path in entry['paths']:+ x,y=path[0]+ v=k.PCB_VIA(b);v.SetPosition(k.VECTOR2I(k.FromMM(x),k.FromMM(y)));v.SetWidth(k.FromMM(entry['viaSize']));v.SetDrill(k.FromMM(entry['viaDrill']));v.SetLayerPair(k.F_Cu,k.B_Cu);v.SetNetCode(b.FindNet(entry['net']).GetNetCode());b.Add(v)+k.ZONE_FILLER(b).Fill(b.Zones());k.SaveBoard(str(p/'candidate.kicad_pcb'),b)+for ext in ['kicad_pro','kicad_dru']:shutil.copy2(p/('source.'+ext),p/('candidate.'+ext))+print('Candidate saved; exit before native CLI DRC.')
videos/inventory.json+8−2@@ -1,6 +1,6 @@ {- "rawTakeCount": 36,- "reviewedExcerptCount": 15,+ "rawTakeCount": 37,+ "reviewedExcerptCount": 16, "countingRule": "Unique raw window recording filenames in this project; excludes derivative action/speed exports and reference projects. Raw count includes rejected takes.", "takes": [ {@@ -218,6 +218,12 @@ "durationSeconds": 6.9, "topic": "AIFlow automatically opens dashboard on status command", "review": "Native Hydrogen action visually reviewed and full decode passed; 6.8 s normal-speed excerpt. Recorder sample-count warning retained."+ },+ {+ "file": "videos/raw/window-400958-20261009-103235.mp4",+ "durationSeconds": 9.9,+ "topic": "Native diode and shunt thermal copper review",+ "review": "Contact sheet reviewed and complete decode passed; 9.8 second normal-speed inspection excerpt. Copper outlines and changing selection/zoom visible; not a construction take. Recorder sample-count warning retained." } ] }