How to implement receive buffer



  • Hi all,

    I am working with serial port. Device that is connected to my pc is sending data in idle state. That data is equal to 0x63.
    When I press a start button on that device new frame is generated and I can receive it in my Qt app.
    Frame starts with 0x01 0x01 0xFF and it is transmitted every few milliseconds.

    What is the best way to handle this data. First I need to detect this start frame and from that position I need to read few more bytes and send to GUI.

    regards



  • @zgembo Anyone has any suggestion?


  • Qt Champions 2018

    @zgembo

    And what is the problem? You already wrote:

    First I need to detect this start frame and from that position I need to read few more bytes and send to GUI.

    and that is exactly what you have to do. you can either peek() into QSerialPorts internal buffer, or readAll() and store the results in your own buffer.

    Just note, that the message comes in in parts and you may need multiple readyReadSignals until a complete message is arrived. And of course, you need to dismiss any incomplete message before the start sequence.

    Regards



  • @aha_1980 Yes I understand the logic but I not quite sure how to implement it.

    Do you have any example that may be of any help?

    Regards



  • Data comes like this:
    0x63;0x63;0x63;0x01;0x01;0xFF;six byres of data; 0x00 final byte; then repeat from 0x01;0x01;0xFF

    So I need to detect start frame, record data and end frame.



  • @zgembo have you check the source code of any of the Qt serial port examples? like serial terminal for instance



  • @pablo-j-rogina Yes I have, but I am having difficulties in detecting start frame 0x01;0x01;0xFF

    I have tried to use QByteArrayMatcher with QByteArray to detect start frame pattern but it is a little bit messy.


  • Qt Champions 2018

    @zgembo said in How to implement receive buffer:

    I have tried to use QByteArrayMatcher with QByteArray

    What's wrong with QByteArray::indexOf() ?


  • Qt Champions 2018

    Hi @zgembo,

    Here is a (absolutely untested, not even compiled) code snippet that could show you the direction:

    static QByteArray nextFrame(QByteArray &buffer)
    {
    	const QByteArray startOfFrame("\x01\0x01\xFF"); // SOF
    	enum { FrameSize = 10 };
    
    	const int pos = buffer.indexIn(startOfFrame);
    	if (pos < 0)
     		return QByteArray();
    
    	// delete everything before SOF
    	buffer.remove(0, pos);
    	if (buffer.size() < FrameSize) // frame is not complete
    		return;
    
    	// extract next frame from buffer
    	const QByteArray newFrame = buffer.left(0, FrameSize);
    	buffer.remove(0, FrameSize);
    	return newFrame;
    }
    
    // connect this slot to the QSerialPort::readRead signal
    void serialReadyRead()
    {
    	static QByteArray buffer;
    
    	buffer.append(m_serial.readAll());
    
    	QByteArray frame = nextFrame(buffer);
    	while (!frame.isEmpty) {
    		qDebug() << frame.toHex();
    		frame = nextFrame(buffer);
    	}
    }
    

    I hope you get the idea.

    Regards



  • @aha_1980 Thank you for your code snippet. I know that you did not even try to compile this code but I have some questions.
    I do not understand nextFrame function completely. You read a frame and then you try to detect position of the SOF block with indexOf function.
    I do not follow you after this part. If the buffer size is less than a frame size you return from the function, but what do you do if it is not?


  • Qt Champions 2018

    When an empty QByteArray is returned, the loop in serialReadyRead() is stopped.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.