# _detect_port.ps1 -- Detect the best serial port via arduino-cli # # Called by upload.bat and monitor.bat. Outputs a single port name # (e.g. COM3) or nothing if no port is found. # # If .anvil.local contains a vid_pid, resolves the device to its # current COM port (handles reassignment after replug). # Falls back to saved port, then auto-detect. param( [string]$VidPid = "", [string]$SavedPort = "" ) $ErrorActionPreference = 'SilentlyContinue' $raw = arduino-cli board list --format json 2>$null if (-not $raw) { # No arduino-cli or no output; fall back to saved port if ($SavedPort) { Write-Output $SavedPort } exit } $data = $raw | ConvertFrom-Json if (-not $data.detected_ports) { if ($SavedPort) { Write-Output $SavedPort } exit } $serial = $data.detected_ports | Where-Object { $_.port.protocol -eq 'serial' } if (-not $serial) { if ($SavedPort) { Write-Output $SavedPort } exit } # -- Try VID:PID resolution first ------------------------------------------ if ($VidPid) { $parts = $VidPid -split ':' if ($parts.Count -eq 2) { $targetVid = $parts[0].ToLower() $targetPid = $parts[1].ToLower() foreach ($p in $serial) { $pVid = ($p.port.properties.vid -replace '^0x','').ToLower() $pPid = ($p.port.properties.pid -replace '^0x','').ToLower() if ($pVid -eq $targetVid -and $pPid -eq $targetPid) { Write-Output $p.port.address exit } } # VID:PID not found -- device not connected # Fall through to saved port / auto-detect } } # -- Fall back to saved port if it exists on the system -------------------- if ($SavedPort) { $found = $serial | Where-Object { $_.port.address -eq $SavedPort } | Select-Object -First 1 if ($found) { Write-Output $SavedPort exit } # Saved port not present either; fall through to auto-detect } # -- Auto-detect: prefer USB serial ports ---------------------------------- $usb = $serial | Where-Object { $_.port.protocol_label -like '*USB*' } | Select-Object -First 1 if ($usb) { Write-Output $usb.port.address exit } # Fall back to any serial port $any = $serial | Select-Object -First 1 if ($any) { Write-Output $any.port.address }