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
QtWS25 Last Chance

Troubleshooting USB Communication with Qt and libusb for Embedded Device Recognition

Scheduled Pinned Locked Moved Unsolved General and Desktop
6 Posts 3 Posters 184 Views
  • 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

              5/6

              17 Mar 2025, 19:09

              • Login

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