Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Sending Packet through QSerialport ?



  • Here the task is ,sending packet through QSerialport and receiver has to receive with some calculations.

    The packet Format is :

    STX(1 byte,0xF0) +datalength(1 byte) +request code(2 bytes) +payload(0 - 100 or may vary dynamically) + ETX(1 byte,0xF1)

    the Function for transmitter is :

    void MainWindow::Txdata(quint16 request_code, quint8 data_leng)
    {

    const QByteArray payload = ui->textEdit->toPlainText().toUtf8();

    QByteArray send;
    send.append('0xF0');
    send.append(data_leng);
    send.append(request_code);
    send.append(payload);
    send.append('0xF1');

    m_pcSerialport->write(send);

    qDebug() <<"sending data:"<<send;

    }

    my code for transmitter side ,help me to complete this task.

    And receiver section :

    1. use the Circular Queue

    2. check for STX?

    3. check for minimum length?

    4. Calculate actual length?

    5. check for Full length(means checking for ETX)?

    6. start extraction?

    this is whole task? if any one help me if they worked previously or any kind of knowledge?

    I am trying to write receiver section code but i am stuck at transmitter section code only?


  • Lifetime Qt Champion

    Hi,

    By receiver section, do you mean the slot that you will connect to your m_pcSerialport readyRead signal ?



  • yes , i will connect to m_pcserialport to Rxdata() function.

    i want the logic of how to create circular queue in receiver section and how to check with conditions above i have mention?

    I have knowledge on FIFO first in first out .So,First is STX ,take that byte and check thh STX wheather it is received or not?


  • Lifetime Qt Champion

    @bhargav

    I would do as follow: you need a member QByteArray m_buf. inside the receive slot, append to it: m_buf+=port->readAll();

    • if m_buf contains STX, you can remove everything before, it is lost garbage
    • if m_buf contains STX and ETX, you can extract that part and parse it. keep everything after ETX, it may already be the next transmission
    • maybe do the checks above in a loop, in case m_buf contains more than one text.

    Regards



  • what about circular queue and how to use ?


  • Lifetime Qt Champion

    Why a circular buffer ? The technique described by @aha_1980 is the most simple yet effective.



  • my lead said use circular queue in receiver section ?

    without circular queue i know how to receive and check the conditions.

    by using circular queue how to extract byte by byte received data. i don't know?

    so ,if any one knowledge on this help me to code ?


  • Lifetime Qt Champion

    Ask him why imposing a circular buffer. I personnaly don’t see why you would need one in this case.



  • how to convert quint8 startbyte = 0xF0;

    to QByteArray ?


  • Lifetime Qt Champion

    @bhargav

    E.g. the same way you already used:

    QByteArray send;
    send.append('0xF0');

    Or use the constructor: QByteArray ba(1, char(startbyte));

    Regards



  • transmit data: "\xF0\x12\x96\x96krishnalkjkl;d\xF1"
    data size: "\xF0\x12\x96\x96kris"

    why my receiver is not receiving all data?

    receiver code:

    QByteArray data ;
    data = m_pcSerialport->readAll();

    qDebug() <<"data size:"<< data;
    

    tx code:

    QByteArray sending;

    QString str = ui->textEdit->toPlainText();
    
    QByteArray send = str.toUtf8();
    
    int size_packet_length = str.size();
    
    qDebug() << "size of payload:"<< size_packet_length;
    
    quint16 req_code = 0xFD96;
    char reqbytes[2];
    reqbytes[0] = (req_code >> 8) & 0xff;
    reqbytes[1] = req_code & 0xff;
    QByteArray 
    
    qDebug() <<"bytes of reqcode:"<<req;
    
    int size_reqcode = sizeof(req_code);
    
    qDebug() << "size of reqcode:"<< size_reqcode;
    
    
    quint8 startbyte = 0xF0;
    
    int size_startbyte = sizeof(startbyte);
    
    qDebug() << "size of startbyte:"<< size_startbyte;
    
    quint8 endbyte = 0xF1;
    
     int size_endbyte = sizeof(endbyte);
    
     qDebug() << "size of endbyte:"<< size_endbyte;
    
    
     int total_datalength = size_reqcode + size_startbyte + size_endbyte + size_packet_length;
    

    // QByteArray totallength = QByteArray::number(total_datalength);

     qDebug() << "size of total datalength:"<< total_datalength;
    
    sending.append(startbyte);
    sending.append(total_datalength);
    sending.append(req);
    sending.append(send);
    sending.append(endbyte);
    
    m_pcSerialport->write(sending,total_datalength);
    
    qDebug() << "transmit data:"<< sending;
    

    tell me why my receiver not receiving all data ?

    any mistakes if found in code suggest me to better?


  • Lifetime Qt Champion

    @bhargav

    Serial ports are slow, therefore your receive the answer in chunks.

    If you look at my answer above again, I said you need a member variable and you append to it.

    In your code you have a local variable, and you assign to it. That's why its not working for you :)

    Regards



  • my receiver code:

    QByteArray data ;
    data += m_pcSerialport->readAll();

     qDebug() <<"data size:"<< data;
     
    
     QByteArray received = data.toHex();
    
     qDebug()<<"testing :"<<received;
     
    
     for (int i = 0; i < received.size(); i++)
     {
        queue.enqueue(received[i]);
     }
    
     qDebug() <<"queue:"<<queue;
    

    how to compare queue with 0xF0(STX), 0xF1(ETX)? how to extract data or payload?


  • Lifetime Qt Champion

    Hi @bhargav,

    as you still insist using a queue, then you should ask the person who told you so.

    If you wanne go my way, I can surely help you, but if you want to go your way, you're on your own.

    Regards



  • ok sir ,

    QByteArray data;
    data +=m_pcserialport->readall();

    qDebug() <<"data received "<<data;

    /// after that i got output like this

    \xF0\x0E\xFD\x96haihelloeveryone\xF1

    from that i have to check the conditions above mention

    if(data == 0xF0)
    {
    qDebug()<<"STX is received ";
    }

    if(data == 0xF1)
    {
    qDebug()<<"ETX is received";
    }

    and how to extract data "haihelloeveryone"? from the received .

    help me code without Queue?


  • Lifetime Qt Champion

    @bhargav

    1. As said above, you need a member variable. data is local, appending to it does not make sense.
    2. I found out that you only need to check if both STX and ETX are in the frame, otherwise you exit the slot and just wait for more data come in (the slot will be
      called again).
    3. Note that parts of your protocol are not used yet (and maybe not needed?): data lenght and request code.
    void MainWindow::slotDataReceived(void)
    {
        m_buf += m_port->readAll();
    
        for (;;) {
            int posStx = m_buf.indexOf(char(0xF0));
            int posEtx = m_buf.indexOf(char(0xF1));
    
            if (posStx >= 0 && posEtx >= 0) {
                // extract payload
                QByteArray data = m_buf.mid(posStx + 4, posEtx - posStx - 4);
                // remove frame from receive buffer
                m_buf.remove(0, posEtx + 1);
                qDebug() << "Data =" << data;
            } else {
                break;
            }
        }
    }
    

    Regards


  • Qt Champions 2020

    @aha_1980 ,

    I admire for your patience. )))



  • thank you so much for your support.

    output of code:
    transmit data: "\xF0\x0F\xFD\x96hai krishna\xF1"
    data received : "\xF0\x0F\xFD\x96hai "
    data received : "krishna

    in receiver last byte is not receiving .so,it is not going to if condition for further operations.

    tnsmitter code:

    // sending through serialport
    sending.append(startbyte);
    sending.append(total_datalength);
    sending.append(req);
    sending.append(send);
    sending.append(endbyte);

     m_pcSerialport->write(sending,total_datalength);
    
     qDebug() << "transmit data:"<< sending;
    

    how to receive last byte?



  • hmm got it.



  • transmit data: "\xF0\x0B\xFD\x96krishna\xF1"
    data received : "\xF0\x0B\xFD\x96kris"
    for STX 0
    for ETX -1
    data received : "hna\xF1"
    for STX -1
    for ETX 3

    like this ,it fail to check the condition?


  • Lifetime Qt Champion

    Hi @bhargav

    Please show your receive slot code.

    Also, I thought a bit more about it and got questions you can ask yourself:

    1. What happens if size or function code contains the chars STX or ETX?
    2. In your send function, you convert a QString toUtf8(). Potentially there might be characters that map to STX or ETX too.

    Regards



  • my output is :
    Port is open: "Unknown error"
    size of payload: 23
    size of reqcode: 2
    size of startbyte: 1
    size of endbyte: 1
    size of total datalength: 27
    transmit data: "\xF0\x1B\xFD\x96krishnalkgkjhkjddhaksjd\xF1"
    data received : "\xF0\x1B\xFD\x96kris"
    data size : 8
    Minimum length is received
    received payload "kri"
    data received : "hnalkgk"
    data size : 7
    Minimum length is received
    both stx and etx recived
    received payload "krikg"
    data received : "jhkjddha"
    data size : 8
    Minimum length is received
    both stx and etx recived
    received payload "krikgddh"
    data received : "ksjd\xF1"
    data size : 5
    Minimum length is received
    both stx and etx recived
    received payload "krikgddh"

    my receiver code is:

    //just checking for bytes available
    if(m_pcSerialport->bytesAvailable() == 0 ) {

        qDebug() << "no data to Receive : bad signal?";
        return;
     }
    
    
    // reading data in serial port
     QByteArray m_buf;
    
    m_buf = m_pcSerialport->readAll();
    

    // char *buff;

    // int size = m_pcSerialport->bytesAvailable();

    // int byte = peek();

    // qDebug() <<"data received :"<< byte;

    qDebug() <<"data received :"<< m_buf;
    qDebug() <<"data size :"<< m_buf.size();
    
    
     // check for minimum length
     int minbytes = 3;
    
     if(m_buf.size() >= minbytes)
     {
         qDebug() << "Minimum length is received";
     }
    
     int stx = m_buf.indexOf(char(0xF0));
     int etx = m_buf.indexOf(char(0xF1));
    
    
    if(stx && etx) {
    
        qDebug() << "both stx and etx recived";
    }
    
     //   calc full len
     //   check full len data avail or not
    

    // if(etx)
    // {
    // qDebug() <<"full length is received";

    // qDebug() <<"full length:"<< m_buf.size();
    // }

     // Extracting the data to show in GUI
     for (int i = 4; i < m_buf.size() - 1; i++) {
    
         ba.append(m_buf[i]);
     }
    
      qDebug() <<"received payload"<< ba;
    
      ui->textEdit_2->setPlainText(ba);
    

    }

    how to calculate full packet length and extract payload to show in GUI?

    help me , i am getting payload in gui but some data is losing ? i want without loosing data i want to show in GUI.


  • Lifetime Qt Champion

    Hi @bhargav,

    please read my post with the example again.

    1. m_buf needs to be a member variable. (Why?)
    2. you need to append to m_buf. (Why?)

    Regards



  • thank you for your support ,just got the output.


Log in to reply