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, randomly missing bytes

QSerialPort, randomly missing bytes

Scheduled Pinned Locked Moved Unsolved General and Desktop
10 Posts 9 Posters 231 Views 3 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.
  • M Offline
    M Offline
    monegator
    wrote last edited by
    #1

    Hello, i'm a bit at a loss.
    Recently I've been having some problems with our software.
    We use it to communicate with our hardware using USB-TTL cables using a WCH chip. The driver is the last version available, either installed automatically by windows or manually.
    The affected PCs are running Windows 10 and 11.

    The problem is, sometimes, at random, communication fails because of a missing byte: apparently the PC doesn't get the last byte from the packet. For years i've been using a library i wrote that used the synchronous approach. (roughly write -> wait for written. read -> wait for data until a timeout. The hardware device is always silent and only responds to command coming from the PC. The process living in another thread so it didn't matter to the GUI if it was blocking)

    I also wrote a new version that is almost completely asynchronous (synchronous write -> wait for bytes written. Then, clear the RX Buffer. Then, slot from data ready signal reads all the data an places it in a QByteArray, a QFuture runner periodically checks for data in the QByteArray and if i'm expecting a response places it in the response buffer)

    Works flawlessly on hundreds of PCs around the globe, except these few ones.
    They are all from different makes, less and more powerful CPUs, the only thing they have in common is that they all are from eastern europe countries. I tried spinning up VMs with those locales, thinking it could make a difference, but i could never make the device fail.

    If we get sent back the cables and the hardware, they all work on our machines.

    I don't really know what to look at, some software is built with 6.8.3, other with 6.10.2. MinGW, i haven't tried building with MSVC

    There is probably some edge case i'm not thinking about but i really don't know what to look at.

    1 Reply Last reply
    1
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote last edited by
      #2

      Hi,

      That's fairly intriguing...
      Did you also compare the motherboards ?
      What USB chip they have ?
      Might be silly but could one of these machines be sent to you ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • hskoglundH Online
        hskoglundH Online
        hskoglund
        wrote last edited by
        #3

        To add to @SGaist, you could try setting up a real PC (not a VM) to eastern europe locale and time, since you're dealing with (perhaps) some hardware dependency. Running your app inside a VM that hardware gets emulated, i.e. not showing the exact same characteristics.

        1 Reply Last reply
        0
        • Axel SpoerlA Offline
          Axel SpoerlA Offline
          Axel Spoerl
          Moderators
          wrote last edited by
          #4

          Checking some basics:

          • readyRead() fires as soon as something can be read, not everything.
          • does QSerialPort live in one thread? Accessing it from multiple threads can be problematic and lead to unpredictable behaviour, actually pretty much the symptoms described.

          @monegator said in QSerialPort, randomly missing bytes:

          almost completely asynchronous

          The almost raises an eyebrow. While having no personal experience with that specific class in a such a setting, I'd recommend to avoid mixing async and sync API.

          Any chance you can show us some code?

          Software Engineer
          The Qt Company, Oslo

          1 Reply Last reply
          3
          • Kent-DorfmanK Offline
            Kent-DorfmanK Offline
            Kent-Dorfman
            wrote last edited by
            #5

            and on the tablet that Moses dropped while coming down from the mountain, it said "Thou shalt use flow control"

            The dystopian literature that served as a warning in my youth has become an instruction manual in my elder years.

            SGaistS 1 Reply Last reply
            2
            • Kent-DorfmanK Kent-Dorfman

              and on the tablet that Moses dropped while coming down from the mountain, it said "Thou shalt use flow control"

              SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote last edited by
              #6

              @Kent-Dorfman said in QSerialPort, randomly missing bytes:

              and on the tablet that Moses dropped while coming down from the mountain, it said "Thou shalt use flow control"

              Highly efficient on the Red Sea !

              Interested in AI ? www.idiap.ch
              Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              1
              • Joe von HabsburgJ Offline
                Joe von HabsburgJ Offline
                Joe von Habsburg
                wrote last edited by Joe von Habsburg
                #7

                If you parse data with like "\r\n" may be you read begin incorrect index

                void onReadyRead()
                {
                    static QByteArray buffer;
                
                    buffer.append(_serial->readAll());
                
                    int index;
                    while((index = buffer.indexOf("\r\n")) != -1) {
                        QByteArray line = buffer.left(index);
                        buffer.remove(0, index + 2);
                
                        if(!line.isEmpty()) {
                            parseData(line);
                        }
                    }
                }
                

                If you use

                _serial->read(N);
                //or
                _serial->readLine();
                

                problem is here my opinion.

                1 Reply Last reply
                0
                • F Offline
                  F Offline
                  FRAUBRJ
                  wrote last edited by
                  #8

                  On my Mac the solution I found is (message is in the global "inputQString")

                  void MainWindow::slotRead(void)
                  {
                  qint64 bw = 0;
                  QByteArray data;

                  data = port->readAll();
                  while (port->waitForReadyRead(15))
                      data += port->readAll();
                  
                  inputQString = data;
                  
                  bw = inputQString.size();
                  
                  //qDebug() << "inputString: " << inputQString << "  bw: " << bw;;
                  ReadRequest(bw);
                  

                  } // slotRead

                  Perhaps adjust the ms parameter of "waitForReadyRead(ms)"

                  Christian EhrlicherC J.HilkJ 2 Replies Last reply
                  0
                  • F FRAUBRJ

                    On my Mac the solution I found is (message is in the global "inputQString")

                    void MainWindow::slotRead(void)
                    {
                    qint64 bw = 0;
                    QByteArray data;

                    data = port->readAll();
                    while (port->waitForReadyRead(15))
                        data += port->readAll();
                    
                    inputQString = data;
                    
                    bw = inputQString.size();
                    
                    //qDebug() << "inputString: " << inputQString << "  bw: " << bw;;
                    ReadRequest(bw);
                    

                    } // slotRead

                    Perhaps adjust the ms parameter of "waitForReadyRead(ms)"

                    Christian EhrlicherC Offline
                    Christian EhrlicherC Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote last edited by
                    #9

                    @FRAUBRJ said in QSerialPort, randomly missing bytes:

                    Perhaps adjust the ms parameter of "waitForReadyRead(ms)"

                    Even better: don't use it at all.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    3
                    • F FRAUBRJ

                      On my Mac the solution I found is (message is in the global "inputQString")

                      void MainWindow::slotRead(void)
                      {
                      qint64 bw = 0;
                      QByteArray data;

                      data = port->readAll();
                      while (port->waitForReadyRead(15))
                          data += port->readAll();
                      
                      inputQString = data;
                      
                      bw = inputQString.size();
                      
                      //qDebug() << "inputString: " << inputQString << "  bw: " << bw;;
                      ReadRequest(bw);
                      

                      } // slotRead

                      Perhaps adjust the ms parameter of "waitForReadyRead(ms)"

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote last edited by
                      #10

                      @FRAUBRJ I'm afraid, you haven't found a solution.

                      You have found a way that happens to work for your hardware and your data at the current time of the moon phase.

                      There is so much to improve here, but the important part is, you need some why to verify that you have all data you expect. Do not expect that all data is there when readAll() is called.

                      And despite what you expect, it is called exactly once, your while loop is literally doing nothing.


                      Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                      Q: What's that?
                      A: It's blue light.
                      Q: What does it do?
                      A: It turns blue.

                      1 Reply Last reply
                      2

                      • Login

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