Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Qt Creator and other tools
  4. QtSerialPort problems with the continuous reading of data from the serial port

QtSerialPort problems with the continuous reading of data from the serial port

Scheduled Pinned Locked Moved Unsolved Qt Creator and other tools
5 Posts 5 Posters 2.2k 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.
  • M Offline
    M Offline
    MatteoB
    wrote on last edited by
    #1

    Hi, I'm reading data from serial port with QT, in mainwindow I've write this code:

    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    #include<QTextStream>
    #include<QSerialPort>
    #include<QSerialPortInfo>
    #include<QtDebug>
    #include<QThread>
    QSerialPort *serial;
    MainWindow::MainWindow(QWidget *parent)
        : QMainWindow(parent),
         ui(new Ui::MainWindow),
          m_standardOutput(stdout)
    {
         ui->setupUi(this);
        serial= new QSerialPort(this);
        serial->setPortName("COM3");
        serial->setBaudRate(QSerialPort::Baud115200);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
        serial->open(QIODevice::ReadOnly);
    
    
    
        connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReaderH);
    
        float HUM;
         HUM=H;
    
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::ReaderH()
    {
    
            quint64 X=20;
        serial->waitForReadyRead();
        m_readData=serial->QSerialPort::read(X);
        //if (!m_timer.isActive())
          //     m_timer.start(5000);
         inter2=QString(m_readData);
        QStringList firstlist2= inter2.split(";");
        m_readData3=firstlist2.takeFirst();
        H=m_readData3.toFloat();
         qDebug() <<"Data:"<<m_readData<< " \r\n";
        //QThread::sleep(11);
    
    
    }
    

    the program reads the data correctly for a few seconds, after a while the reading starts to be out of phase, like this:

    Data: "60.904655;25.779804$"

    Data: "60.970406;25.816269$"

    Data: "60.988335;25.798037$"

    Data: "60."

    Data: "883736;25.7"

    Data: "61570$"

    Data: "60."

    Data: "91063"

    Data: "7;25.779804$"

    Data: "60."

    Data: "934544;25."

    Data: "798037$"

    Data: "60"

    Data: ".871784;25.798037$"

    I can't understand how to solve the problem. Thank you for your time.

    J.HilkJ JonBJ Pablo J. RoginaP KroMignonK 4 Replies Last reply
    0
    • M MatteoB

      Hi, I'm reading data from serial port with QT, in mainwindow I've write this code:

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      #include<QTextStream>
      #include<QSerialPort>
      #include<QSerialPortInfo>
      #include<QtDebug>
      #include<QThread>
      QSerialPort *serial;
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent),
           ui(new Ui::MainWindow),
            m_standardOutput(stdout)
      {
           ui->setupUi(this);
          serial= new QSerialPort(this);
          serial->setPortName("COM3");
          serial->setBaudRate(QSerialPort::Baud115200);
          serial->setDataBits(QSerialPort::Data8);
          serial->setParity(QSerialPort::NoParity);
          serial->setStopBits(QSerialPort::OneStop);
          serial->setFlowControl(QSerialPort::NoFlowControl);
          serial->open(QIODevice::ReadOnly);
      
      
      
          connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReaderH);
      
          float HUM;
           HUM=H;
      
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
      }
      
      void MainWindow::ReaderH()
      {
      
              quint64 X=20;
          serial->waitForReadyRead();
          m_readData=serial->QSerialPort::read(X);
          //if (!m_timer.isActive())
            //     m_timer.start(5000);
           inter2=QString(m_readData);
          QStringList firstlist2= inter2.split(";");
          m_readData3=firstlist2.takeFirst();
          H=m_readData3.toFloat();
           qDebug() <<"Data:"<<m_readData<< " \r\n";
          //QThread::sleep(11);
      
      
      }
      

      the program reads the data correctly for a few seconds, after a while the reading starts to be out of phase, like this:

      Data: "60.904655;25.779804$"

      Data: "60.970406;25.816269$"

      Data: "60.988335;25.798037$"

      Data: "60."

      Data: "883736;25.7"

      Data: "61570$"

      Data: "60."

      Data: "91063"

      Data: "7;25.779804$"

      Data: "60."

      Data: "934544;25."

      Data: "798037$"

      Data: "60"

      Data: ".871784;25.798037$"

      I can't understand how to solve the problem. Thank you for your time.

      J.HilkJ Offline
      J.HilkJ Offline
      J.Hilk
      Moderators
      wrote on last edited by
      #2

      @MatteoB
      you have to accumulate your data, THERE IS NO GUARANTEE that all data is in the serial port buffer, when ready read is emitted.

      also, do not call waitForReady read, inside the slot, that is connected to the signal, bad things may happen

      mockup code:

      #include <QCoreApplication>
      
      #include <QSerialPort>
      #include <QDebug>
      
      QSerialPort serial;
      int sendIndex(-1);
      
      static const QVector<QByteArray> toSend{
          {"Command1"},
          {"Command2"},
          {"Command3"},
      };
      
      void writeNextCommand(){
          sendIndex++;
          if(sendIndex < toSend.size()){
              serial.write(toSend.at(sendIndex));
          } else {
              qDebug() << "All Send";
          }
      }
      
      QByteArray receivedData;
      void onReadyRead(){
          receivedData += serial.readAll();
      
          //Your own logic, that ba is complete and correct
      
          //--
          qDebug() << "onReadyRead: new bytes:" << receivedData.toHex(' ');
      
          //if(dataOK(receivedData))
          writeNextCommand();
      }
      
      qint64 bytesWrittenSoFar(0);
      void onBytesWritten(qint64 bytesWritten){
          bytesWrittenSoFar += bytesWritten;
          if( bytesWrittenSoFar == toSend.at(sendIndex).size()){
              qDebug() << QString("All bytes (%1) of the command send, expecting now answer").arg(bytesWrittenSoFar);
              bytesWrittenSoFar = 0;
          }else
              qDebug() << bytesWrittenSoFar << " of" << toSend.at(sendIndex).size();
      }
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
          //Setup Port
      
          QObject::connect(&serial, &QSerialPort::bytesWritten,&onBytesWritten);
          QObject::connect(&serial, &QSerialPort::readyRead, &onReadyRead);
      
          serial.setPortName("PortX");
         /*
          serial.setParity();
          serial.setBaudRate();
          serial.setDataBits();
          serial.setStopBits();
          serial.setFlowControl();
          */
          if(serial.open(QIODevice::ReadWrite)){
              writeNextCommand();
          } else {
              qDebug() << "Could not open Serialport";
          }
      
          return a.exec();
      }
      
      

      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
      3
      • M MatteoB

        Hi, I'm reading data from serial port with QT, in mainwindow I've write this code:

        #include "mainwindow.h"
        #include "ui_mainwindow.h"
        #include<QTextStream>
        #include<QSerialPort>
        #include<QSerialPortInfo>
        #include<QtDebug>
        #include<QThread>
        QSerialPort *serial;
        MainWindow::MainWindow(QWidget *parent)
            : QMainWindow(parent),
             ui(new Ui::MainWindow),
              m_standardOutput(stdout)
        {
             ui->setupUi(this);
            serial= new QSerialPort(this);
            serial->setPortName("COM3");
            serial->setBaudRate(QSerialPort::Baud115200);
            serial->setDataBits(QSerialPort::Data8);
            serial->setParity(QSerialPort::NoParity);
            serial->setStopBits(QSerialPort::OneStop);
            serial->setFlowControl(QSerialPort::NoFlowControl);
            serial->open(QIODevice::ReadOnly);
        
        
        
            connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReaderH);
        
            float HUM;
             HUM=H;
        
        }
        
        MainWindow::~MainWindow()
        {
            delete ui;
        }
        
        void MainWindow::ReaderH()
        {
        
                quint64 X=20;
            serial->waitForReadyRead();
            m_readData=serial->QSerialPort::read(X);
            //if (!m_timer.isActive())
              //     m_timer.start(5000);
             inter2=QString(m_readData);
            QStringList firstlist2= inter2.split(";");
            m_readData3=firstlist2.takeFirst();
            H=m_readData3.toFloat();
             qDebug() <<"Data:"<<m_readData<< " \r\n";
            //QThread::sleep(11);
        
        
        }
        

        the program reads the data correctly for a few seconds, after a while the reading starts to be out of phase, like this:

        Data: "60.904655;25.779804$"

        Data: "60.970406;25.816269$"

        Data: "60.988335;25.798037$"

        Data: "60."

        Data: "883736;25.7"

        Data: "61570$"

        Data: "60."

        Data: "91063"

        Data: "7;25.779804$"

        Data: "60."

        Data: "934544;25."

        Data: "798037$"

        Data: "60"

        Data: ".871784;25.798037$"

        I can't understand how to solve the problem. Thank you for your time.

        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3

        @MatteoB
        Similarities to the discussion currently on-going in https://forum.qt.io/topic/117717/qserialport-waitforreadyread-exits-with-timeou

        connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReaderH);
        ...
        void MainWindow::ReaderH()
        {
            serial->waitForReadyRead();
        ...
        

        Absolutely not! Do not make the blocking waitForReadyRead(); inside the non-blocking QSerialPort::readyRead slot! Do not make any blocking calls if you are using the asynchronous signals/slots, or vice versa.

        I do not know whether this is the cause of your behaviour or not, but start by picking one or the other (preferably the async non-block signals), and stick to them alone :)

        EDIT Post crossed with that from @J-Hilk . Use his code approach.

        1 Reply Last reply
        3
        • M MatteoB

          Hi, I'm reading data from serial port with QT, in mainwindow I've write this code:

          #include "mainwindow.h"
          #include "ui_mainwindow.h"
          #include<QTextStream>
          #include<QSerialPort>
          #include<QSerialPortInfo>
          #include<QtDebug>
          #include<QThread>
          QSerialPort *serial;
          MainWindow::MainWindow(QWidget *parent)
              : QMainWindow(parent),
               ui(new Ui::MainWindow),
                m_standardOutput(stdout)
          {
               ui->setupUi(this);
              serial= new QSerialPort(this);
              serial->setPortName("COM3");
              serial->setBaudRate(QSerialPort::Baud115200);
              serial->setDataBits(QSerialPort::Data8);
              serial->setParity(QSerialPort::NoParity);
              serial->setStopBits(QSerialPort::OneStop);
              serial->setFlowControl(QSerialPort::NoFlowControl);
              serial->open(QIODevice::ReadOnly);
          
          
          
              connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReaderH);
          
              float HUM;
               HUM=H;
          
          }
          
          MainWindow::~MainWindow()
          {
              delete ui;
          }
          
          void MainWindow::ReaderH()
          {
          
                  quint64 X=20;
              serial->waitForReadyRead();
              m_readData=serial->QSerialPort::read(X);
              //if (!m_timer.isActive())
                //     m_timer.start(5000);
               inter2=QString(m_readData);
              QStringList firstlist2= inter2.split(";");
              m_readData3=firstlist2.takeFirst();
              H=m_readData3.toFloat();
               qDebug() <<"Data:"<<m_readData<< " \r\n";
              //QThread::sleep(11);
          
          
          }
          

          the program reads the data correctly for a few seconds, after a while the reading starts to be out of phase, like this:

          Data: "60.904655;25.779804$"

          Data: "60.970406;25.816269$"

          Data: "60.988335;25.798037$"

          Data: "60."

          Data: "883736;25.7"

          Data: "61570$"

          Data: "60."

          Data: "91063"

          Data: "7;25.779804$"

          Data: "60."

          Data: "934544;25."

          Data: "798037$"

          Data: "60"

          Data: ".871784;25.798037$"

          I can't understand how to solve the problem. Thank you for your time.

          Pablo J. RoginaP Offline
          Pablo J. RoginaP Offline
          Pablo J. Rogina
          wrote on last edited by
          #4

          @MatteoB in addition to all the previous suggestions, you may want to try/study the serial port examples, in particular the Terminal one.

          Upvote the answer(s) that helped you solve the issue
          Use "Topic Tools" button to mark your post as Solved
          Add screenshots via postimage.org
          Don't ask support requests via chat/PM. Please use the forum so others can benefit from the solution in the future

          1 Reply Last reply
          0
          • M MatteoB

            Hi, I'm reading data from serial port with QT, in mainwindow I've write this code:

            #include "mainwindow.h"
            #include "ui_mainwindow.h"
            #include<QTextStream>
            #include<QSerialPort>
            #include<QSerialPortInfo>
            #include<QtDebug>
            #include<QThread>
            QSerialPort *serial;
            MainWindow::MainWindow(QWidget *parent)
                : QMainWindow(parent),
                 ui(new Ui::MainWindow),
                  m_standardOutput(stdout)
            {
                 ui->setupUi(this);
                serial= new QSerialPort(this);
                serial->setPortName("COM3");
                serial->setBaudRate(QSerialPort::Baud115200);
                serial->setDataBits(QSerialPort::Data8);
                serial->setParity(QSerialPort::NoParity);
                serial->setStopBits(QSerialPort::OneStop);
                serial->setFlowControl(QSerialPort::NoFlowControl);
                serial->open(QIODevice::ReadOnly);
            
            
            
                connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReaderH);
            
                float HUM;
                 HUM=H;
            
            }
            
            MainWindow::~MainWindow()
            {
                delete ui;
            }
            
            void MainWindow::ReaderH()
            {
            
                    quint64 X=20;
                serial->waitForReadyRead();
                m_readData=serial->QSerialPort::read(X);
                //if (!m_timer.isActive())
                  //     m_timer.start(5000);
                 inter2=QString(m_readData);
                QStringList firstlist2= inter2.split(";");
                m_readData3=firstlist2.takeFirst();
                H=m_readData3.toFloat();
                 qDebug() <<"Data:"<<m_readData<< " \r\n";
                //QThread::sleep(11);
            
            
            }
            

            the program reads the data correctly for a few seconds, after a while the reading starts to be out of phase, like this:

            Data: "60.904655;25.779804$"

            Data: "60.970406;25.816269$"

            Data: "60.988335;25.798037$"

            Data: "60."

            Data: "883736;25.7"

            Data: "61570$"

            Data: "60."

            Data: "91063"

            Data: "7;25.779804$"

            Data: "60."

            Data: "934544;25."

            Data: "798037$"

            Data: "60"

            Data: ".871784;25.798037$"

            I can't understand how to solve the problem. Thank you for your time.

            KroMignonK Offline
            KroMignonK Offline
            KroMignon
            wrote on last edited by KroMignon
            #5

            @MatteoB said in QtSerialPort problems with the continuous reading of data from the serial port:

            void MainWindow::ReaderH()
            {
            quint64 X=20;
            serial->waitForReadyRead();
            m_readData=serial->QSerialPort::read(X);
            //if (!m_timer.isActive())
            // m_timer.start(5000);
            inter2=QString(m_readData);
            QStringList firstlist2= inter2.split(";");
            m_readData3=firstlist2.takeFirst();
            H=m_readData3.toFloat();
            qDebug() <<"Data:"<<m_readData<< " \r\n";
            //QThread::sleep(11);
            }

            I think you have 2 problems with your implementation:

            • first: mixing pooling mode functions (waitForReadyRead() / waitForBytesWritten()) and asynchronous functions (readyRead() / bytesWritten()) is not recommended
            • second: a serial port link is a stream interface and not a packet interface. So you have to know how to detect message begin and end from this stream. When you read data, you may read the full message or just a part of it!

            So you code cannot work properly!
            I support your messages ends with $, so you could do something like this:

            void MainWindow::ReaderH()
            {
                // I support m_readData is a QByteArray
                while(serial->bytesAvailable())
                {
                    m_readData.append(serial->readall());
                }
                int idx=0;
                while( (idx=m_readData.indexOf('$')) >= 0 )
                {
                    if(idx > 0)
                    {
                       auto message = QString(m_readData.left(idx));
                       qDebug() << "Message:"<< message << " \r\n";
                    }
                    m_readData.remove(0, idx+1);
                }
            }
            

            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

            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