Skip to content

10.2.1: Extra but unusable disk drive with QT Py ESP32-S3 #11076

Description

@wireddown

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.

Image

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions