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. Problems with RTS management with QtSerialPort
Forum Updated to NodeBB v4.3 + New Features

Problems with RTS management with QtSerialPort

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 2 Posters 1.9k 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.
  • I Offline
    I Offline
    iaguirre
    wrote on last edited by iaguirre
    #1

    Hi all.

    I am implementing a communicatin protocol over RS485 and I am having problems with the RTS management.
    I am QSerialPort class in Qt 5.6.1.

    I put UP the RTS when I am going to trasnmit a frame data and when the "bytesWritten" signal is received I put it DOWN in the connected slot.
    If I have no answer to the above sent frame, I retransmit it. But in the retranmission (in the same slot as above) the RTS signal is put down before all the data have been retransmitted.

    The up and down of the signal is done with the method "setRequestToSend".

    This is the code the mos relevant related code:

    Port configuration
    if(mSerialPort->open(QIODevice::ReadWrite)){
    currentTxId = 0;
    mSerialPort->setBaudRate(QSerialPort::Baud115200);
    mSerialPort->setDataBits(QSerialPort::Data8);
    mSerialPort->setFlowControl(QSerialPort::NoFlowControl);
    mSerialPort->setStopBits(QSerialPort::OneStop);
    mSerialPort->setParity(QSerialPort::NoParity);

        mSerialPort->setDataTerminalReady(true);       
    
        bool rtsUP = mSerialPort->isRequestToSend();
        mSerialPort->setRequestToSend(!rtsUP);
    
       connect(mSerialPort, SIGNAL(readyRead()), this, SLOT(onDataAvailable()));
       connect(mSerialPort, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
    

    }

    Send Data and RTS Up
    bool AppProtocolHandler::sendFrameWithACK(const QByteArray frame)
    {
    QByteArray txframe = frame;
    txframe.push_front(flag_STX);
    txframe.push_front(flag_DLE);
    txframe.push_back(flag_DEL);
    txframe.push_back(flag_ETX);

     //Start frame retransmission Timer
    m_txTimer->start(FRAME_RETRANSMISION_TIME);
    
    bool rtsUP = mSerialPort->isRequestToSend();
    if (rtsUP){
        mSerialPort->setRequestToSend(false);
    }
    
    qint64 frameLenght = static_cast<qint64> (frame.at(0));
    qint64 txlen = mSerialPort->write(txframe, frameLenght);
    
    if (mSerialPort->waitForBytesWritten(500)){
        m_txframe = frame;
        m_pendingFrames.insert(static_cast<int>(txframe.at(5)), static_cast<t_prot_cmd>(txframe.at(6)));
         return true;
    }
    else
    {
        qDebug()<< "AppProtocolHandler::sendFrameWithACK waitForBytesWritten(500) = FALSE";
        mSerialPort->setRequestToSend(true);
        return false;
    }
    

    }

    End Send Data and RTS Down
    void AppProtocolHandler::onBytesWritten(qint64 nBytes)
    {
    qint64 frameLenght = static_cast<qint64> (m_txframe.at(0));

    if (nBytes == frameLenght)
    {
        bool rtsUP = mSerialPort->isRequestToSend();
        if (!rtsUP){
            mSerialPort->setRequestToSend(true);
        }
    }
    

    }

    Any help or experience would be appreciated.
    Thanks!!

    aha_1980A 1 Reply Last reply
    0
    • I iaguirre

      Hi all.

      I am implementing a communicatin protocol over RS485 and I am having problems with the RTS management.
      I am QSerialPort class in Qt 5.6.1.

      I put UP the RTS when I am going to trasnmit a frame data and when the "bytesWritten" signal is received I put it DOWN in the connected slot.
      If I have no answer to the above sent frame, I retransmit it. But in the retranmission (in the same slot as above) the RTS signal is put down before all the data have been retransmitted.

      The up and down of the signal is done with the method "setRequestToSend".

      This is the code the mos relevant related code:

      Port configuration
      if(mSerialPort->open(QIODevice::ReadWrite)){
      currentTxId = 0;
      mSerialPort->setBaudRate(QSerialPort::Baud115200);
      mSerialPort->setDataBits(QSerialPort::Data8);
      mSerialPort->setFlowControl(QSerialPort::NoFlowControl);
      mSerialPort->setStopBits(QSerialPort::OneStop);
      mSerialPort->setParity(QSerialPort::NoParity);

          mSerialPort->setDataTerminalReady(true);       
      
          bool rtsUP = mSerialPort->isRequestToSend();
          mSerialPort->setRequestToSend(!rtsUP);
      
         connect(mSerialPort, SIGNAL(readyRead()), this, SLOT(onDataAvailable()));
         connect(mSerialPort, SIGNAL(bytesWritten(qint64)), this, SLOT(onBytesWritten(qint64)));
      

      }

      Send Data and RTS Up
      bool AppProtocolHandler::sendFrameWithACK(const QByteArray frame)
      {
      QByteArray txframe = frame;
      txframe.push_front(flag_STX);
      txframe.push_front(flag_DLE);
      txframe.push_back(flag_DEL);
      txframe.push_back(flag_ETX);

       //Start frame retransmission Timer
      m_txTimer->start(FRAME_RETRANSMISION_TIME);
      
      bool rtsUP = mSerialPort->isRequestToSend();
      if (rtsUP){
          mSerialPort->setRequestToSend(false);
      }
      
      qint64 frameLenght = static_cast<qint64> (frame.at(0));
      qint64 txlen = mSerialPort->write(txframe, frameLenght);
      
      if (mSerialPort->waitForBytesWritten(500)){
          m_txframe = frame;
          m_pendingFrames.insert(static_cast<int>(txframe.at(5)), static_cast<t_prot_cmd>(txframe.at(6)));
           return true;
      }
      else
      {
          qDebug()<< "AppProtocolHandler::sendFrameWithACK waitForBytesWritten(500) = FALSE";
          mSerialPort->setRequestToSend(true);
          return false;
      }
      

      }

      End Send Data and RTS Down
      void AppProtocolHandler::onBytesWritten(qint64 nBytes)
      {
      qint64 frameLenght = static_cast<qint64> (m_txframe.at(0));

      if (nBytes == frameLenght)
      {
          bool rtsUP = mSerialPort->isRequestToSend();
          if (!rtsUP){
              mSerialPort->setRequestToSend(true);
          }
      }
      

      }

      Any help or experience would be appreciated.
      Thanks!!

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

      Hi @iaguirre,

      on which platform are you?

      I guess your problem is most likely, that onBytesWritten is called when QSerialPort has written the data to the operating system (which has it's own buffers), but that does not mean the data is actually (completely) written on the serial line (and therefore not completely received from the other side).

      We had a problem like this some month ago, where a Linux flush call helped; I just don't find it now :(

      In any case, this will mean you have to block your program so it should preferable be done in a thread.

      Edit: found it: https://forum.qt.io/topic/83399/qtserialport-blocking-write-in-raspberry-pi-raspbian-pixel

      Qt has to stay free or it will die.

      1 Reply Last reply
      2
      • I Offline
        I Offline
        iaguirre
        wrote on last edited by
        #3

        We are running the program on Linux.

        When you say Linux flush call, you mean QtSerialPort flush method?

        Thanks again.

        aha_1980A 1 Reply Last reply
        0
        • I iaguirre

          We are running the program on Linux.

          When you say Linux flush call, you mean QtSerialPort flush method?

          Thanks again.

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

          Hi @iaguirre,

          We are running the program on Linux.

          Good. The solution I have for you is not portable...

          When you say Linux flush call, you mean QtSerialPort flush method?

          The guy in the other thread cleared both the QtSerialPort (with flush) and Kernel buffers (with tcdrain) and it worked for him. Please see: https://forum.qt.io/topic/83399/qtserialport-blocking-write-in-raspberry-pi-raspbian-pixel/7

          As said, keep in mind that it will block your program for the time it takes to write the bytes.

          Qt has to stay free or it will die.

          1 Reply Last reply
          1
          • I Offline
            I Offline
            iaguirre
            wrote on last edited by
            #5

            Thanks for your answer.
            It doesn´t work for me.

            aha_1980A 1 Reply Last reply
            0
            • I iaguirre

              Thanks for your answer.
              It doesn´t work for me.

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

              Hi @iaguirre,

              How did you implement it?
              How did you check that it does not work as expected?

              Qt has to stay free or it will die.

              I 1 Reply Last reply
              0
              • aha_1980A aha_1980

                Hi @iaguirre,

                How did you implement it?
                How did you check that it does not work as expected?

                I Offline
                I Offline
                iaguirre
                wrote on last edited by
                #7

                Hi again.

                The best solution has been to enable RTS after open the port, following the instructions readed here:
                https://github.com/torvalds/linux/blob/master/Documentation/serial/serial-rs485.txt

                You should verify if your linux kernel driver supports it.

                Regards

                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