Qt - serial communication - receiving
-
I solved my problem by creating a slot for readyRead() signal. Solution/problem is described here:
-
I have next problem. When I was very short cable RS485 the frame was received all in one shot . now in long cable the frame recive is byte by bytes, so my code doesn't works.
Like I said I use slot "recive()" for readyRead() signal.void SerialWorker::recive() { QByteArray buffer_checksum; quint8 inByte; quint8 checksum_temp; int numByte = 0; int receiverStatus = RCV_ST_IDLE; Frame *m_inFrame = nullptr; int dataLength = 0; QByteArray receivedData = m_Serial->readAll(); qDebug()<<receivedData; while(receivedData.count() > 0) { ................... ................. } }How I should wait for all bytes in frame in my slot ?
-
I have next problem. When I was very short cable RS485 the frame was received all in one shot . now in long cable the frame recive is byte by bytes, so my code doesn't works.
Like I said I use slot "recive()" for readyRead() signal.void SerialWorker::recive() { QByteArray buffer_checksum; quint8 inByte; quint8 checksum_temp; int numByte = 0; int receiverStatus = RCV_ST_IDLE; Frame *m_inFrame = nullptr; int dataLength = 0; QByteArray receivedData = m_Serial->readAll(); qDebug()<<receivedData; while(receivedData.count() > 0) { ................... ................. } }How I should wait for all bytes in frame in my slot ?
@Damian7546 said in Qt - serial communication - receiving:
How I should wait for all bytes in frame in my slot ?
You must not wait but read the data into a custom buffer (e.g. QByteArray) and parse the data later on.
-
So, I changed my slot "recive()" in this way:
void SerialWorker::recive() { receivedData = receivedData + m_Serial->readAll(); if(!receivedData.isEmpty()) { timeoutReciveData(this, SLOT(parseRecivedData()), 1000); } }But something is wrong with singleshot , because doesn't work:
void SerialWorker::parseRecivedData() { qDebug() << receivedData ; /* parse should be here */ } void SerialWorker::timeoutReciveData(const QObject *obj, const char *signalOrSlot, int msDelay) { QTimer::singleShot(msDelay, obj, signalOrSlot); }Any idea ?
-
So, I changed my slot "recive()" in this way:
void SerialWorker::recive() { receivedData = receivedData + m_Serial->readAll(); if(!receivedData.isEmpty()) { timeoutReciveData(this, SLOT(parseRecivedData()), 1000); } }But something is wrong with singleshot , because doesn't work:
void SerialWorker::parseRecivedData() { qDebug() << receivedData ; /* parse should be here */ } void SerialWorker::timeoutReciveData(const QObject *obj, const char *signalOrSlot, int msDelay) { QTimer::singleShot(msDelay, obj, signalOrSlot); }Any idea ?
@Damian7546 said in Qt - serial communication - receiving:
But something is wrong with singleshot , because doesn't work:
does not work? What does this mean? Why do you not directly call parseRecivedData or QTimer::singleShot()?
-
This post is deleted!
-
@Damian7546 said in Qt - serial communication - receiving:
But something is wrong with singleshot , because doesn't work:
does not work? What does this mean? Why do you not directly call parseRecivedData or QTimer::singleShot()?
@Christian-Ehrlicher said in Qt - serial communication - receiving:
Why do you not directly call parseRecivedData
Because I do not know when my frame will be completed, so I give the some time by timeoutReciveData and next go to parseRecivedData().
I expect such a frame:
DevAddres,LengthFrame,Command,Data1...n,CRCH,CRCL@Christian-Ehrlicher said in Qt - serial communication - receiving:
does not work? What does this mean?
The parseRecivedData() slot does not start even though buffer "receivedData" are not empty .
-
@Christian-Ehrlicher said in Qt - serial communication - receiving:
Why do you not directly call parseRecivedData
Because I do not know when my frame will be completed, so I give the some time by timeoutReciveData and next go to parseRecivedData().
I expect such a frame:
DevAddres,LengthFrame,Command,Data1...n,CRCH,CRCL@Christian-Ehrlicher said in Qt - serial communication - receiving:
does not work? What does this mean?
The parseRecivedData() slot does not start even though buffer "receivedData" are not empty .
@Damian7546 said in Qt - serial communication - receiving:
Because I do not know when my frame will be completed, so I give the some time by timeoutReciveData and next go to parseRecivedData().
And why should it be finished in 1000ms? It does not help at all.
Parse your buffer directly. -
Ok,
thank for your suggestion. I must rewrite my parseRecivedData() function. -
I wrote again my "recive()" function like you said, it works, but I have several doubt.
void SerialWorker::recive() { QByteArray buff2CalcChecksum; Frame *m_inFrame = nullptr; receivedData_raw = receivedData_raw + m_Serial->readAll(); if(!receivedData_raw.isEmpty()) { for(int i=0; i < receivedData_raw.count(); i++) { buff2CalcChecksum = buff2CalcChecksum + receivedData_raw[i]; if ((((m_inFrame->CalculateCRC2_in(buff2CalcChecksum)) & 0xFF) == buff2CalcChecksum[i+2]) && (((m_inFrame->CalculateCRC2_in(buff2CalcChecksum) >> 8) & 0xFF) == buff2CalcChecksum[i+1])) { qDebug() << "We have the correct frame"; receivedData = receivedData_raw; receivedData_raw.clear(); parseRecivedData(); } if (receivedData_raw.count() > 20 ) receivedData_raw.clear(); /// it is not a good idea... } } }-
How to protect code when too long no CRC sums ?
-
It is a good idea that from first byte, calculate CRC sum to recognize my whole frame?
-
-
I don't think your code will ever work - the data comes in as a stream so you first have to figure out the start and end of your frame. For this a lot of protocols use a start and end-marker so you know when a frame starts and ends.
-
This protocol do not have marker start and end of frame. This is a frame:

-
Then I don't know how you will ever find the start of a frame... they must have at least e.g. an end marker ('\r' or '\n' for example) where you can start from.