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. QSerialPort::availablePorts reports portName available after unplugging
Forum Update on Monday, May 27th 2025

QSerialPort::availablePorts reports portName available after unplugging

Scheduled Pinned Locked Moved Solved General and Desktop
14 Posts 4 Posters 1.3k 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.
  • J Offline
    J Offline
    Jeff Barnes
    wrote on last edited by
    #1

    Re: [QSerialPort issues - error signals](plugging/unplugging quickly)

    J 1 Reply Last reply
    0
    • J Jeff Barnes

      You are probably right.

      If I put a sleep(1) after availablePorts(), I get accurate info and can even reconnect.

      J Offline
      J Offline
      Jeff Barnes
      wrote on last edited by Jeff Barnes
      #14

      @Jeff-Barnes

      #include "jtagclient.h"
      
      #include <unistd.h>
      #include <QSerialPortInfo>
      #include <QTimer>
      
      QString JtagClient::m_usbDevice = "ttyUSB0";
      
      JtagClient::JtagClient(QObject *parent)
         :   QObject(parent)
      {
         m_serialPort = new QSerialPort(m_usbDevice);
      }
      
      void JtagClient::run()
      {
         if (!m_serialPort->open(QIODevice::ReadWrite))
         {
             emit usbDeviceStatus("Could not open serial port");
             return;
         }
         QTimer *tm = new QTimer;
         QTimer *retmr = new QTimer;
         tm->setInterval(500);
         tm->setSingleShot(false);
         retmr->setInterval(500);
         retmr->setSingleShot(false);
         QObject::connect(this, &JtagClient::stopDisconnectTimer, tm, &QTimer::stop);
         QObject::connect(this, &JtagClient::stopReconnectTimer, retmr, &QTimer::stop);
         QObject::connect(this, SIGNAL(startReconnectTimer()), retmr, SLOT(start()));
         QObject::connect(this, &JtagClient::finished, tm, &QTimer::deleteLater);
         QObject::connect(this, &JtagClient::finished, retmr, &QTimer::deleteLater);
         QObject::connect(tm, &QTimer::timeout, [&]() {
             bool found = false;
             foreach (QSerialPortInfo inf, QSerialPortInfo::availablePorts())
             {
                 if (m_usbDevice == inf.portName())
                 {
                     emit usbDeviceStatus("Waiting for usb serial disconnect");
                     found = true;
                     break;
                 }
             }
             if (!found)
             {
                 m_serialPort->close();
                 m_serialPort->deleteLater();
                 emit usbDeviceStatus("Cable removed");
                 emit stopDisconnectTimer();
                 emit startReconnectTimer();
             }
         });
         QObject::connect(retmr, &QTimer::timeout, [&]() {
             bool found = false;
             foreach (QSerialPortInfo inf, QSerialPortInfo::availablePorts())
             {
                 if (m_usbDevice == inf.portName())
                 {
                     found = true;
                     //500000 causes a Permission denied error, presumably the kernel hasn't finished the inode
                     //750000 causes a Permission denied error for ReadWrite, but works for ReadOnly
                     //usleep(750000);
                     sleep(1);
                     m_serialPort = new QSerialPort(m_usbDevice);
                     if (!m_serialPort->open(QIODevice::ReadWrite))
                     {
                         emit usbDeviceStatus(QString("Could not re-open device: %1").arg(m_serialPort->errorString()));
                     }
                     else
                     {
                         emit usbDeviceStatus("Connection re-established");
                     }
                     break;
                 }
             }
             if (found)
             {
                 emit stopReconnectTimer();
                 emit finished();
             }
             else
                 emit usbDeviceStatus("Waiting for re-connect");
         });
         tm->start();
      }
      
      
      1 Reply Last reply
      0
      • J Jeff Barnes

        Re: [QSerialPort issues - error signals](plugging/unplugging quickly)

        J Offline
        J Offline
        Jeff Barnes
        wrote on last edited by
        #2

        @Jeff-Barnes

        Given the following code, the if (!found) block is never executed after a serial port was open, then unplugged. I need to either unplug (or preferably power down) the serial device.

        QTimer *tm = new QTimer;
        tm->setInterval(250);
        tm->setSingleShot(false);
        QObject::connect(tm, &QTimer::timeout, [&]() {
            bool found = false;
            foreach (QSerialPortInfo inf, QSerialPortInfo::availablePorts())
            {
                if (m_usbDevice == inf.portName())
                {
                    if (tmct++ %4 == 0)
                    {
                        //I see this message even after unplugging the device.
                        emit usbDeviceStatus("Waiting for device power down");
                    }
                    found = true;
                    break;
                }
            }
            if (!found)
            {
                qDebug() << "serial port closed"; //never see it
                m_serialPort->deleteLater();
                qDebug() << "deleting serial port";
                //device powered off
                emit usbDeviceStatus("Device powered down");
                tm->stop();
                tm->deleteLater();
                retmr->start();
                qDebug() << "started retmr";
            }
        });
        
        aha_1980A 1 Reply Last reply
        0
        • J Jeff Barnes

          @Jeff-Barnes

          Given the following code, the if (!found) block is never executed after a serial port was open, then unplugged. I need to either unplug (or preferably power down) the serial device.

          QTimer *tm = new QTimer;
          tm->setInterval(250);
          tm->setSingleShot(false);
          QObject::connect(tm, &QTimer::timeout, [&]() {
              bool found = false;
              foreach (QSerialPortInfo inf, QSerialPortInfo::availablePorts())
              {
                  if (m_usbDevice == inf.portName())
                  {
                      if (tmct++ %4 == 0)
                      {
                          //I see this message even after unplugging the device.
                          emit usbDeviceStatus("Waiting for device power down");
                      }
                      found = true;
                      break;
                  }
              }
              if (!found)
              {
                  qDebug() << "serial port closed"; //never see it
                  m_serialPort->deleteLater();
                  qDebug() << "deleting serial port";
                  //device powered off
                  emit usbDeviceStatus("Device powered down");
                  tm->stop();
                  tm->deleteLater();
                  retmr->start();
                  qDebug() << "started retmr";
              }
          });
          
          aha_1980A Offline
          aha_1980A Offline
          aha_1980
          Lifetime Qt Champion
          wrote on last edited by
          #3

          Hi @Jeff-Barnes,

          • which platform is that?
          • and which Qt version?

          Qt has to stay free or it will die.

          J 1 Reply Last reply
          1
          • aha_1980A aha_1980

            Hi @Jeff-Barnes,

            • which platform is that?
            • and which Qt version?
            J Offline
            J Offline
            Jeff Barnes
            wrote on last edited by
            #4

            @aha_1980 Platform Ubuntu 16.04 Qt 5.11

            mrjjM 1 Reply Last reply
            0
            • J Jeff Barnes

              @aha_1980 Platform Ubuntu 16.04 Qt 5.11

              mrjjM Offline
              mrjjM Offline
              mrjj
              Lifetime Qt Champion
              wrote on last edited by
              #5

              @Jeff-Barnes
              Hi
              Have you checked that ubuntu does in fact remove
              the dev name when you unplug the sub->serial device ?

              1 Reply Last reply
              0
              • J Offline
                J Offline
                Jeff Barnes
                wrote on last edited by
                #6

                Before unplugging serial cable:

                ls /dev/ttyUSB0
                /dev/ttyUSB0

                After:
                ls /dev/ttyUSB0
                ls: cannot access '/dev/ttyUSB0': No such file or directory

                J 1 Reply Last reply
                0
                • J Jeff Barnes

                  Before unplugging serial cable:

                  ls /dev/ttyUSB0
                  /dev/ttyUSB0

                  After:
                  ls /dev/ttyUSB0
                  ls: cannot access '/dev/ttyUSB0': No such file or directory

                  J Offline
                  J Offline
                  Jeff Barnes
                  wrote on last edited by Jeff Barnes
                  #7

                  @Jeff-Barnes IMO, this is a bug in QSerialPort/QSerialPortInfo implementation, because the serial port is de-registered with the computer when the serial cable is unplugged, yet QSerialPortInfo::availablePorts() still lists it.

                  However, in my particular use case, I worked around it by leaving the QSerialPort open, the serial cable plugged in and power cycling the board. The USB is providing power to the serial port, so it is still active.

                  aha_1980A 1 Reply Last reply
                  0
                  • J Jeff Barnes

                    @Jeff-Barnes IMO, this is a bug in QSerialPort/QSerialPortInfo implementation, because the serial port is de-registered with the computer when the serial cable is unplugged, yet QSerialPortInfo::availablePorts() still lists it.

                    However, in my particular use case, I worked around it by leaving the QSerialPort open, the serial cable plugged in and power cycling the board. The USB is providing power to the serial port, so it is still active.

                    aha_1980A Offline
                    aha_1980A Offline
                    aha_1980
                    Lifetime Qt Champion
                    wrote on last edited by
                    #8

                    Hi @Jeff-Barnes, it could be a bug indeed.

                    Which type of USB adapter is this? Can you post the dmesg lines after plugging the adapter in and out? @kuzulis, any more information for investigation needed?

                    Qt has to stay free or it will die.

                    1 Reply Last reply
                    1
                    • J Offline
                      J Offline
                      Jeff Barnes
                      wrote on last edited by
                      #9

                      jbarnes@jbarnes-All-Series:~/rail/desktop-tools$ sudo dmesg -C
                      jbarnes@jbarnes-All-Series:~/rail/desktop-tools$ dmesg
                      [1370519.563632] usb 3-4: USB disconnect, device number 78
                      [1370519.563719] ftdi_sio ttyUSB0: FTDI USB Serial Device converter now disconnected from ttyUSB0
                      [1370519.563731] ftdi_sio 3-4:1.0: device disconnected
                      [1370527.159840] usb 3-4: new full-speed USB device number 81 using xhci_hcd
                      [1370527.293315] usb 3-4: New USB device found, idVendor=0403, idProduct=6001
                      [1370527.293317] usb 3-4: New USB device strings: Mfr=1, Product=2, SerialNumber=3
                      [1370527.293318] usb 3-4: Product: FT232R USB UART
                      [1370527.293319] usb 3-4: Manufacturer: FTDI
                      [1370527.293321] usb 3-4: SerialNumber: A50285BI
                      [1370527.295768] ftdi_sio 3-4:1.0: FTDI USB Serial Device converter detected
                      [1370527.295805] usb 3-4: Detected FT232RL
                      [1370527.295939] usb 3-4: FTDI USB Serial Device converter now attached to ttyUSB0

                      1 Reply Last reply
                      0
                      • K Offline
                        K Offline
                        kuzulis
                        Qt Champions 2020
                        wrote on last edited by kuzulis
                        #10

                        QSerialPortInfo takes info from the udev... Usually if you keep a serial port open, and then unplug an USB cable, then it can show that a device still is present in system.

                        From your code it is unclear what do you do. You should try to check it in two variants:

                        1. Try to keep QSerialPort as open.
                        2. Try do not touch the QSeralPort at all.

                        PS: It is not a QSPI issue, most likelly, you should address it to systemd bug-tracker or the kernel dev-list.

                        1 Reply Last reply
                        2
                        • J Offline
                          J Offline
                          Jeff Barnes
                          wrote on last edited by
                          #11

                          You are probably right.

                          If I put a sleep(1) after availablePorts(), I get accurate info and can even reconnect.

                          J 2 Replies Last reply
                          0
                          • J Offline
                            J Offline
                            Jeff Barnes
                            wrote on last edited by
                            #12
                            This post is deleted!
                            1 Reply Last reply
                            1
                            • J Jeff Barnes

                              You are probably right.

                              If I put a sleep(1) after availablePorts(), I get accurate info and can even reconnect.

                              J Offline
                              J Offline
                              Jeff Barnes
                              wrote on last edited by Jeff Barnes
                              #13
                              This post is deleted!
                              1 Reply Last reply
                              0
                              • J Jeff Barnes

                                You are probably right.

                                If I put a sleep(1) after availablePorts(), I get accurate info and can even reconnect.

                                J Offline
                                J Offline
                                Jeff Barnes
                                wrote on last edited by Jeff Barnes
                                #14

                                @Jeff-Barnes

                                #include "jtagclient.h"
                                
                                #include <unistd.h>
                                #include <QSerialPortInfo>
                                #include <QTimer>
                                
                                QString JtagClient::m_usbDevice = "ttyUSB0";
                                
                                JtagClient::JtagClient(QObject *parent)
                                   :   QObject(parent)
                                {
                                   m_serialPort = new QSerialPort(m_usbDevice);
                                }
                                
                                void JtagClient::run()
                                {
                                   if (!m_serialPort->open(QIODevice::ReadWrite))
                                   {
                                       emit usbDeviceStatus("Could not open serial port");
                                       return;
                                   }
                                   QTimer *tm = new QTimer;
                                   QTimer *retmr = new QTimer;
                                   tm->setInterval(500);
                                   tm->setSingleShot(false);
                                   retmr->setInterval(500);
                                   retmr->setSingleShot(false);
                                   QObject::connect(this, &JtagClient::stopDisconnectTimer, tm, &QTimer::stop);
                                   QObject::connect(this, &JtagClient::stopReconnectTimer, retmr, &QTimer::stop);
                                   QObject::connect(this, SIGNAL(startReconnectTimer()), retmr, SLOT(start()));
                                   QObject::connect(this, &JtagClient::finished, tm, &QTimer::deleteLater);
                                   QObject::connect(this, &JtagClient::finished, retmr, &QTimer::deleteLater);
                                   QObject::connect(tm, &QTimer::timeout, [&]() {
                                       bool found = false;
                                       foreach (QSerialPortInfo inf, QSerialPortInfo::availablePorts())
                                       {
                                           if (m_usbDevice == inf.portName())
                                           {
                                               emit usbDeviceStatus("Waiting for usb serial disconnect");
                                               found = true;
                                               break;
                                           }
                                       }
                                       if (!found)
                                       {
                                           m_serialPort->close();
                                           m_serialPort->deleteLater();
                                           emit usbDeviceStatus("Cable removed");
                                           emit stopDisconnectTimer();
                                           emit startReconnectTimer();
                                       }
                                   });
                                   QObject::connect(retmr, &QTimer::timeout, [&]() {
                                       bool found = false;
                                       foreach (QSerialPortInfo inf, QSerialPortInfo::availablePorts())
                                       {
                                           if (m_usbDevice == inf.portName())
                                           {
                                               found = true;
                                               //500000 causes a Permission denied error, presumably the kernel hasn't finished the inode
                                               //750000 causes a Permission denied error for ReadWrite, but works for ReadOnly
                                               //usleep(750000);
                                               sleep(1);
                                               m_serialPort = new QSerialPort(m_usbDevice);
                                               if (!m_serialPort->open(QIODevice::ReadWrite))
                                               {
                                                   emit usbDeviceStatus(QString("Could not re-open device: %1").arg(m_serialPort->errorString()));
                                               }
                                               else
                                               {
                                                   emit usbDeviceStatus("Connection re-established");
                                               }
                                               break;
                                           }
                                       }
                                       if (found)
                                       {
                                           emit stopReconnectTimer();
                                           emit finished();
                                       }
                                       else
                                           emit usbDeviceStatus("Waiting for re-connect");
                                   });
                                   tm->start();
                                }
                                
                                
                                1 Reply Last reply
                                0

                                • Login

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