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. Reciving data from barcode scanner
Forum Updated to NodeBB v4.3 + New Features

Reciving data from barcode scanner

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

    Hi,

    In qt I have simple receiving data from my barcode scanner.
    The received data is in format:
    "IR01XXXXXXXX\r\n"

    The receive() is my slot from readyread.

    I think that my parsing data in slot is not good:

    void ScannerSerialWorker::recive()
    {
        m_receivedDataTimeout = false;
        m_receivedDataTimeoutTimer.start(20);
        qDebug() << "raw recivedData: " << receivedData;
        while(m_Serial->bytesAvailable() && !m_receivedDataTimeout)
        {
           receivedData.append(m_Serial->readAll());
           if(receivedData.endsWith("\r\n") && receivedData.startsWith("IR01")) {
               receivedFrame = receivedData.remove(receivedData.count()-2,2);
    
               qDebug() << "Recived frame: " << receivedData.toHex();
               receivedData.clear();
               parseRecivedData();
               m_receivedDataTimeout = false;
               m_receivedDataTimeoutTimer.stop();
            }
        }
        if(m_receivedDataTimeout)
        {
            receivedData.clear();
            m_receivedDataTimeout = false;
            m_receivedDataTimeoutTimer.stop();
        }
    
    }
    
    

    And timeout is realized by:

    connect(&m_receivedDataTimeoutTimer, &QTimer::timeout, this, [&](){m_receivedDataTimeout = true;} );
    

    Someone can help me how write better function, more reliable ?

    JonBJ 1 Reply Last reply
    0
    • D Damian7546

      Hi,

      In qt I have simple receiving data from my barcode scanner.
      The received data is in format:
      "IR01XXXXXXXX\r\n"

      The receive() is my slot from readyread.

      I think that my parsing data in slot is not good:

      void ScannerSerialWorker::recive()
      {
          m_receivedDataTimeout = false;
          m_receivedDataTimeoutTimer.start(20);
          qDebug() << "raw recivedData: " << receivedData;
          while(m_Serial->bytesAvailable() && !m_receivedDataTimeout)
          {
             receivedData.append(m_Serial->readAll());
             if(receivedData.endsWith("\r\n") && receivedData.startsWith("IR01")) {
                 receivedFrame = receivedData.remove(receivedData.count()-2,2);
      
                 qDebug() << "Recived frame: " << receivedData.toHex();
                 receivedData.clear();
                 parseRecivedData();
                 m_receivedDataTimeout = false;
                 m_receivedDataTimeoutTimer.stop();
              }
          }
          if(m_receivedDataTimeout)
          {
              receivedData.clear();
              m_receivedDataTimeout = false;
              m_receivedDataTimeoutTimer.stop();
          }
      
      }
      
      

      And timeout is realized by:

      connect(&m_receivedDataTimeoutTimer, &QTimer::timeout, this, [&](){m_receivedDataTimeout = true;} );
      

      Someone can help me how write better function, more reliable ?

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

      @Damian7546
      Don't know what you mean by "more reliable".

      I wouldn't do the parsing inside the code which repeatedly reads from the serial port. UI would probably have that function emit a signal when a "line" has been received, and let something which handles that do the parsing then. Also have that deal with startsWith("IR01") rather than here. Similarly I wouldn't put a timeout in here. I don't even think that this code will allow the timer to tick to expire/timeout, did you see whether it actually even follows that route?

      D 1 Reply Last reply
      0
      • JonBJ JonB

        @Damian7546
        Don't know what you mean by "more reliable".

        I wouldn't do the parsing inside the code which repeatedly reads from the serial port. UI would probably have that function emit a signal when a "line" has been received, and let something which handles that do the parsing then. Also have that deal with startsWith("IR01") rather than here. Similarly I wouldn't put a timeout in here. I don't even think that this code will allow the timer to tick to expire/timeout, did you see whether it actually even follows that route?

        D Offline
        D Offline
        Damian7546
        wrote on last edited by
        #3

        @JonB said in Reciving data from barcode scanner:

        I wouldn't do the parsing inside the code which repeatedly reads from the serial port. UI would probably have that function emit a signal when a "line" has been received, and let something which handles that do the parsing then. Also have that deal with startsWith("IR01") rather than here. Similarly I wouldn't put a timeout in here. I don't even think that this code will allow the timer to tick to expire/timeout, did you see whether it actually even follows that route?

        How do you think the above code should appear? please for any example .

        JonBJ 1 Reply Last reply
        0
        • D Damian7546

          @JonB said in Reciving data from barcode scanner:

          I wouldn't do the parsing inside the code which repeatedly reads from the serial port. UI would probably have that function emit a signal when a "line" has been received, and let something which handles that do the parsing then. Also have that deal with startsWith("IR01") rather than here. Similarly I wouldn't put a timeout in here. I don't even think that this code will allow the timer to tick to expire/timeout, did you see whether it actually even follows that route?

          How do you think the above code should appear? please for any example .

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

          @Damian7546

          void ScannerSerialWorker::receiveData()
          {
                 receivedData.append(m_Serial->readAll());
                 if (receivedData.endsWith("\r\n")) {
                     receivedFrame = receivedData.remove(receivedData.count()-2,2);
          }
          

          Other stuff, like parsing and if you really need to do timeouts (you should not, the "protocol" of the received data from the barcode scanner should indicate this, e.g. by appending \r\n for each "line" if that is what it does), I would do elsewhere in the calling code, not in the readyRead() slot. Maybe emit receivedDataLine() from receiveData() if/when it gets a "complete line" and is ready to parse.

          D 1 Reply Last reply
          0
          • JonBJ JonB

            @Damian7546

            void ScannerSerialWorker::receiveData()
            {
                   receivedData.append(m_Serial->readAll());
                   if (receivedData.endsWith("\r\n")) {
                       receivedFrame = receivedData.remove(receivedData.count()-2,2);
            }
            

            Other stuff, like parsing and if you really need to do timeouts (you should not, the "protocol" of the received data from the barcode scanner should indicate this, e.g. by appending \r\n for each "line" if that is what it does), I would do elsewhere in the calling code, not in the readyRead() slot. Maybe emit receivedDataLine() from receiveData() if/when it gets a "complete line" and is ready to parse.

            D Offline
            D Offline
            Damian7546
            wrote on last edited by Damian7546
            #5

            @JonB and what do you think about below solution ?

            void ScannerSerialWorker::initSerialPort(QString port)
            {
                // Serial Port Initialization
                m_Serial = new QSerialPort(this);
                m_Serial->setPortName(port);
                m_Serial->setBaudRate(QSerialPort::Baud115200);
                m_Serial->setDataBits(QSerialPort::Data8);
                m_Serial->setParity(QSerialPort::NoParity);
                m_Serial->setStopBits(QSerialPort::OneStop);
                m_Serial->setFlowControl(QSerialPort::NoFlowControl);
            
                if ( m_Serial->open(QIODevice::ReadOnly)){
            
                    QObject::connect(m_Serial, &QSerialPort::readyRead, this, [&]() {
                        const QByteArray scannedData = m_Serial->readAll();
                        qDebug() << "Scanned data by scanner: " << scannedData;
            
                        receivedData.append(scannedData);
                        if(receivedData.endsWith("\r\n")) {
                            parseRecivedData();
                         }
                    });
                }
                qDebug() << "SerialPort for Barcode reader status: " << m_Serial->isOpen();
            }
            
            void ScannerSerialWorker::parseRecivedData()
            {
                ScannerFrame *m_inFrame = nullptr;
                if (m_inFrame == nullptr)
                    m_inFrame = new ScannerFrame();
            
                else{
                    m_inFrame->Clear();
                }
            
                receivedFrame = receivedData.remove(receivedData.count()-2,2);
                receivedData.clear();
            
                for (int i=receivedFrame.indexOf("IR01"); i< receivedFrame.count(); i++)
                    m_inFrame->AddByte(receivedFrame[i]);
            
                receivedData.clear();
            
                emit this->frameReceived(m_inFrame);
                delete m_inFrame;
            }
            
            JonBJ 1 Reply Last reply
            0
            • D Damian7546

              @JonB and what do you think about below solution ?

              void ScannerSerialWorker::initSerialPort(QString port)
              {
                  // Serial Port Initialization
                  m_Serial = new QSerialPort(this);
                  m_Serial->setPortName(port);
                  m_Serial->setBaudRate(QSerialPort::Baud115200);
                  m_Serial->setDataBits(QSerialPort::Data8);
                  m_Serial->setParity(QSerialPort::NoParity);
                  m_Serial->setStopBits(QSerialPort::OneStop);
                  m_Serial->setFlowControl(QSerialPort::NoFlowControl);
              
                  if ( m_Serial->open(QIODevice::ReadOnly)){
              
                      QObject::connect(m_Serial, &QSerialPort::readyRead, this, [&]() {
                          const QByteArray scannedData = m_Serial->readAll();
                          qDebug() << "Scanned data by scanner: " << scannedData;
              
                          receivedData.append(scannedData);
                          if(receivedData.endsWith("\r\n")) {
                              parseRecivedData();
                           }
                      });
                  }
                  qDebug() << "SerialPort for Barcode reader status: " << m_Serial->isOpen();
              }
              
              void ScannerSerialWorker::parseRecivedData()
              {
                  ScannerFrame *m_inFrame = nullptr;
                  if (m_inFrame == nullptr)
                      m_inFrame = new ScannerFrame();
              
                  else{
                      m_inFrame->Clear();
                  }
              
                  receivedFrame = receivedData.remove(receivedData.count()-2,2);
                  receivedData.clear();
              
                  for (int i=receivedFrame.indexOf("IR01"); i< receivedFrame.count(); i++)
                      m_inFrame->AddByte(receivedFrame[i]);
              
                  receivedData.clear();
              
                  emit this->frameReceived(m_inFrame);
                  delete m_inFrame;
              }
              
              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @Damian7546
              This look about right.

              Personally I would do the receivedFrame = receivedData.remove(receivedData.count()-2,2); in the readyRead() slot next to where you look for the terminating \r\n as they are linked.

              Your code assumes you will only get one "line" any time readyRead() is signalled. I don't know if that is guaranteed: in terms of readyRead() itself it could be fired just once when multiple "lines" arrive. If you care about this possibility you would need to handle it.

              Christian EhrlicherC 1 Reply Last reply
              0
              • JonBJ JonB

                @Damian7546
                This look about right.

                Personally I would do the receivedFrame = receivedData.remove(receivedData.count()-2,2); in the readyRead() slot next to where you look for the terminating \r\n as they are linked.

                Your code assumes you will only get one "line" any time readyRead() is signalled. I don't know if that is guaranteed: in terms of readyRead() itself it could be fired just once when multiple "lines" arrive. If you care about this possibility you would need to handle it.

                Christian EhrlicherC Online
                Christian EhrlicherC Online
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @JonB said in Reciving data from barcode scanner:

                if that is guaranteed

                No, it's not - it's a stream like any other stream too.

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

                D 1 Reply Last reply
                0
                • Christian EhrlicherC Christian Ehrlicher

                  @JonB said in Reciving data from barcode scanner:

                  if that is guaranteed

                  No, it's not - it's a stream like any other stream too.

                  D Offline
                  D Offline
                  Damian7546
                  wrote on last edited by Damian7546
                  #8

                  I gave up with :

                   receivedFrame = receivedData.remove(receivedData.count()-2,2);
                  

                  Now is my code:

                  void ScannerSerialWorker::initSerialPort(QString port)
                  {
                      // Serial Port Initialization
                      m_Serial = new QSerialPort(this);
                      m_Serial->setPortName(port);
                      m_Serial->setBaudRate(QSerialPort::Baud115200);
                      m_Serial->setDataBits(QSerialPort::Data8);
                      m_Serial->setParity(QSerialPort::NoParity);
                      m_Serial->setStopBits(QSerialPort::OneStop);
                      m_Serial->setFlowControl(QSerialPort::NoFlowControl);
                  
                      if ( m_Serial->open(QIODevice::ReadOnly)) {
                          QObject::connect(m_Serial, &QSerialPort::readyRead, this, [&]() {
                              const QByteArray scannedData = m_Serial->readAll();
                              qDebug() << "Scanned data by scanner (RAW): " << scannedData;
                  
                              receivedData.append(scannedData);
                              if(receivedData.contains("\r\n")) {
                                  parseRecivedData();
                                  qDebug() << "Scanned data by scanner: " << receivedData;
                               }
                          });
                      }
                      qDebug() << "SerialPort for Barcode reader status: " << m_Serial->isOpen();
                  }
                  
                  void ScannerSerialWorker::parseRecivedData()
                  {
                      ScannerFrame *m_inFrame = nullptr;
                      if (m_inFrame == nullptr)
                          m_inFrame = new ScannerFrame();
                  
                      else{
                          m_inFrame->Clear();
                      }
                  
                      for (int i=receivedData.indexOf("IR01"); i < receivedData.indexOf("\r\n", 3) ; i++)
                          m_inFrame->AddByte(receivedFrame[i]);
                  
                      receivedData.clear();
                  
                      emit this->frameReceived(m_inFrame);
                      delete m_inFrame;
                  }
                  

                  @JonB said in Reciving data from barcode scanner:

                  Your code assumes you will only get one "line" any time readyRead() is signalled.

                  ..so how do i fix my code?

                  Christian EhrlicherC 1 Reply Last reply
                  0
                  • D Damian7546

                    I gave up with :

                     receivedFrame = receivedData.remove(receivedData.count()-2,2);
                    

                    Now is my code:

                    void ScannerSerialWorker::initSerialPort(QString port)
                    {
                        // Serial Port Initialization
                        m_Serial = new QSerialPort(this);
                        m_Serial->setPortName(port);
                        m_Serial->setBaudRate(QSerialPort::Baud115200);
                        m_Serial->setDataBits(QSerialPort::Data8);
                        m_Serial->setParity(QSerialPort::NoParity);
                        m_Serial->setStopBits(QSerialPort::OneStop);
                        m_Serial->setFlowControl(QSerialPort::NoFlowControl);
                    
                        if ( m_Serial->open(QIODevice::ReadOnly)) {
                            QObject::connect(m_Serial, &QSerialPort::readyRead, this, [&]() {
                                const QByteArray scannedData = m_Serial->readAll();
                                qDebug() << "Scanned data by scanner (RAW): " << scannedData;
                    
                                receivedData.append(scannedData);
                                if(receivedData.contains("\r\n")) {
                                    parseRecivedData();
                                    qDebug() << "Scanned data by scanner: " << receivedData;
                                 }
                            });
                        }
                        qDebug() << "SerialPort for Barcode reader status: " << m_Serial->isOpen();
                    }
                    
                    void ScannerSerialWorker::parseRecivedData()
                    {
                        ScannerFrame *m_inFrame = nullptr;
                        if (m_inFrame == nullptr)
                            m_inFrame = new ScannerFrame();
                    
                        else{
                            m_inFrame->Clear();
                        }
                    
                        for (int i=receivedData.indexOf("IR01"); i < receivedData.indexOf("\r\n", 3) ; i++)
                            m_inFrame->AddByte(receivedFrame[i]);
                    
                        receivedData.clear();
                    
                        emit this->frameReceived(m_inFrame);
                        delete m_inFrame;
                    }
                    

                    @JonB said in Reciving data from barcode scanner:

                    Your code assumes you will only get one "line" any time readyRead() is signalled.

                    ..so how do i fix my code?

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

                    Why not simply use QIODevice::canReadLine() / readLine()? Your approach only reads the first line, ignores if there one more line or a part of it is available since it throws it away.

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

                    D 1 Reply Last reply
                    0
                    • Christian EhrlicherC Christian Ehrlicher

                      Why not simply use QIODevice::canReadLine() / readLine()? Your approach only reads the first line, ignores if there one more line or a part of it is available since it throws it away.

                      D Offline
                      D Offline
                      Damian7546
                      wrote on last edited by Damian7546
                      #10

                      @Christian-Ehrlicher so it's enough if I only change one line in my code:

                      const QByteArray scannedData = m_Serial->readAll();
                      

                      to

                      const QByteArray scannedData = m_Serial->readLine();
                      

                      ?
                      Using readLine() I will have \r\n in recived buffor ?

                      JonBJ Christian EhrlicherC 2 Replies Last reply
                      0
                      • D Damian7546

                        @Christian-Ehrlicher so it's enough if I only change one line in my code:

                        const QByteArray scannedData = m_Serial->readAll();
                        

                        to

                        const QByteArray scannedData = m_Serial->readLine();
                        

                        ?
                        Using readLine() I will have \r\n in recived buffor ?

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

                        @Damian7546 said in Reciving data from barcode scanner:

                        Using readLine() I will have \r\n in recived buffor ?

                        Try it and see?

                        1 Reply Last reply
                        0
                        • D Damian7546

                          @Christian-Ehrlicher so it's enough if I only change one line in my code:

                          const QByteArray scannedData = m_Serial->readAll();
                          

                          to

                          const QByteArray scannedData = m_Serial->readLine();
                          

                          ?
                          Using readLine() I will have \r\n in recived buffor ?

                          Christian EhrlicherC Online
                          Christian EhrlicherC Online
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on last edited by
                          #12

                          @Damian7546 said in Reciving data from barcode scanner:

                          to
                          const QByteArray scannedData = m_Serial->readLine();

                          ?

                          No, since there can be more than one line in your buffer. Wrap it in a canReadLine() call.

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

                          D 1 Reply Last reply
                          0
                          • Christian EhrlicherC Christian Ehrlicher

                            @Damian7546 said in Reciving data from barcode scanner:

                            to
                            const QByteArray scannedData = m_Serial->readLine();

                            ?

                            No, since there can be more than one line in your buffer. Wrap it in a canReadLine() call.

                            D Offline
                            D Offline
                            Damian7546
                            wrote on last edited by Damian7546
                            #13

                            @Christian-Ehrlicher Like below ?

                            void ScannerSerialWorker::initSerialPort(QString port)
                            {
                                // Serial Port Initialization
                                m_Serial = new QSerialPort(this);
                                m_Serial->setPortName(port);
                                m_Serial->setBaudRate(QSerialPort::Baud9600);
                                m_Serial->setDataBits(QSerialPort::Data8);
                                m_Serial->setParity(QSerialPort::NoParity);
                                m_Serial->setStopBits(QSerialPort::OneStop);
                                m_Serial->setFlowControl(QSerialPort::NoFlowControl);
                            
                                if ( m_Serial->open(QIODevice::ReadOnly)) {
                                    QObject::connect(m_Serial, &QSerialPort::readyRead, this, [&]() {
                            
                                        while (m_Serial->canReadLine()){
                                            const QByteArray scannedData = m_Serial->readLine();
                                            qDebug() << "Scanned data by scanner (RAW): " << scannedData;
                            
                                            receivedData.append(scannedData);
                                            if(receivedData.contains("\r\n"))
                                                parseRecivedData();
                                        }
                                    });
                                }
                                qDebug() << "SerialPort for Barcode reader status: " << m_Serial->isOpen();
                            }
                            
                            
                            Christian EhrlicherC 1 Reply Last reply
                            0
                            • D Damian7546

                              @Christian-Ehrlicher Like below ?

                              void ScannerSerialWorker::initSerialPort(QString port)
                              {
                                  // Serial Port Initialization
                                  m_Serial = new QSerialPort(this);
                                  m_Serial->setPortName(port);
                                  m_Serial->setBaudRate(QSerialPort::Baud9600);
                                  m_Serial->setDataBits(QSerialPort::Data8);
                                  m_Serial->setParity(QSerialPort::NoParity);
                                  m_Serial->setStopBits(QSerialPort::OneStop);
                                  m_Serial->setFlowControl(QSerialPort::NoFlowControl);
                              
                                  if ( m_Serial->open(QIODevice::ReadOnly)) {
                                      QObject::connect(m_Serial, &QSerialPort::readyRead, this, [&]() {
                              
                                          while (m_Serial->canReadLine()){
                                              const QByteArray scannedData = m_Serial->readLine();
                                              qDebug() << "Scanned data by scanner (RAW): " << scannedData;
                              
                                              receivedData.append(scannedData);
                                              if(receivedData.contains("\r\n"))
                                                  parseRecivedData();
                                          }
                                      });
                                  }
                                  qDebug() << "SerialPort for Barcode reader status: " << m_Serial->isOpen();
                              }
                              
                              
                              Christian EhrlicherC Online
                              Christian EhrlicherC Online
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on last edited by
                              #14

                              @Damian7546 said in Reciving data from barcode scanner:

                                          receivedData.append(scannedData);
                                          if(receivedData.contains("\r\n"))
                                              parseRecivedData();
                              

                              Why do you read it line by line just to append it to a QByteArray and split it again afterwards?

                              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
                              1
                              • D Damian7546 has marked this topic as solved on

                              • Login

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