QSerialport in a thread lost the last String sended by a microcontroller
-
First, excuse me, the thread seems doubled but it is not, because the former, was not solved,now I use a new code that fix delays.
Hi, I'm trying to make a communication between a microcontroller and a Qt program.
When the Microcontroller read the string R00, responds with the next 23 strings (sent one by one, ending in '\n'):
c0+mA+yC+t199+i1F+B0+b1+nThe Name+gGenGroup+v10.1+f0.33+sR+\n
...
...
till 23 strings..
c21+mO+y7+t004+i7F+B5+b6+nJuan +gCircuito+v31.1+f1.33+sS+\n
c22+mA+y8+t308+i8F+B6+b7+nRamon +gGenGroup+v32.1+f2.33+sO+\nthe first three, are sent with 1 second delay, but the rest witout delay.
The problem is that the last string is not readed
please, any help will be wellcomed.
Here is my code: (I insist, the code is moved into a thread from MainWindow)
#ifndef SPORT_H #define SPORT_H #include <QDebug> //#include <Windows.h> #include <QtSerialPort/QSerialPort> #include <QtSerialPort/QSerialPortInfo> #define maxPort 41 #define baudRate CBR_19200 #define maxSB 256 #define askId "cb?" #define iDAck "cbr" #include <QThread> #include <string.h> class sport : public QObject { Q_OBJECT public: sport(); bool makeCnx(); bool exit = false; public slots: void updateMsg(QString newMsg); void run(); signals: void received(QString rcv); void conInf(QString cnxInfo); void finished(); private: // void read(); // void write(); QSerialPort serial; QStringList qWriteBuf; }; #endif // SPORT_H
#include "sport.h" #include<iostream> using namespace std; //sssssssssssssssssssssssssssssssssssssssssssssss void sport::updateMsg(QString newMsg){ //write here newMsg = newMsg + '\0'; qWriteBuf << newMsg; newMsg = ""; } //ssssssssssssssssssssssssssssssssssssssssssssEND sport::sport() { /// if (makeCnx()) run(); //das ist nicht klug } //************************************************ void sport::run(){ QString line = ""; QString s; while(!exit){ if(qWriteBuf.size() > 0){ foreach(const QString &output, qWriteBuf) { if (output != ""){ //qWriteBuf != "" string sWB = output.toStdString().c_str(); char cWB[maxSB]; qint8 in; in = 0; while(in < sWB.size()){ cWB[in] = sWB[in]; in++; } cWB[in] = '\0'; //char wbuf2[] = "R00"; serial.write(cWB); qDebug() << "Out Buff: " << cWB; } } //Del foreach qWriteBuf.clear(); } if (serial.waitForReadyRead(100)) { /* while(!line.endsWith("\n")){ s = serial.readLine(); line += s; } qDebug() << line; line = "";*/ qDebug() << "readyRead"; QString s = serial.readLine(); line += s; if (line.endsWith("\n")) { cerr << line.toStdString().c_str(); // qDebug() << "line:" << line; line = ""; } } // qDebug() << "Input Buff " << line; emit finished(); } //von while } //************************************************ bool sport::makeCnx(){ //serial = new QSerialPort; qint8 p = 0; while(p < maxPort){ QString portType = "COM"; QString port = portType + QString::number(p); serial.setPortName(port); if (serial.open(QIODevice::ReadWrite)){ qDebug() << port << " Open"; qDebug() << "Baud? " << serial.setBaudRate(QSerialPort::Baud19200); qDebug() << "Data bits? " << serial.setDataBits(QSerialPort::Data8); qDebug() << "Parity? " << serial.setParity(QSerialPort::NoParity); qDebug() << "Stop Bits? " << serial.setStopBits(QSerialPort::OneStop); serial.write(askId); if(serial.waitForReadyRead(1000)){ if (serial.readAll() == "cbr\n"){ qDebug() << endl << "Connected on " << port; return 1; } } else{ qDebug() << "time out"; serial.close(); return 0; } } else { qDebug() << port << " Not Ready"; } p++; } //From while qDebug() << "Click Box not connected"; return 0; }
-
Hi
it does read all the first 22 lines?
what if u only send 10 lines
will it then read only 9? -
Hi,
If I may, you should rather use QByteArray than QString, you are doing a lot of unneeded conversion and manipulation.
-
I would offer to @yczo to add
qDebug() << "Bytes to read:" << serial.bytesAvaiable();
after each:
if (serial.waitForReadyRead(100))
to understand, how it work, to exclude explosion of a brain... I think that @yczo will be surprised... Also, I would advise to read documentation on QIODevice::canReadLine(), QIODevice::readLine()... And to try to add canReadLine(), readLine() or readAll() after each waitForReadyRead(), and to see results. And only then, try to adopt the code to "how really it works", but not "how @yczo think it works".