Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition
Forum Updated to NodeBB v4.3 + New Features

Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 266 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • A Offline
    A Offline
    Andrew23
    wrote on 17 Mar 2025, 15:07 last edited by
    #1

    I have an embedded USB device called 'Cruise Dongle USBP' with VID 0x0001 and PID 0x0002 (these values are just for testing) for which I loaded the WinUSB driver using Zadig.
    alt text
    alt text
    Now I want to communicate with this device in Qt using the libusb library, but when I search for it, the library cannot find it.

    void USBDevice::ScanUsbDevices()
    {
        libusb_context *ctx = nullptr;
        libusb_device **device_list = nullptr;
        ssize_t count;
    
        if (libusb_init(&ctx) != 0) {
            qWarning() << "Error initializing libusb";
        }
    
        // Get the device list
        count = libusb_get_device_list(ctx, &device_list);
    
        if (count < 0) {
            usbList->addItem("Error: Unable to get the device list.");
            libusb_exit(ctx);
            return;
        }
    
        qDebug() << "USB devices found:" << count;
    
        // usbList->addItem(QString("USB devices found: %1").arg(count));
    
        // Iterate over the found devices
        for (ssize_t i = 0; i < count; i++) {
            libusb_device *device = device_list[i];
            libusb_device_descriptor desc;
    
            if (libusb_get_device_descriptor(device, &desc) == 0) {
                QString info = QString("VID: 0x%1 PID: 0x%2")
                .arg(desc.idVendor, 4, 16, QChar('0'))
                    .arg(desc.idProduct, 4, 16, QChar('0'));
    
                // Try to open the device to read extra information
                libusb_device_handle *handle;
                if (libusb_open(device, &handle) == 0) {
                    unsigned char buffer[256];
    
                    if (desc.iManufacturer && libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, buffer, sizeof(buffer)) > 0) {
                        info += " | Manufacturer: " + QString::fromUtf8(reinterpret_cast<char*>(buffer));
                    }
    
                    if (desc.iProduct && libusb_get_string_descriptor_ascii(handle, desc.iProduct, buffer, sizeof(buffer)) > 0) {
                        info += " | Product: " + QString::fromUtf8(reinterpret_cast<char*>(buffer));
                    }
    
                    libusb_close(handle);
                }
    
                // usbList->addItem(info);
                qDebug() << info;
            }
        }
    
        // Free the device list
        libusb_free_device_list(device_list, 1);
        libusb_exit(ctx);
    }
    
    

    that returns

    AllK required contiguous memory = 675016 (64bit)
      8 HotK Handles: HandleSize 2112 PoolSize 16912 (bytes)
      64 LstK Handles: HandleSize 64 PoolSize 4112 (bytes)
      2048 LstInfoK Handles: HandleSize 64 PoolSize 131088 (bytes)
      128 UsbK Handles: HandleSize 96 PoolSize 12304 (bytes)
      64 DevK Handles: HandleSize 112 PoolSize 7184 (bytes)
      2048 OvlK Handles: HandleSize 104 PoolSize 213008 (bytes)
      64 OvlPoolK Handles: HandleSize 96 PoolSize 6160 (bytes)
      32 StmK Handles: HandleSize 176 PoolSize 5648 (bytes)
      2048 IsochK Handles: HandleSize 136 PoolSize 278544 (bytes)
    
    Dynamically allocated as needed:
    	KLST_DEVINFO = 2596 bytes each
    USB devices found: 6
    "VID: 0x8086 PID: 0xa36d"
    "VID: 0x8087 PID: 0x0aaa"
    "VID: 0x10de PID: 0x1ada"
    "VID: 0x0b05 PID: 0x1866 | Manufacturer: ASUSTeK Computer Inc. | Product: N-KEY Device"
    "VID: 0x046d PID: 0xc01e | Manufacturer: Logitech | Product: USB-PS/2 Optical Mouse"
    "VID: 0x1366 PID: 0x1050"
    

    I have tried reinstalling the drivers and changing them to Klibusb or others, but nothing works. Can anyone give me some advice?

    J 1 Reply Last reply 17 Mar 2025, 15:12
    1
    • A Andrew23
      17 Mar 2025, 15:07

      I have an embedded USB device called 'Cruise Dongle USBP' with VID 0x0001 and PID 0x0002 (these values are just for testing) for which I loaded the WinUSB driver using Zadig.
      alt text
      alt text
      Now I want to communicate with this device in Qt using the libusb library, but when I search for it, the library cannot find it.

      void USBDevice::ScanUsbDevices()
      {
          libusb_context *ctx = nullptr;
          libusb_device **device_list = nullptr;
          ssize_t count;
      
          if (libusb_init(&ctx) != 0) {
              qWarning() << "Error initializing libusb";
          }
      
          // Get the device list
          count = libusb_get_device_list(ctx, &device_list);
      
          if (count < 0) {
              usbList->addItem("Error: Unable to get the device list.");
              libusb_exit(ctx);
              return;
          }
      
          qDebug() << "USB devices found:" << count;
      
          // usbList->addItem(QString("USB devices found: %1").arg(count));
      
          // Iterate over the found devices
          for (ssize_t i = 0; i < count; i++) {
              libusb_device *device = device_list[i];
              libusb_device_descriptor desc;
      
              if (libusb_get_device_descriptor(device, &desc) == 0) {
                  QString info = QString("VID: 0x%1 PID: 0x%2")
                  .arg(desc.idVendor, 4, 16, QChar('0'))
                      .arg(desc.idProduct, 4, 16, QChar('0'));
      
                  // Try to open the device to read extra information
                  libusb_device_handle *handle;
                  if (libusb_open(device, &handle) == 0) {
                      unsigned char buffer[256];
      
                      if (desc.iManufacturer && libusb_get_string_descriptor_ascii(handle, desc.iManufacturer, buffer, sizeof(buffer)) > 0) {
                          info += " | Manufacturer: " + QString::fromUtf8(reinterpret_cast<char*>(buffer));
                      }
      
                      if (desc.iProduct && libusb_get_string_descriptor_ascii(handle, desc.iProduct, buffer, sizeof(buffer)) > 0) {
                          info += " | Product: " + QString::fromUtf8(reinterpret_cast<char*>(buffer));
                      }
      
                      libusb_close(handle);
                  }
      
                  // usbList->addItem(info);
                  qDebug() << info;
              }
          }
      
          // Free the device list
          libusb_free_device_list(device_list, 1);
          libusb_exit(ctx);
      }
      
      

      that returns

      AllK required contiguous memory = 675016 (64bit)
        8 HotK Handles: HandleSize 2112 PoolSize 16912 (bytes)
        64 LstK Handles: HandleSize 64 PoolSize 4112 (bytes)
        2048 LstInfoK Handles: HandleSize 64 PoolSize 131088 (bytes)
        128 UsbK Handles: HandleSize 96 PoolSize 12304 (bytes)
        64 DevK Handles: HandleSize 112 PoolSize 7184 (bytes)
        2048 OvlK Handles: HandleSize 104 PoolSize 213008 (bytes)
        64 OvlPoolK Handles: HandleSize 96 PoolSize 6160 (bytes)
        32 StmK Handles: HandleSize 176 PoolSize 5648 (bytes)
        2048 IsochK Handles: HandleSize 136 PoolSize 278544 (bytes)
      
      Dynamically allocated as needed:
      	KLST_DEVINFO = 2596 bytes each
      USB devices found: 6
      "VID: 0x8086 PID: 0xa36d"
      "VID: 0x8087 PID: 0x0aaa"
      "VID: 0x10de PID: 0x1ada"
      "VID: 0x0b05 PID: 0x1866 | Manufacturer: ASUSTeK Computer Inc. | Product: N-KEY Device"
      "VID: 0x046d PID: 0xc01e | Manufacturer: Logitech | Product: USB-PS/2 Optical Mouse"
      "VID: 0x1366 PID: 0x1050"
      

      I have tried reinstalling the drivers and changing them to Klibusb or others, but nothing works. Can anyone give me some advice?

      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 17 Mar 2025, 15:12 last edited by
      #2

      @Andrew23 libusb is not part of Qt, you should consider asking there

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      A 1 Reply Last reply 17 Mar 2025, 18:36
      1
      • J Offline
        J Offline
        JoeCFD
        wrote on 17 Mar 2025, 17:54 last edited by
        #3

        And is it a better choice to use native Windows code to do the same job?

        1 Reply Last reply
        1
        • J jsulm
          17 Mar 2025, 15:12

          @Andrew23 libusb is not part of Qt, you should consider asking there

          A Offline
          A Offline
          Andrew23
          wrote on 17 Mar 2025, 18:36 last edited by
          #4

          @jsulm said in Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition:

          @Andrew23 libusb is not part of Qt, you should consider asking there

          Yes, I know, but I thought that maybe someone had encountered the same issue while implementing a Qt application that uses the libusb library.

          @JoeCFD said in Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition:

          And is it a better choice to use native Windows code to do the same job?

          What do you mean? Sorry, but I’m a beginner in implementing USB communication between a device and an application.

          J 1 Reply Last reply 17 Mar 2025, 19:09
          0
          • A Andrew23
            17 Mar 2025, 18:36

            @jsulm said in Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition:

            @Andrew23 libusb is not part of Qt, you should consider asking there

            Yes, I know, but I thought that maybe someone had encountered the same issue while implementing a Qt application that uses the libusb library.

            @JoeCFD said in Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition:

            And is it a better choice to use native Windows code to do the same job?

            What do you mean? Sorry, but I’m a beginner in implementing USB communication between a device and an application.

            J Offline
            J Offline
            JoeCFD
            wrote on 17 Mar 2025, 19:09 last edited by JoeCFD
            #5

            @Andrew23 Try to use Qt serial port to detect USB Devices

            #include <QCoreApplication>
            #include <QSerialPortInfo>
            #include <QDebug>
            
            int main(int argc, char *argv[])
            {
               QCoreApplication a(argc, argv);
            
               // List all available serial ports
               QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
               foreach (const QSerialPortInfo &port, ports) {
                   qDebug() << "Port:" << port.portName();
                   qDebug() << "Description:" << port.description();
                   qDebug() << "Manufacturer:" << port.manufacturer();
                   qDebug() << "Vendor ID:" << port.vendorIdentifier();
                   qDebug() << "Product ID:" << port.productIdentifier();
                   qDebug() << "-----------------------------------";
               }
            
               return a.exec();
            }
            

            Open and Communicate with the USB Device

            #include <QCoreApplication>
            #include <QSerialPort>
            #include <QSerialPortInfo>
            #include <QDebug>
            
            int main(int argc, char *argv[])
            {
                QCoreApplication a(argc, argv);
            
                // Create a serial port object
                QSerialPort serial;
            
                // Configure the serial port
                serial.setPortName("COM3"); // Replace with your device's port name
                serial.setBaudRate(QSerialPort::Baud9600);
                serial.setDataBits(QSerialPort::Data8);
                serial.setParity(QSerialPort::NoParity);
                serial.setStopBits(QSerialPort::OneStop);
                serial.setFlowControl(QSerialPort::NoFlowControl);
            
                // Open the serial port
                if (serial.open(QIODevice::ReadWrite)) {
                    qDebug() << "Connected to" << serial.portName();
            
                    // Write data to the device
                    QByteArray data = "Hello, USB Device!";
                    serial.write(data);
                    qDebug() << "Data sent:" << data;
            
                    // Read data from the device
                    if (serial.waitForReadyRead(5000)) { // Wait for 5 seconds
                        QByteArray response = serial.readAll();
                        qDebug() << "Response:" << response;
                    } else {
                        qDebug() << "Timeout: No response from device.";
                    }
            
                    // Close the serial port
                    serial.close();
                } else {
                    qDebug() << "Failed to open port" << serial.portName();
                }
            
                return a.exec();
            }
            

            If the code above does not work for you, try to find Windows API

            #include <windows.h>
            #include <setupapi.h>
            #include <iostream>
            #include <string>
            #include <vector>
            #include <iomanip>
            
            #pragma comment(lib, "setupapi.lib")
            
            // Function to convert a wide string to a std::string
            std::string WideStringToString(const std::wstring& wideStr) {
                if (wideStr.empty()) return std::string();
                int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, &wideStr[0], (int)wideStr.size(), nullptr, 0, nullptr, nullptr);
                std::string str(sizeNeeded, 0);
                WideCharToMultiByte(CP_UTF8, 0, &wideStr[0], (int)wideStr.size(), &str[0], sizeNeeded, nullptr, nullptr);
                return str;
            }
            
            // Function to enumerate USB devices
            void EnumerateUSBDevices() {
                HDEVINFO deviceInfoSet;
                SP_DEVINFO_DATA deviceInfoData;
                DWORD deviceIndex = 0;
            
                // Initialize the device information set for USB devices
                deviceInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_USB, nullptr, nullptr, DIGCF_PRESENT | DIGCF_PROFILE);
                if (deviceInfoSet == INVALID_HANDLE_VALUE) {
                    std::cerr << "Failed to get device information set." << std::endl;
                    return;
                }
            
                // Initialize the device information structure
                deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
            
                // Enumerate through all devices in the set
                while (SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex++, &deviceInfoData)) {
                    // Get the device instance ID (contains VID and PID)
                    wchar_t deviceID[256];
                    if (SetupDiGetDeviceInstanceId(deviceInfoSet, &deviceInfoData, deviceID, sizeof(deviceID) / sizeof(deviceID[0]), nullptr)) {
                        std::wstring deviceIDStr(deviceID);
                        std::string deviceIDUtf8 = WideStringToString(deviceIDStr);
            
                        // Extract VID and PID from the device instance ID
                        size_t vidPos = deviceIDUtf8.find("VID_");
                        size_t pidPos = deviceIDUtf8.find("PID_");
                        if (vidPos != std::string::npos && pidPos != std::string::npos) {
                            std::string vid = deviceIDUtf8.substr(vidPos + 4, 4);
                            std::string pid = deviceIDUtf8.substr(pidPos + 4, 4);
            
                            std::cout << "Device ID: " << deviceIDUtf8 << std::endl;
                            std::cout << "VID: " << vid << ", PID: " << pid << std::endl;
                        }
                    }
            
                    // Get the device description
                    wchar_t deviceDescription[256];
                    if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_FRIENDLYNAME, nullptr, (PBYTE)deviceDescription, sizeof(deviceDescription), nullptr)) {
                        std::wstring descriptionStr(deviceDescription);
                        std::string descriptionUtf8 = WideStringToString(descriptionStr);
                        std::cout << "Description: " << descriptionUtf8 << std::endl;
                    }
            
                    std::cout << "-----------------------------------" << std::endl;
                }
            
                // Clean up
                SetupDiDestroyDeviceInfoList(deviceInfoSet);
            }
            
            int main() {
                EnumerateUSBDevices();
                return 0;
            }
            
            A 1 Reply Last reply 18 Mar 2025, 08:58
            0
            • J JoeCFD
              17 Mar 2025, 19:09

              @Andrew23 Try to use Qt serial port to detect USB Devices

              #include <QCoreApplication>
              #include <QSerialPortInfo>
              #include <QDebug>
              
              int main(int argc, char *argv[])
              {
                 QCoreApplication a(argc, argv);
              
                 // List all available serial ports
                 QList<QSerialPortInfo> ports = QSerialPortInfo::availablePorts();
                 foreach (const QSerialPortInfo &port, ports) {
                     qDebug() << "Port:" << port.portName();
                     qDebug() << "Description:" << port.description();
                     qDebug() << "Manufacturer:" << port.manufacturer();
                     qDebug() << "Vendor ID:" << port.vendorIdentifier();
                     qDebug() << "Product ID:" << port.productIdentifier();
                     qDebug() << "-----------------------------------";
                 }
              
                 return a.exec();
              }
              

              Open and Communicate with the USB Device

              #include <QCoreApplication>
              #include <QSerialPort>
              #include <QSerialPortInfo>
              #include <QDebug>
              
              int main(int argc, char *argv[])
              {
                  QCoreApplication a(argc, argv);
              
                  // Create a serial port object
                  QSerialPort serial;
              
                  // Configure the serial port
                  serial.setPortName("COM3"); // Replace with your device's port name
                  serial.setBaudRate(QSerialPort::Baud9600);
                  serial.setDataBits(QSerialPort::Data8);
                  serial.setParity(QSerialPort::NoParity);
                  serial.setStopBits(QSerialPort::OneStop);
                  serial.setFlowControl(QSerialPort::NoFlowControl);
              
                  // Open the serial port
                  if (serial.open(QIODevice::ReadWrite)) {
                      qDebug() << "Connected to" << serial.portName();
              
                      // Write data to the device
                      QByteArray data = "Hello, USB Device!";
                      serial.write(data);
                      qDebug() << "Data sent:" << data;
              
                      // Read data from the device
                      if (serial.waitForReadyRead(5000)) { // Wait for 5 seconds
                          QByteArray response = serial.readAll();
                          qDebug() << "Response:" << response;
                      } else {
                          qDebug() << "Timeout: No response from device.";
                      }
              
                      // Close the serial port
                      serial.close();
                  } else {
                      qDebug() << "Failed to open port" << serial.portName();
                  }
              
                  return a.exec();
              }
              

              If the code above does not work for you, try to find Windows API

              #include <windows.h>
              #include <setupapi.h>
              #include <iostream>
              #include <string>
              #include <vector>
              #include <iomanip>
              
              #pragma comment(lib, "setupapi.lib")
              
              // Function to convert a wide string to a std::string
              std::string WideStringToString(const std::wstring& wideStr) {
                  if (wideStr.empty()) return std::string();
                  int sizeNeeded = WideCharToMultiByte(CP_UTF8, 0, &wideStr[0], (int)wideStr.size(), nullptr, 0, nullptr, nullptr);
                  std::string str(sizeNeeded, 0);
                  WideCharToMultiByte(CP_UTF8, 0, &wideStr[0], (int)wideStr.size(), &str[0], sizeNeeded, nullptr, nullptr);
                  return str;
              }
              
              // Function to enumerate USB devices
              void EnumerateUSBDevices() {
                  HDEVINFO deviceInfoSet;
                  SP_DEVINFO_DATA deviceInfoData;
                  DWORD deviceIndex = 0;
              
                  // Initialize the device information set for USB devices
                  deviceInfoSet = SetupDiGetClassDevs(&GUID_DEVCLASS_USB, nullptr, nullptr, DIGCF_PRESENT | DIGCF_PROFILE);
                  if (deviceInfoSet == INVALID_HANDLE_VALUE) {
                      std::cerr << "Failed to get device information set." << std::endl;
                      return;
                  }
              
                  // Initialize the device information structure
                  deviceInfoData.cbSize = sizeof(SP_DEVINFO_DATA);
              
                  // Enumerate through all devices in the set
                  while (SetupDiEnumDeviceInfo(deviceInfoSet, deviceIndex++, &deviceInfoData)) {
                      // Get the device instance ID (contains VID and PID)
                      wchar_t deviceID[256];
                      if (SetupDiGetDeviceInstanceId(deviceInfoSet, &deviceInfoData, deviceID, sizeof(deviceID) / sizeof(deviceID[0]), nullptr)) {
                          std::wstring deviceIDStr(deviceID);
                          std::string deviceIDUtf8 = WideStringToString(deviceIDStr);
              
                          // Extract VID and PID from the device instance ID
                          size_t vidPos = deviceIDUtf8.find("VID_");
                          size_t pidPos = deviceIDUtf8.find("PID_");
                          if (vidPos != std::string::npos && pidPos != std::string::npos) {
                              std::string vid = deviceIDUtf8.substr(vidPos + 4, 4);
                              std::string pid = deviceIDUtf8.substr(pidPos + 4, 4);
              
                              std::cout << "Device ID: " << deviceIDUtf8 << std::endl;
                              std::cout << "VID: " << vid << ", PID: " << pid << std::endl;
                          }
                      }
              
                      // Get the device description
                      wchar_t deviceDescription[256];
                      if (SetupDiGetDeviceRegistryProperty(deviceInfoSet, &deviceInfoData, SPDRP_FRIENDLYNAME, nullptr, (PBYTE)deviceDescription, sizeof(deviceDescription), nullptr)) {
                          std::wstring descriptionStr(deviceDescription);
                          std::string descriptionUtf8 = WideStringToString(descriptionStr);
                          std::cout << "Description: " << descriptionUtf8 << std::endl;
                      }
              
                      std::cout << "-----------------------------------" << std::endl;
                  }
              
                  // Clean up
                  SetupDiDestroyDeviceInfoList(deviceInfoSet);
              }
              
              int main() {
                  EnumerateUSBDevices();
                  return 0;
              }
              
              A Offline
              A Offline
              Andrew23
              wrote on 18 Mar 2025, 08:58 last edited by
              #6

              @JoeCFD said in Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition:

              @Andrew23 Try to use Qt serial port to detect USB Devices

              Maybe I didn't explain my context well. What you suggested is to open a serial connection with QSerialPort, but my USB device is not a CDC-ACM class device that creates a virtual COM port. My goal is to communicate with my USB device through bulk transfer, reading/writing to its endpoints. I know that implementing a driver for this purpose is usually necessary, but I have discovered that it is possible to use the generic WinUSB driver with the libusb library. Am I wrong?

              1 Reply Last reply
              0

              3/6

              17 Mar 2025, 17:54

              • Login

              • Login or register to search.
              3 out of 6
              • First post
                3/6
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved