CircuitPython version and board name
Adafruit CircuitPython 10.2.1 on 2026-05-13; Adafruit QT Py ESP32-S3 4MB Flash 2MB PSRAM with ESP32S3
Board ID:adafruit_qtpy_esp32s3_4mbflash_2mbpsram
UID:4F21AFA56341
MAC:54:64:CB:3F:40:4F
Code/REPL
"""Windows demo
pip install pyserial wmi
"""
from pprint import pprint
from serial.tools.list_ports_windows import comports
discovered_comports = {
comport.device: {
"com_port": comport.device,
"com_id": comport.hwid,
"serial_number": comport.serial_number,
}
for comport in sorted(comports()) if comport.device != "COM1"
}
pprint(discovered_comports)
print()
from wmi import WMI
disks_and_serial_numbers = {}
host_pc = WMI()
for disk in list(host_pc.Win32_PhysicalMedia()):
# Full value has format '\\\\.\\PHYSICALDRIVE0'
disk_id = disk.wmi_property("Tag").value.split("\\")[-1]
serial_number = disk.wmi_property("SerialNumber").value
disks_and_serial_numbers.update(
{
disk_id: {
"serial_number": serial_number,
}
}
)
pprint(disks_and_serial_numbers)
print()
partitions_and_disks = {}
for entry in list(host_pc.Win32_DiskDriveToDiskPartition()):
# Full value has format '\\\\HOSTNAME\\root\\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #0"'
partition = entry.wmi_property("Dependent").value.split("=")[-1].replace('"', "")
# Full value has format '\\\\HOSTNAME\\root\\cimv2:Win32_DiskDrive.DeviceID="\\\\\\\\.\\\\PHYSICALDRIVE0"'
disk_id = entry.wmi_property("Antecedent").value.split("=")[-1].replace('"', "").split("\\")[-1]
partitions_and_disks.update(
{
disk_id: {
"drive_partition": partition,
}
}
)
pprint(partitions_and_disks)
print()
drive_letters_and_partitions = {}
for entry in list(host_pc.Win32_LogicalDiskToPartition()):
# Full value has format '\\\\HOSTNAME\\root\\cimv2:Win32_LogicalDisk.DeviceID="C:"'
drive_letter = entry.wmi_property("Dependent").value.split("=")[-1].replace('"', "")
# Full value has format '\\\\HOSTNAME\\root\\cimv2:Win32_DiskPartition.DeviceID="Disk #0, Partition #2"'
drive_partition = entry.wmi_property("Antecedent").value.split("=")[-1].replace('"', "")
drive_letters_and_partitions.update(
{
drive_partition: {
"drive_root": drive_letter,
}
}
)
pprint(drive_letters_and_partitions)
print()
drive_letters_and_labels = {}
for volume in list(host_pc.Win32_Volume()):
drive_letter = volume.wmi_property("DriveLetter").value
if drive_letter:
drive_label = volume.wmi_property("Label").value
drive_letters_and_labels.update(
{
drive_letter: {
"drive_label": drive_label,
}
}
)
pprint(drive_letters_and_labels)
Behavior
Running the Python code above on my Windows PC results in this output.
The code searches for serial ports and collects storage information from WMI.
Note that I used diff syntax so that I can highlight specific lines.
python demo.py
{'COM4': {'com_id': 'USB VID:PID=239A:8144 SER=4F21AFA56341 LOCATION=1-7:x.0',
'com_port': 'COM4',
+ 'serial_number': '4F21AFA56341'}}
{'PHYSICALDRIVE0': {'serial_number': '6479_A750_C0D0_13BD.'},
'PHYSICALDRIVE1': {'serial_number': 'E823_8FA6_BF53_0001_001B_448B_47AF_9EF8.'},
+ 'PHYSICALDRIVE2': {'serial_number': '4F21AFA56340'},
+ 'PHYSICALDRIVE3': {'serial_number': '4F21AFA56341'}}
{'PHYSICALDRIVE0': {'drive_partition': 'Disk #0, Partition #2'},
'PHYSICALDRIVE1': {'drive_partition': 'Disk #1, Partition #0'},
'PHYSICALDRIVE2': {'drive_partition': 'Disk #2, Partition #0'}}
{'Disk #0, Partition #1': {'drive_root': 'C:'},
'Disk #1, Partition #0': {'drive_root': 'X:'},
'Disk #2, Partition #0': {'drive_root': 'E:'}}
{'C:': {'drive_label': 'Windows'},
- 'D:': {'drive_label': None},
+ 'E:': {'drive_label': 'CIRCUITPY'},
'X:': {'drive_label': 'xtra'}}
Observations
- The serial number for the QT Py's serial port matches the serial number for
PHYSICALDRIVE3
PHYSICALDRIVE3 has no partitions and it presents as D:
- Instead, the QT Py's disk drive is
E: and belongs to PHYSICALDRIVE2
- The serial number for the QT Py's drive is off-by-one from its serial port
The extra disk drive also presents in Explorer.
Description
This behavior seems similar to this report for CircuitPython 10.0.0-alpha.2 on Raspberry Pi Pico W with rp2040
https://forums.adafruit.com/viewtopic.php?p=1052262
but instead the device is Adafruit QT Py ESP32-S3 4MB Flash.
For Adafruit QT Py ESP32-S3 devices, is this a bug or expected behavior?
If this is expected for CircuitPython 10, would it be possible to declare the same serial number for the UART and disk drive, and use the off-by-one serial number for the extra drive?
Additional information
In my projects, I use a matching serial number between COM ports and physical drives to detect CircuitPython devices and separate them from other COM ports and disk drives.
When I upgraded one of my QT Py devices from CircuitPython 9 to CircuitPython 10, I noticed this new disk drive and off-by-one serial number because my CircuitPython detection code started returning empty results.
CircuitPython version and board name
Code/REPL
Behavior
Running the Python code above on my Windows PC results in this output.
The code searches for serial ports and collects storage information from WMI.
Note that I used
diffsyntax so that I can highlight specific lines.python demo.py{'COM4': {'com_id': 'USB VID:PID=239A:8144 SER=4F21AFA56341 LOCATION=1-7:x.0', 'com_port': 'COM4', + 'serial_number': '4F21AFA56341'}} {'PHYSICALDRIVE0': {'serial_number': '6479_A750_C0D0_13BD.'}, 'PHYSICALDRIVE1': {'serial_number': 'E823_8FA6_BF53_0001_001B_448B_47AF_9EF8.'}, + 'PHYSICALDRIVE2': {'serial_number': '4F21AFA56340'}, + 'PHYSICALDRIVE3': {'serial_number': '4F21AFA56341'}} {'PHYSICALDRIVE0': {'drive_partition': 'Disk #0, Partition #2'}, 'PHYSICALDRIVE1': {'drive_partition': 'Disk #1, Partition #0'}, 'PHYSICALDRIVE2': {'drive_partition': 'Disk #2, Partition #0'}} {'Disk #0, Partition #1': {'drive_root': 'C:'}, 'Disk #1, Partition #0': {'drive_root': 'X:'}, 'Disk #2, Partition #0': {'drive_root': 'E:'}} {'C:': {'drive_label': 'Windows'}, - 'D:': {'drive_label': None}, + 'E:': {'drive_label': 'CIRCUITPY'}, 'X:': {'drive_label': 'xtra'}}Observations
PHYSICALDRIVE3PHYSICALDRIVE3has no partitions and it presents asD:E:and belongs toPHYSICALDRIVE2The extra disk drive also presents in Explorer.
Description
This behavior seems similar to this report for CircuitPython 10.0.0-alpha.2 on Raspberry Pi Pico W with rp2040
https://forums.adafruit.com/viewtopic.php?p=1052262
but instead the device is Adafruit QT Py ESP32-S3 4MB Flash.
For Adafruit QT Py ESP32-S3 devices, is this a bug or expected behavior?
If this is expected for CircuitPython 10, would it be possible to declare the same serial number for the UART and disk drive, and use the off-by-one serial number for the extra drive?
Additional information
In my projects, I use a matching serial number between COM ports and physical drives to detect CircuitPython devices and separate them from other COM ports and disk drives.
When I upgraded one of my QT Py devices from CircuitPython 9 to CircuitPython 10, I noticed this new disk drive and off-by-one serial number because my CircuitPython detection code started returning empty results.