I am making a universal programmer/monitor board with ATmega328 with Arduino as ISP. I use a USB hub chip to include multiple functions, thus when I connect the board more COM ports show up.
I have trouble getting to autodetect the right port with platformio, is there anything I can help myself with? So far I am under the impression auto-detect likes to take higher number location ports.
Here’s an output from pio device list:
COM9 #Actuall CH340 connected to the ATmega328 programmer
Hardware ID: USB VID:PID=1A86:7523 SER=9 LOCATION=1-188.8.131.52
Description: USB-SERIAL CH340 (COM9)
COM10 #USB to Serial monitor (contains a CH340)
Hardware ID: USB VID:PID=1A86:7523 SER=9 LOCATION=1-184.108.40.206
Description: USB-SERIAL CH340 (COM10)
COM1 #Some port I dont use
Hardware ID: ACPI\PNP0501\0
Description: Communications Port (COM1)
COM12 #Serial monitor port, prefers to take this port, if not connected then C10
Hardware ID: USB VID:PID=1A86:7523 SER=9 LOCATION=1-220.127.116.11
Description: USB-SERIAL CH340 (COM12)
Correct. The loop goes through all devices and returns the last one. Unless there’s a direct match by hardware ID (VID, PID). See core logic at
You can set the upload_port to a specific COM port or use a wildcard expression. If PIO grabs the wrong upload (or monitor_port), you can thus correct it.
There’s also the possibility of programmatically setting the upload port / $UPLOAD_PORT via a script. See docs. For that you of course also have to have a way to always tell to which board you’re uploading. You may e.g. want to match the USB serial number of the chip to that one USB serial converter chip you’re working with, or analyze the USB hubs tree structure / location path (e.g., target upload port is always connected to first port of USB hub?) to find the correct one and then env.Replace(UPLOAD_PORT = <correct port>) that result.