Results 1 to 10 of 10

Thread: QtSerialPort - SerialPortInfo returns 0 ports available

  1. #1
    Join Date
    Apr 2013
    Location
    N/A
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default QtSerialPort - SerialPortInfo returns 0 ports available

    I have Qt 5.0.1 on Windows 7 64-bit and I have downloaded and installed QtSerialPort following instructions on Wiki. I use MS VC++ Express 2010 compiler.

    With simple example code from cenumerator I get 0 ports available. However, in Control Panel and using terminal program I can connect to my serial device.
    I also did a quick Python script and it works from there using PySerial.

    Any thoughts how to fix this?

    Qt Code:
    1. QList<QSerialPortInfo> serialPortInfoList = QSerialPortInfo::availablePorts();
    2. QTextStream out(stdout);
    3.  
    4. out << QObject::tr("Total number of ports available: ") << serialPortInfoList.count() << endl;
    5.  
    6. foreach (const QSerialPortInfo &serialPortInfo, serialPortInfoList) {
    7. out << endl
    8. << QObject::tr("Port: ") << serialPortInfo.portName() << endl
    9. << QObject::tr("Location: ") << serialPortInfo.systemLocation() << endl
    10. << QObject::tr("Description: ") << serialPortInfo.description() << endl
    11. << QObject::tr("Manufacturer: ") << serialPortInfo.manufacturer() << endl
    12. << QObject::tr("Vendor Identifier: ") << (serialPortInfo.hasVendorIdentifier() ? QByteArray::number(serialPortInfo.vendorIdentifier(), 16) : QByteArray()) << endl
    13. << QObject::tr("Product Identifier: ") << (serialPortInfo.hasProductIdentifier() ? QByteArray::number(serialPortInfo.productIdentifier(), 16) : QByteArray()) << endl
    14. << QObject::tr("Busy: ") << (serialPortInfo.isBusy() ? QObject::tr("Yes") : QObject::tr("No")) << endl;
    15. }
    To copy to clipboard, switch view to plain text mode 


    Qt Code:
    1. QT += core gui sql serialport
    To copy to clipboard, switch view to plain text mode 

    Output:

    Total number of ports available: 0

  2. #2
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    This may be an issue with Windows Setup API not showing the errant device.

    What happens if you just try to open COMx?

  3. #3
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    2 slanina,

    Possibly it is regression which belongs to a recent patch which had to optimize enumeration: https://codereview.qt-project.org/#change,53725

    Also already created issue about this bug: https://bugreports.qt-project.org/br...TPLAYGROUND-27

    May you give detailed information on the used device (VID/PID/Class GUID and etc), and also give *.inf driver files?


    UPD:
    At present the solution isn't known. Temporarily you can use workaround - simply to roll away change to this patch for QSerialPortInfo.

    PS:
    Win32 API again and again throws to us "surprises".
    The behavior of Setup API doesn't give in to logic, or I don't understand something...

  4. #4
    Join Date
    Apr 2013
    Location
    N/A
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    Quote Originally Posted by kuzulis View Post
    2 slanina,

    Possibly it is regression which belongs to a recent patch which had to optimize enumeration: https://codereview.qt-project.org/#change,53725

    Also already created issue about this bug: https://bugreports.qt-project.org/br...TPLAYGROUND-27

    May you give detailed information on the used device (VID/PID/Class GUID and etc), and also give *.inf driver files?


    UPD:
    At present the solution isn't known. Temporarily you can use workaround - simply to roll away change to this patch for QSerialPortInfo.

    PS:
    Win32 API again and again throws to us "surprises".
    The behavior of Setup API doesn't give in to logic, or I don't understand something...
    It is a custom device I am developing from one sample given by NXP for their LPC series of microcontrollers (LPC11U35). It is based on the code that works fine on the device side as given by NXP. Actually based on that code I did a device and one code in October 2012 but then I have used QtExtSerialPort and it enumerated fine.
    Enumeration would be beneficial to me, since I could then detect and parse manufacturer name and device name (basically me) and make sure the user does not need to select a COM port - so I could have an "auto connect" upon application loading.

    Any hints how to rollback the patch? I have never done this on Windows.

    Upload of .inf file seems to fail so I am copying it below. It uses NXP VID/PID since it is their example...

    Qt Code:
    1. ;************************************************************
    2. ; Windows USB CDC ACM Setup File
    3. ; Copyright (c) 2000 Microsoft Corporation
    4.  
    5.  
    6. [Version]
    7. Signature="$Windows NT$"
    8. Class=Ports
    9. ClassGuid={4D36E978-E325-11CE-BFC1-08002BE10318}
    10. Provider=%MFGNAME%
    11. LayoutFile=layout.inf
    12. CatalogFile=%MFGFILENAME%.cat
    13. DriverVer=11/15/2007,5.1.2600.0
    14.  
    15. [Manufacturer]
    16. %MFGNAME%=DeviceList, NTamd64
    17.  
    18. [DestinationDirs]
    19. DefaultDestDir=12
    20.  
    21.  
    22. ;------------------------------------------------------------------------------
    23. ; Windows 2000/XP/Vista-32bit Sections
    24. ;------------------------------------------------------------------------------
    25.  
    26. [DriverInstall.nt]
    27. include=mdmcpq.inf
    28. CopyFiles=DriverCopyFiles.nt
    29. AddReg=DriverInstall.nt.AddReg
    30.  
    31. [DriverCopyFiles.nt]
    32. usbser.sys,,,0x20
    33.  
    34. [DriverInstall.nt.AddReg]
    35. HKR,,DevLoader,,*ntkern
    36. HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
    37. HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
    38.  
    39. [DriverInstall.nt.Services]
    40. AddService=usbser, 0x00000002, DriverService.nt
    41.  
    42. [DriverService.nt]
    43. DisplayName=%SERVICE%
    44. ServiceType=1
    45. StartType=3
    46. ErrorControl=1
    47. ServiceBinary=%12%\%DRIVERFILENAME%.sys
    48.  
    49. ;------------------------------------------------------------------------------
    50. ; Vista-64bit Sections
    51. ;------------------------------------------------------------------------------
    52.  
    53. [DriverInstall.NTamd64]
    54. include=mdmcpq.inf
    55. CopyFiles=DriverCopyFiles.NTamd64
    56. AddReg=DriverInstall.NTamd64.AddReg
    57.  
    58. [DriverCopyFiles.NTamd64]
    59. %DRIVERFILENAME%.sys,,,0x20
    60.  
    61. [DriverInstall.NTamd64.AddReg]
    62. HKR,,DevLoader,,*ntkern
    63. HKR,,NTMPDriver,,%DRIVERFILENAME%.sys
    64. HKR,,EnumPropPages32,,"MsPorts.dll,SerialPortPropPageProvider"
    65.  
    66. [DriverInstall.NTamd64.Services]
    67. AddService=usbser, 0x00000002, DriverService.NTamd64
    68.  
    69. [DriverService.NTamd64]
    70. DisplayName=%SERVICE%
    71. ServiceType=1
    72. StartType=3
    73. ErrorControl=1
    74. ServiceBinary=%12%\%DRIVERFILENAME%.sys
    75.  
    76.  
    77. ;------------------------------------------------------------------------------
    78. ; Vendor and Product ID Definitions
    79. ;------------------------------------------------------------------------------
    80. ; When developing your USB device, the VID and PID used in the PC side
    81. ; application program and the firmware on the microcontroller must match.
    82. ; Modify the below line to use your VID and PID. Use the format as shown below.
    83. ; Note: One INF file can be used for multiple devices with different VID and PIDs.
    84. ; For each supported device, append ",USB\VID_xxxx&PID_yyyy" to the end of the line.
    85. ;------------------------------------------------------------------------------
    86. [SourceDisksFiles]
    87. [SourceDisksNames]
    88. [DeviceList]
    89. %DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_2047
    90.  
    91. [DeviceList.NTamd64]
    92. %DESCRIPTION%=DriverInstall, USB\VID_1FC9&PID_2047
    93.  
    94.  
    95. ;------------------------------------------------------------------------------
    96. ; String Definitions
    97. ;------------------------------------------------------------------------------
    98. ;Modify these strings to customize your device
    99. ;------------------------------------------------------------------------------
    100. [Strings]
    101. MFGFILENAME="CDC_vista"
    102. DRIVERFILENAME ="usbser"
    103. MFGNAME="http://www.lpcware.com/content/project/LPCUSBlib"
    104. INSTDISK="LPCUSBlib CDC Driver Installer"
    105. DESCRIPTION="Communications Port"
    106. SERVICE="USB RS-232 Emulation Driver"
    To copy to clipboard, switch view to plain text mode 

  5. #5
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    It is clear. It seems that this problem is observed with USB CDC ACM devices.

    Please try new patch: https://bugreports.qt-project.org/br...TPLAYGROUND-27

    And please let me know about results.
    Last edited by kuzulis; 26th April 2013 at 15:27.

  6. #6
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    Guys, seems that I'm found some solution. Please waiting...


    Added after 1 37 minutes:


    The patch is updated: https://codereview.qt-project.org/#change,54832

    Please check its functionality, HowTo do it see: https://bugreports.qt-project.org/br...TPLAYGROUND-27
    Last edited by kuzulis; 27th April 2013 at 12:48.

  7. #7
    Join Date
    Apr 2013
    Location
    N/A
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    I have applied the patch and now I can enumerate my device. I can connect and read/write data to it.

    BUT

    My device receives *any single character* and sends the following output:

    DAT:9224,45080,8,36,0,24,176,0\n\r


    It seems after some time I get constant reading problems. Below is my code of the QThread run() method:

    Qt Code:
    1. void DataFeeder::run()
    2. {
    3. qDebug() << "DataFeeder - Started.";
    4.  
    5. done = false;
    6. bool retval = true;
    7.  
    8. QSerialPort serial;
    9. serial.setPortName(comPort);
    10.  
    11. qDebug() << "Trying to open " << comPort;
    12. if (!serial.open(QIODevice::ReadWrite)) {
    13. qDebug() << QString("Can't open %1, error code %2").arg(comPort).arg(serial.error());
    14. retval = false;
    15. }
    16.  
    17. if (!serial.setBaudRate(QSerialPort::Baud9600)) {
    18. qDebug() << QString("Can't set baud rate 9600 baud to port %1, error code %2").arg(comPort).arg(serial.error());
    19. retval = false;
    20. }
    21.  
    22. if (!serial.setDataBits(QSerialPort::Data8)) {
    23. qDebug() << QString("Can't set 8 data bits to port %1, error code %2").arg(comPort).arg(serial.error());
    24. retval = false;
    25. }
    26.  
    27. if (!serial.setParity(QSerialPort::NoParity)) {
    28. qDebug() << QString("Can't set no patity to port %1, error code %2").arg(comPort).arg(serial.error());
    29. retval = false;
    30. }
    31.  
    32. if (!serial.setStopBits(QSerialPort::OneStop)) {
    33. qDebug() << QString("Can't set 1 stop bit to port %1, error code %2").arg(comPort).arg(serial.error());
    34. retval = false;
    35. }
    36.  
    37. if (!serial.setFlowControl(QSerialPort::NoFlowControl)) {
    38. qDebug() << QString("Can't set no flow control to port %1, error code %2").arg(comPort).arg(serial.error());
    39. retval = false;
    40. }
    41.  
    42.  
    43. qDebug() << comPort << " opened.";
    44.  
    45. mutex->lock();
    46.  
    47. if(retval)
    48. {
    49. do
    50. {
    51.  
    52. QByteArray requestData = QString("d").toLocal8Bit();
    53. serial.write(requestData);
    54. if(serial.waitForBytesWritten(5000))
    55. {
    56. if(serial.waitForReadyRead(2000))
    57. {
    58. QByteArray responseData = serial.readAll();
    59. QString data;
    60. data = data.fromLatin1(responseData).trimmed();
    61. qDebug() << "Got:$" << data << "$";
    62.  
    63. }
    64. else
    65. {
    66. emit feederError("Data not correct - list size.");
    67. }
    68. }
    69. else
    70. {
    71. emit feederError("WaitForReadyRead failed.");
    72. }
    73. }
    74. else
    75. {
    76. emit feederError("WaitForBytesWritten failed.");
    77. }
    78.  
    79. } while( !waitCondition->wait(mutex, sleepTime) && !done);
    80.  
    81. }
    82.  
    83. mutex->unlock();
    84.  
    85. qDebug() << "DataFeeder - Ended.";
    86.  
    87. if(serial.isOpen())
    88. {
    89. serial.close();
    90. }
    91.  
    92. }
    To copy to clipboard, switch view to plain text mode 

    Output is:

    Trying to open "COM6"
    "COM6" opened.
    Got:$ "" $
    Got:$ "DAT:10760,43288,8,42,0,24,169,0" $
    .
    .
    .
    "WaitForReadyRead failed."
    "WaitForReadyRead failed."
    "WaitForReadyRead failed."
    .
    .
    .


    So first thing is that first write to the device always fails and I get back empty string.
    And then after some time (approx after 10-15 writes of a single charachter and reads of data shown) I get that else {} block with timeout for read.

    I have tried using terminal program and I wrote many charachters and got back data all the time with no blockage and failure.

    Also I have noticed that readLine() fails and I get timeout so I use readAll() as in the blockingmaster example. However, from the device side I do send \r\n characters at the end.

    Also if I keep waitForBytesWritten timeout at 1000 msec, then I get write timeouts even though I am sending only 1 charachter at 9600 bps. Read timeout of 2000msec should be enough for reading this small dataset.

  8. #8
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    That I can advise in this situation:

    1. Add a method of obtaining the error code after unsuccessful waitForReadyRead() and output the error code to the console.
    2. Make the same project only with use of asynchronous approach (without waitForXXX() methods), see Master example. Because implementation of the synchronous approach isn't up to the end designed and it isn't recommended.

  9. #9
    Join Date
    Apr 2013
    Location
    N/A
    Posts
    14
    Thanked 1 Time in 1 Post
    Qt products
    Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    Quote Originally Posted by kuzulis View Post
    That I can advise in this situation:

    1. Add a method of obtaining the error code after unsuccessful waitForReadyRead() and output the error code to the console.
    2. Make the same project only with use of asynchronous approach (without waitForXXX() methods), see Master example. Because implementation of the synchronous approach isn't up to the end designed and it isn't recommended.
    I have made a new code based on the Master example. And I am experiencing the same problem....after some time it starts to get errors. Below is error message which I have printed out:


    Timeout waiting to read serial port "COM3"
    Error code: 9 String: "Unknown error"


    Qt Code:
    1. DataFeeder2::DataFeeder2(QString useComPort, QObject *parent, int nSleepTime) :
    2. QObject(parent), sleepTime(nSleepTime), comPort(useComPort), waitingForReply(false)
    3. {
    4.  
    5.  
    6. serial.setPortName(comPort);
    7. timer.setInterval(sleepTime);
    8. errorTimer.setSingleShot(true);
    9.  
    10. connect(&serial, SIGNAL(readyRead()),
    11. this, SLOT(readResponse()));
    12. connect(&timer, SIGNAL(timeout()),
    13. this, SLOT(acquireData()));
    14. connect(&errorTimer, SIGNAL(timeout()),
    15. this, SLOT(processTimeout()));
    16. }
    17.  
    18. DataFeeder2::~DataFeeder2()
    19. {
    20. if(serial.isOpen())
    21. {
    22. serial.close();
    23. }
    24. }
    25.  
    26. bool DataFeeder2::start()
    27. {
    28. bool retval = true;
    29.  
    30. serial.setPortName(comPort);
    31.  
    32. qDebug() << "Trying to open " << comPort;
    33. if (!serial.open(QIODevice::ReadWrite)) {
    34. qDebug() << QString("Can't open %1, error code %2").arg(comPort).arg(serial.error());
    35. retval = false;
    36. }
    37.  
    38. if (!serial.setBaudRate(QSerialPort::Baud9600)) {
    39. qDebug() << QString("Can't set baud rate 9600 baud to port %1, error code %2").arg(comPort).arg(serial.error());
    40. retval = false;
    41. }
    42.  
    43. if (!serial.setDataBits(QSerialPort::Data8)) {
    44. qDebug() << QString("Can't set 8 data bits to port %1, error code %2").arg(comPort).arg(serial.error());
    45. retval = false;
    46. }
    47.  
    48. if (!serial.setParity(QSerialPort::NoParity)) {
    49. qDebug() << QString("Can't set no patity to port %1, error code %2").arg(comPort).arg(serial.error());
    50. retval = false;
    51. }
    52.  
    53. if (!serial.setStopBits(QSerialPort::OneStop)) {
    54. qDebug() << QString("Can't set 1 stop bit to port %1, error code %2").arg(comPort).arg(serial.error());
    55. retval = false;
    56. }
    57.  
    58. if (!serial.setFlowControl(QSerialPort::NoFlowControl)) {
    59. qDebug() << QString("Can't set no flow control to port %1, error code %2").arg(comPort).arg(serial.error());
    60. retval = false;
    61. }
    62.  
    63.  
    64. qDebug() << comPort << " opened.";
    65.  
    66. waitingForReply = false;
    67.  
    68. timer.start();
    69.  
    70.  
    71. return retval;
    72.  
    73. }
    74.  
    75. void DataFeeder2::stop()
    76. {
    77. timer.stop();
    78. errorTimer.stop();
    79. serial.close();
    80.  
    81. qDebug() << "DataFeeder2 stopped.";
    82. }
    83.  
    84. void DataFeeder2::setSleepTime(int nSleepTime)
    85. {
    86. if(sleepTime != nSleepTime)
    87. {
    88. sleepTime = nSleepTime;
    89. timer.setInterval(sleepTime);
    90. emit sleepTimeChanged(sleepTime);
    91. }
    92. }
    93.  
    94. void DataFeeder2::processTimeout()
    95. {
    96. qDebug() << "Timeout waiting to read serial port " << comPort;
    97. qDebug() << "Error code: " << serial.error() << " String: " << serial.errorString();
    98. }
    99.  
    100. void DataFeeder2::acquireData()
    101. {
    102. if(!waitingForReply)
    103. {
    104. serial.write(QString("d").toLocal8Bit());
    105. errorTimer.start(2000);
    106. waitingForReply = true;
    107. }
    108. }
    109.  
    110. void DataFeeder2::readResponse()
    111. {
    112. errorTimer.stop();
    113.  
    114. //QByteArray responseData = serial.readAll();
    115. QByteArray responseData = serial.readLine();
    116. qDebug() << "Got:$" << data << "$";
    117.  
    118. waitingForReply = false;
    119.  
    120. }
    To copy to clipboard, switch view to plain text mode 

    In readResponse() I have tried readAll() to read everything and readLine() which I would prefer since it is blocking and my client terminates the string with \n\r. In any case behaviour is the same - works fine and then after 1-2 minutes it stops.

    When from GUI I call stop() method on my object and then start() again, it again successfully opens COM3, connects and starts reading data. Then again after some time (1-2 minutes) it stops.
    Last edited by slanina; 1st May 2013 at 08:06.

  10. #10
    Join Date
    Jan 2009
    Location
    Russia
    Posts
    309
    Thanks
    2
    Thanked 43 Times in 42 Posts
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: QtSerialPort - SerialPortInfo returns 0 ports available

    For this question you needed to make a separate thread.

    Concerning realization:

    Not necessarily that readAll() (and furthermore readLine()) will return full string. At first it is necessary for you it will be convinced that in the buffer really there is a full answer.

    For your case you have to check canReadLine() (or bytesAvailable()). If it returns false, it means that full string yet isn't in the buffer and you have to wait the rest data at the following readyRead().

    The signal readyRead() is emits at reception at least one symbol. Therefore readAll () has to return at least one symbol.

    So, you need wait until full string is not received and then read it.

Similar Threads

  1. Adding QtSerialPort as a library -
    By HSPalm in forum Newbie
    Replies: 14
    Last Post: 26th June 2014, 17:16
  2. Help to generate QtSerialPort documentation
    By cstr in forum Installation and Deployment
    Replies: 2
    Last Post: 10th April 2013, 20:04
  3. Replies: 18
    Last Post: 3rd December 2012, 18:05
  4. QtSerialPort synchronous approach
    By codein in forum Newbie
    Replies: 2
    Last Post: 4th September 2012, 10:45
  5. cannot build qtserialport
    By banlinhtienphong in forum Qt Programming
    Replies: 1
    Last Post: 16th December 2011, 06:56

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.