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. Error while writing and reading (SerialPort)

Error while writing and reading (SerialPort)

Scheduled Pinned Locked Moved Solved General and Desktop
10 Posts 3 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.
  • E Offline
    E Offline
    Elite_Shergio
    wrote on last edited by aha_1980
    #1

    Hello There!

    I´m new in Qt and doing Serial Communication. I need to make the connection between a GPS receiver and my PC, the connection is correct, and the reading is ok as well... but there is a problem, when a try to write and send commands to the GPS always got something wrong...
    When I was able to send the information correctly, something strange happends. If a configure the GPS outside QT (RealTerm), and reconfigure with my code, the response that supose to give me just 2 short messages in the command window, get stuck with the same message and sends me infinite number of them

    0_1566857135181_error1.png

    if there is no previous configuration, the program doesn't send anything, at least that seems to be.

    0_1566857202192_error2.png

    This is my code

    #include "myserial.h"
    #include <QtSerialPort/QSerialPort>
    #include <QObject>
    #include <QtWidgets>
    #include <QFile>
    #include <QTextStream>
    
    int main(int argc, char *argv[])
    {
        QCoreApplication a(argc, argv);
    
            //MySerialPort();
    
            MySerialPort iSerialPort;
            iSerialPort.openSerialPort();
    
            return a.exec();
    }
    
    
    MySerialPort::MySerialPort()
    {
    
        serial = new QSerialPort(this);
        connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
        //openSerialPort();
    
    }
    
    void MySerialPort::openSerialPort()
    {
        QString nombre;
    
        const auto infos = QSerialPortInfo::availablePorts();
        for (const QSerialPortInfo &info : infos) {
            QString puerto = info.portName();
            if ( info.manufacturer() == "Prolific" )
            {
                nombre = puerto;
                qDebug().noquote() << "El GPS se encuentra conectado en el puerto:" << nombre;
            }
        }
    
        serial->setPortName(nombre);
        serial->setBaudRate(QSerialPort::Baud9600);
        serial->setDataBits(QSerialPort::Data8);
        serial->setParity(QSerialPort::NoParity);
        serial->setStopBits(QSerialPort::OneStop);
        serial->setFlowControl(QSerialPort::NoFlowControl);
        if (serial->open(QIODevice::ReadWrite)) {
    
            showStatusMessage("Contectado a GPS");
    
        } else {
    
            showStatusMessage(tr("Open error"));
        }
    }
    
    void MySerialPort::closeSerialPort()
    {
        if (serial->isOpen())
            serial->close();
    
        showStatusMessage(tr("Disconnected"));
    }
    
    void MySerialPort::sendData()
    {
        static char Cf[]={0x40, 0x40, 0x43, 0x66, 0x25, 0x0D, 0x0A};
        for (int i=0; i < 7; i++)
            {
                serial->putChar(Cf[i]);
            }/*
        static char Gd[]={0x40, 0x40, 0x47, 0x64, 0x03, 0x20, 0x0D, 0x0A};
        for (int i=0; i < 8; i++)
            {
                serial->putChar(Gd[i]);
            }
        static char Ge[]={0x40, 0x40, 0x47, 0x65, 0x01, 0x23, 0x0D, 0x0A};
        for (int i=0; i < 8; i++)
            {
                serial->putChar(Ge[i]);
            }*/
        static char Hn[]={0x40, 0x40, 0x48, 0x6e, 0x02, 0x24, 0x0D, 0x0A};
        for (int i=0; i < 8; i++)
            {
                serial->putChar(Hn[i]);
            }
    
    }
    
    void MySerialPort::readData()
    {
    
        sendData();
    
    
        QByteArray data = serial->readAll();
    
        // qDebug() << data;
    
        QByteArray received = data.toHex();
    
        qDebug()<<"testing :"<<received;
    
    
       
    
    
    }
    
    void MySerialPort::handleError(QSerialPort::SerialPortError error)
    {
        if (error == QSerialPort::ResourceError) {
            closeSerialPort();
        }
    }
    
    
    void MySerialPort::showStatusMessage(const QString &message)
    {
        qDebug() << message;
    }
    
    
    

    Any help would be nice, thank you

    aha_1980A 1 Reply Last reply
    0
    • E Offline
      E Offline
      Elite_Shergio
      wrote on last edited by
      #10

      Its works now!!

      I better call both functions in order to execute one at time, used the readyRead signal

      ...
      MySerialPort::MySerialPort()
      {
      
          serial = new QSerialPort(this);
          connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
      ...
      
          serial->setPortName(nombre);
          serial->setBaudRate(QSerialPort::Baud9600);
          serial->setDataBits(QSerialPort::Data8);
          serial->setParity(QSerialPort::NoParity);
          serial->setStopBits(QSerialPort::OneStop);
          serial->setFlowControl(QSerialPort::NoFlowControl);
          if (serial->open(QIODevice::ReadWrite))
          {
      
              showStatusMessage("Contectado a GPS");
      
          } else {
      
              showStatusMessage(tr("Open error"));
          }
      
          sendData();
      
          readData();
      
      }
      
      ...
      ...
      

      Used "waitForBytesWritten()" at the end of writing, and "QIODevice::readyRead();" before start reading, so there is no failure now. Thanks everybody!

      1 Reply Last reply
      0
      • hskoglundH Offline
        hskoglundH Offline
        hskoglund
        wrote on last edited by
        #2

        Hi, the connection to the GPS is 9600 baud, which means about 1000 characters per second, but in void MySerialPort::readData():

        void MySerialPort::readData()
        {
        // you're transmitting 15 characters, which takes about 15 milliseconds
             sendData();
        
        // but you're immediately trying to get an answer from the GPS
            QByteArray data = serial->readAll();
        

        try waiting 15 milliseconds for the 15 characters to be transmitted and then wait at least 15 milliseconds more the characters to arrive, before doing serial->readAll()

        Note: there are lots of helper functions for this in the QSerialPort class, for example you can use waitForBytesWritten() to make sure all of 15 characters have been transmitted before you're expecting an answer.

        aha_1980A E 2 Replies Last reply
        4
        • hskoglundH hskoglund

          Hi, the connection to the GPS is 9600 baud, which means about 1000 characters per second, but in void MySerialPort::readData():

          void MySerialPort::readData()
          {
          // you're transmitting 15 characters, which takes about 15 milliseconds
               sendData();
          
          // but you're immediately trying to get an answer from the GPS
              QByteArray data = serial->readAll();
          

          try waiting 15 milliseconds for the 15 characters to be transmitted and then wait at least 15 milliseconds more the characters to arrive, before doing serial->readAll()

          Note: there are lots of helper functions for this in the QSerialPort class, for example you can use waitForBytesWritten() to make sure all of 15 characters have been transmitted before you're expecting an answer.

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

          @hskoglund

          While I fully agree to the first part of your answer, I object to the second one.

          try waiting 15 milliseconds for the 15 characters to be transmitted and then wait at least 15 milliseconds more the characters to arrive, before doing serial->readAll()

          No, that is wrong.

          The correct way is to use a slot connected to readyRead() and read the incoming data there. Once the device answers, you will get the data there.

          Everything else, including waitForBytesWritten() is contra-productive (except if running in a separate thread).

          Regards

          Qt has to stay free or it will die.

          hskoglundH 1 Reply Last reply
          3
          • E Elite_Shergio

            Hello There!

            I´m new in Qt and doing Serial Communication. I need to make the connection between a GPS receiver and my PC, the connection is correct, and the reading is ok as well... but there is a problem, when a try to write and send commands to the GPS always got something wrong...
            When I was able to send the information correctly, something strange happends. If a configure the GPS outside QT (RealTerm), and reconfigure with my code, the response that supose to give me just 2 short messages in the command window, get stuck with the same message and sends me infinite number of them

            0_1566857135181_error1.png

            if there is no previous configuration, the program doesn't send anything, at least that seems to be.

            0_1566857202192_error2.png

            This is my code

            #include "myserial.h"
            #include <QtSerialPort/QSerialPort>
            #include <QObject>
            #include <QtWidgets>
            #include <QFile>
            #include <QTextStream>
            
            int main(int argc, char *argv[])
            {
                QCoreApplication a(argc, argv);
            
                    //MySerialPort();
            
                    MySerialPort iSerialPort;
                    iSerialPort.openSerialPort();
            
                    return a.exec();
            }
            
            
            MySerialPort::MySerialPort()
            {
            
                serial = new QSerialPort(this);
                connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
                //openSerialPort();
            
            }
            
            void MySerialPort::openSerialPort()
            {
                QString nombre;
            
                const auto infos = QSerialPortInfo::availablePorts();
                for (const QSerialPortInfo &info : infos) {
                    QString puerto = info.portName();
                    if ( info.manufacturer() == "Prolific" )
                    {
                        nombre = puerto;
                        qDebug().noquote() << "El GPS se encuentra conectado en el puerto:" << nombre;
                    }
                }
            
                serial->setPortName(nombre);
                serial->setBaudRate(QSerialPort::Baud9600);
                serial->setDataBits(QSerialPort::Data8);
                serial->setParity(QSerialPort::NoParity);
                serial->setStopBits(QSerialPort::OneStop);
                serial->setFlowControl(QSerialPort::NoFlowControl);
                if (serial->open(QIODevice::ReadWrite)) {
            
                    showStatusMessage("Contectado a GPS");
            
                } else {
            
                    showStatusMessage(tr("Open error"));
                }
            }
            
            void MySerialPort::closeSerialPort()
            {
                if (serial->isOpen())
                    serial->close();
            
                showStatusMessage(tr("Disconnected"));
            }
            
            void MySerialPort::sendData()
            {
                static char Cf[]={0x40, 0x40, 0x43, 0x66, 0x25, 0x0D, 0x0A};
                for (int i=0; i < 7; i++)
                    {
                        serial->putChar(Cf[i]);
                    }/*
                static char Gd[]={0x40, 0x40, 0x47, 0x64, 0x03, 0x20, 0x0D, 0x0A};
                for (int i=0; i < 8; i++)
                    {
                        serial->putChar(Gd[i]);
                    }
                static char Ge[]={0x40, 0x40, 0x47, 0x65, 0x01, 0x23, 0x0D, 0x0A};
                for (int i=0; i < 8; i++)
                    {
                        serial->putChar(Ge[i]);
                    }*/
                static char Hn[]={0x40, 0x40, 0x48, 0x6e, 0x02, 0x24, 0x0D, 0x0A};
                for (int i=0; i < 8; i++)
                    {
                        serial->putChar(Hn[i]);
                    }
            
            }
            
            void MySerialPort::readData()
            {
            
                sendData();
            
            
                QByteArray data = serial->readAll();
            
                // qDebug() << data;
            
                QByteArray received = data.toHex();
            
                qDebug()<<"testing :"<<received;
            
            
               
            
            
            }
            
            void MySerialPort::handleError(QSerialPort::SerialPortError error)
            {
                if (error == QSerialPort::ResourceError) {
                    closeSerialPort();
                }
            }
            
            
            void MySerialPort::showStatusMessage(const QString &message)
            {
                qDebug() << message;
            }
            
            
            

            Any help would be nice, thank you

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

            @elite_shergio

            By the way, can't you use the Qt positioning module?

            Qt has to stay free or it will die.

            E 1 Reply Last reply
            1
            • aha_1980A aha_1980

              @hskoglund

              While I fully agree to the first part of your answer, I object to the second one.

              try waiting 15 milliseconds for the 15 characters to be transmitted and then wait at least 15 milliseconds more the characters to arrive, before doing serial->readAll()

              No, that is wrong.

              The correct way is to use a slot connected to readyRead() and read the incoming data there. Once the device answers, you will get the data there.

              Everything else, including waitForBytesWritten() is contra-productive (except if running in a separate thread).

              Regards

              hskoglundH Offline
              hskoglundH Offline
              hskoglund
              wrote on last edited by
              #5

              @aha_1980 said in Error while writing and reading (SerialPort):

              try waiting 15 milliseconds for the 15 characters to be transmitted and then wait at least 15 milliseconds more the characters to arrive, before doing serial->readAll()

              No, that is wrong.

              Yes, agreed it's a dumb way. (Also waitForBytesWritten() has a history of being unreliable, at least on Windows.)

              Problem was: readyRead() signal is connected ok, but transmitting the 15 characters inside the readyRead() signal handler and expecting an immediate answer will fail, so I tried to explain that serial communication is a sloooow business.

              aha_1980A 1 Reply Last reply
              3
              • hskoglundH hskoglund

                @aha_1980 said in Error while writing and reading (SerialPort):

                try waiting 15 milliseconds for the 15 characters to be transmitted and then wait at least 15 milliseconds more the characters to arrive, before doing serial->readAll()

                No, that is wrong.

                Yes, agreed it's a dumb way. (Also waitForBytesWritten() has a history of being unreliable, at least on Windows.)

                Problem was: readyRead() signal is connected ok, but transmitting the 15 characters inside the readyRead() signal handler and expecting an immediate answer will fail, so I tried to explain that serial communication is a sloooow business.

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

                @hskoglund said in Error while writing and reading (SerialPort):

                Problem was: readyRead() signal is connected ok, but transmitting the 15 characters inside the readyRead() signal handler and expecting an immediate answer will fail, so I tried to explain that serial communication is a sloooow business.

                That is fully correct. But sending the characters out will lead to another answer, i.e. another readyRead() signal and there the answer can be handled.

                Regards

                Qt has to stay free or it will die.

                1 Reply Last reply
                1
                • hskoglundH hskoglund

                  Hi, the connection to the GPS is 9600 baud, which means about 1000 characters per second, but in void MySerialPort::readData():

                  void MySerialPort::readData()
                  {
                  // you're transmitting 15 characters, which takes about 15 milliseconds
                       sendData();
                  
                  // but you're immediately trying to get an answer from the GPS
                      QByteArray data = serial->readAll();
                  

                  try waiting 15 milliseconds for the 15 characters to be transmitted and then wait at least 15 milliseconds more the characters to arrive, before doing serial->readAll()

                  Note: there are lots of helper functions for this in the QSerialPort class, for example you can use waitForBytesWritten() to make sure all of 15 characters have been transmitted before you're expecting an answer.

                  E Offline
                  E Offline
                  Elite_Shergio
                  wrote on last edited by
                  #7
                  This post is deleted!
                  1 Reply Last reply
                  0
                  • aha_1980A aha_1980

                    @elite_shergio

                    By the way, can't you use the Qt positioning module?

                    E Offline
                    E Offline
                    Elite_Shergio
                    wrote on last edited by
                    #8

                    @aha_1980

                    Hi!
                    Didn´t know that module exists, will take a look

                    1 Reply Last reply
                    0
                    • E Offline
                      E Offline
                      Elite_Shergio
                      wrote on last edited by
                      #9

                      @hskoglund

                      H

                      Now I get that, will use "readyRead()" and won´t ask for inmmediate answer haha thanks!

                      1 Reply Last reply
                      1
                      • E Offline
                        E Offline
                        Elite_Shergio
                        wrote on last edited by
                        #10

                        Its works now!!

                        I better call both functions in order to execute one at time, used the readyRead signal

                        ...
                        MySerialPort::MySerialPort()
                        {
                        
                            serial = new QSerialPort(this);
                            connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
                        ...
                        
                            serial->setPortName(nombre);
                            serial->setBaudRate(QSerialPort::Baud9600);
                            serial->setDataBits(QSerialPort::Data8);
                            serial->setParity(QSerialPort::NoParity);
                            serial->setStopBits(QSerialPort::OneStop);
                            serial->setFlowControl(QSerialPort::NoFlowControl);
                            if (serial->open(QIODevice::ReadWrite))
                            {
                        
                                showStatusMessage("Contectado a GPS");
                        
                            } else {
                        
                                showStatusMessage(tr("Open error"));
                            }
                        
                            sendData();
                        
                            readData();
                        
                        }
                        
                        ...
                        ...
                        

                        Used "waitForBytesWritten()" at the end of writing, and "QIODevice::readyRead();" before start reading, so there is no failure now. Thanks everybody!

                        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