diff --git a/frontend/src/components/velxio-components/PiPicoWElement.ts b/frontend/src/components/velxio-components/PiPicoWElement.ts index cd9efb5a..0c7c6f73 100644 --- a/frontend/src/components/velxio-components/PiPicoWElement.ts +++ b/frontend/src/components/velxio-components/PiPicoWElement.ts @@ -39,15 +39,26 @@ const PINS_PI_PICO_W = [ { name: 'GP22', x: 97, y: 157 }, { name: 'RUN', x: 97, y: 144 }, { name: 'GP26', x: 97, y: 131 }, + // Alias entries: examples and saved projects also reference the ADC pins + // as A0/A1/A2 (Arduino-style) — same physical pins, same coordinates. + // Without these the wire endpoint anchored at the board corner. Mirrors + // the RX2/16 dual-entry precedent in Esp32Element. + { name: 'A0', x: 97, y: 131 }, { name: 'GP27', x: 97, y: 119 }, + { name: 'A1', x: 97, y: 119 }, { name: 'GND.7', x: 97, y: 106 }, { name: 'GP28', x: 97, y: 93 }, + { name: 'A2', x: 97, y: 93 }, { name: 'ADC_VREF', x: 97, y: 81 }, { name: '3V3', x: 97, y: 68 }, { name: '3V3_EN', x: 97, y: 55 }, { name: 'GND.8', x: 97, y: 42 }, { name: 'VSYS', x: 97, y: 30 }, { name: 'VBUS', x: 97, y: 17 }, + // GP25 is the onboard LED, not a header pin — but pico-blink-style + // examples wire an external LED to it for visibility. Anchor at the LED + // silk so those wires stop falling back to the board corner. + { name: 'GP25', x: 40, y: 14 }, ]; class PiPicoWElement extends HTMLElement { diff --git a/frontend/src/data/examples-storage-microsd.ts b/frontend/src/data/examples-storage-microsd.ts index 0a43fed2..66d3d91f 100644 --- a/frontend/src/data/examples-storage-microsd.ts +++ b/frontend/src/data/examples-storage-microsd.ts @@ -194,7 +194,7 @@ export const microsdExamples: ExampleProject[] = [ { id: 'w-miso', start: { componentId: 'esp32', pinName: '19' }, end: { componentId: 'sd1', pinName: 'MISO' }, color: '#22cc22' }, { id: 'w-sck', start: { componentId: 'esp32', pinName: '18' }, end: { componentId: 'sd1', pinName: 'SCK' }, color: '#ffdd33' }, { id: 'w-vcc', start: { componentId: 'esp32', pinName: '3V3' }, end: { componentId: 'sd1', pinName: 'VCC' }, color: '#ff4444' }, - { id: 'w-gnd', start: { componentId: 'esp32', pinName: 'GND.1' }, end: { componentId: 'sd1', pinName: 'GND' }, color: '#000000' }, + { id: 'w-gnd', start: { componentId: 'esp32', pinName: 'GND' }, end: { componentId: 'sd1', pinName: 'GND' }, color: '#000000' }, ], }, ]; diff --git a/frontend/src/data/examples.ts b/frontend/src/data/examples.ts index f30c4960..03134251 100644 --- a/frontend/src/data/examples.ts +++ b/frontend/src/data/examples.ts @@ -4484,7 +4484,7 @@ void loop() { wires: [ { id: 'w1', - start: { componentId: 'arduino-uno', pinName: 'TX' }, + start: { componentId: 'arduino-uno', pinName: 'GP0' }, end: { componentId: 'r-led-rx-a', pinName: '1' }, color: '#ff8800', }, diff --git a/frontend/src/utils/pinPositionCalculator.ts b/frontend/src/utils/pinPositionCalculator.ts index 10b5b501..74437123 100644 --- a/frontend/src/utils/pinPositionCalculator.ts +++ b/frontend/src/utils/pinPositionCalculator.ts @@ -71,6 +71,31 @@ export function calculatePinPosition( pin = pinInfo.find((p: any) => p.description === `GPIO${gpioNum}`); } } + // Generic alias fallbacks — every unresolved endpoint used to silently + // anchor at the board CORNER (0,0 of the element), which users read as a + // broken circuit. The names below are electrically identical spellings + // that boards/examples/saved projects disagree on (a 2026-08 audit found + // 15 gallery examples and 28 saved projects wired to a spelling their + // board element doesn't expose). Only consulted after exact + the two + // legacy fallbacks above miss, so no existing resolution changes. + if (!pin) { + const candidates: string[] = []; + const dot = pinName.match(/^(.+)\.\d+$/); + if (dot) candidates.push(dot[1]); // GND.1 -> GND (esp32 classic) + if (pinName === '3.3V') candidates.push('3V3', '3V3.1', '3V'); + if (pinName === '3V3') candidates.push('3V3.1', '3.3V', '3V'); + if (pinName === '5V') candidates.push('5V.1', 'VBUS', 'VIN'); + if (pinName === 'GND2') candidates.push('GND.2'); + const dNum = pinName.match(/^D(\d+)$/); + if (dNum) candidates.push(dNum[1], `GP${dNum[1]}`); // D13 -> 13 (esp32) / GP13 (pico) + if (/^\d+$/.test(pinName)) candidates.push(`D${pinName}`, `GP${pinName}`); + if (pinName === '36') candidates.push('VP'); // ESP32 devkit silk for GPIO36 + if (pinName === '39') candidates.push('VN'); // ESP32 devkit silk for GPIO39 + for (const c of candidates) { + pin = pinInfo.find((p: any) => p.name === c); + if (pin) break; + } + } if (!pin) { console.warn(`[pinPositionCalculator] Pin ${pinName} not found on component ${componentId}`); console.warn(