Reciving data from barcode scanner
-
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\nfor each "line" if that is what it does), I would do elsewhere in the calling code, not in thereadyRead()slot. Maybeemit receivedDataLine()fromreceiveData()if/when it gets a "complete line" and is ready to parse.@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; } -
@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; }@Damian7546
This look about right.Personally I would do the
receivedFrame = receivedData.remove(receivedData.count()-2,2);in thereadyRead()slot next to where you look for the terminating\r\nas 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 ofreadyRead()itself it could be fired just once when multiple "lines" arrive. If you care about this possibility you would need to handle it. -
@Damian7546
This look about right.Personally I would do the
receivedFrame = receivedData.remove(receivedData.count()-2,2);in thereadyRead()slot next to where you look for the terminating\r\nas 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 ofreadyRead()itself it could be fired just once when multiple "lines" arrive. If you care about this possibility you would need to handle it.@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.
-
@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.
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?
-
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?
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.
-
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.
@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();?
UsingreadLine()I will have\r\nin recived buffor ? -
@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();?
UsingreadLine()I will have\r\nin recived buffor ?@Damian7546 said in Reciving data from barcode scanner:
Using readLine() I will have \r\n in recived buffor ?
Try it and see?
-
@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();?
UsingreadLine()I will have\r\nin recived buffor ?@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.
-
@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.
@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-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(); }@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?
-
D Damian7546 has marked this topic as solved on