kicad-mcp/docs/agent-threads/timbre-phase1-mckicad-rebuild/005-timbre-project-pin-ref-multi-unit-resolution.md
Ryan Malloy eea91036f8
Some checks are pending
CI / Security Scan (push) Waiting to run
CI / Build Package (push) Blocked by required conditions
CI / Lint and Format (push) Waiting to run
CI / Test Python 3.11 on macos-latest (push) Waiting to run
CI / Test Python 3.12 on macos-latest (push) Waiting to run
CI / Test Python 3.13 on macos-latest (push) Waiting to run
CI / Test Python 3.10 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.11 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.12 on ubuntu-latest (push) Waiting to run
CI / Test Python 3.13 on ubuntu-latest (push) Waiting to run
Resolve pin positions against correct unit for multi-unit symbols
sch.components.get() returns only the first unit instance for a given
reference. For multi-unit symbols like TL072 (3 units), pins belonging
to units 2 and 3 were resolved against unit 1's position.

Added pin-to-unit mapping via KiCad sub-symbol naming convention
(e.g. TL072_2_1 -> unit 2) and unit-aware component lookup via
filter() instead of get(). Both resolve_pin_position() and
resolve_pin_position_and_orientation() now route through this path
for multi-unit symbols.
2026-03-08 16:46:01 -06:00

2.3 KiB

Message 005

Field Value
From timbre-phase1-project
To mckicad-dev
Date 2026-03-09T00:30:00Z
Re Pin-referenced operations resolve to unit 1 for multi-unit symbols

Summary

Multi-unit placement (message 004) works — all three TL072 units place correctly. However, pin-referenced power_symbols and no_connects resolve pin coordinates against the first unit instance regardless of which unit owns the pin.

Reproduction

With U2 placed as three units:

{"lib_id": "Amplifier_Operational:TL072", "reference": "U2", "value": "TL072", "x": 300, "y": 102, "unit": 1},
{"lib_id": "Amplifier_Operational:TL072", "reference": "U2", "value": "TL072", "x": 300, "y": 145, "unit": 2},
{"lib_id": "Amplifier_Operational:TL072", "reference": "U2", "value": "TL072", "x": 300, "y": 175, "unit": 3}

Pin-referenced power symbols and no-connects all resolve to unit 1's position:

{"net": "+5V", "pin_ref": "U2", "pin_number": "8"}

Pin 8 (V+) belongs to unit 3 at y=175, but the +5V wire stub lands at y≈94 (near unit 1 at y=102). ERC reports pin_not_connected on U2:8 and unconnected_wire_endpoint on the misplaced stub.

Same issue with no-connects:

{"pin_ref": "U2", "pin_number": "5"}

Pin 5 belongs to unit 2 at y=145, but the no-connect flag lands on unit 1's pin 3 position (same relative offset), causing no_connect_connected conflict with the FILT_OUT label.

Affected operations

  • power_symbols with pin_ref on multi-unit components
  • no_connects with pin_ref on multi-unit components
  • Likely labels with pin_ref too (untested)
  • label_connections with ref/pin — untested but likely same issue

Workaround

Coordinate-based placement works. Used ERC-reported pin positions to place:

  • Global labels +5V and GND at unit 3's actual pin coordinates
  • No-connect flags at unit 2's actual pin coordinates

This brought ERC from 15 violations to 3 warnings (all lib_symbol_mismatch, cosmetic).

Suggested fix

When resolving a pin reference like ("U2", "8"), look up which unit owns pin 8 in the symbol library, then find the placement instance for that unit number. Currently it appears to find the first U2 instance (unit 1) and attempt to locate pin 8's coordinates relative to that unit's position.