Results 1 to 6 of 6

Thread: Assigning quint16_t to QByteArray while sending serial data frame from PC to device

  1. #1
    Join Date
    Jan 2021
    Posts
    20
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Assigning quint16_t to QByteArray while sending serial data frame from PC to device

    Hi,

    My structure contains a variable of type quint16_t and before sending to a device through serial port, I am appending it to a QByteArray. As QByteArray holds byte, I see only one byte is sent. Actually I want len field should hold 2 bytes.

    Qt Code:
    1. typedef struct x_hdr
    2. {
    3. ....
    4. quint16_t len;
    5. }x;
    6.  
    7.  
    8. void tx_msg_fun(QByteArray *tx_msg)
    9. {
    10. tx_msg->append(sizeof(x));
    11. }
    To copy to clipboard, switch view to plain text mode 

    serial data frame is : SOF (1 byte)| seq (1 byte) | len (2 bytes) [holds length of data] | payload (n bytes)| chksum (2 bytes) | eof (1 byte)

    When I send this, only one byte is allocated for len & chksum field.
    How can append 2 bytes in the serial frame. Could someone help me on this ?

    Best Regards,
    Anita
    Last edited by d_stranz; 21st January 2021 at 21:40. Reason: missing [code] tags

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,844
    Thanks
    270
    Thanked 786 Times in 776 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Assigning quint16_t to QByteArray while sending serial data frame from PC to devi

    When I send this, only one byte is allocated for len & chksum field.
    If struct x_hdr's size is less than 256 bytes, then only one byte is needed to hold the size. I think you are confusing the sizes of the variables in the struct with the size of the struct itself. Just because one of the data members is 16 bits long, that adds only 2 bytes to sizeof( x ).

    If you need to write a 2-byte size to your buffer, then store sizeof( x ) in a quint16_t variable and write that variable out. Same thing for your checksum.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  3. #3
    Join Date
    Jan 2021
    Posts
    20
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Assigning quint16_t to QByteArray while sending serial data frame from PC to devi

    Quote Originally Posted by d_stranz View Post
    If struct x_hdr's size is less than 256 bytes, then only one byte is needed to hold the size. I think you are confusing the sizes of the variables in the struct with the size of the struct itself. Just because one of the data members is 16 bits long, that adds only 2 bytes to sizeof( x ).

    If you need to write a 2-byte size to your buffer, then store sizeof( x ) in a quint16_t variable and write that variable out. Same thing for your checksum.

    I am trying to explain briefly, with pseudo code

    serial data frame Format:

    --------------------------------------------------------------------------------------------------------------------
    (1 byte) | (1 byte) | (2 bytes) | (n bytes) | (2 bytes) | (1 byte)
    -------------------------------------------------------------------------------------------------------------------
    SOF | seq | len [holds length of payload] | payload | checksum | EOF
    ---------------------------------------------------------------------------------------------------------------------


    Qt Code:
    1. typedef struct x_hdr
    2. {
    3. uint16_t id;
    4. uint16_t type;
    5. } X_HDR;
    6.  
    7.  
    8. void MainWindow::build_msg (uint8_t seq, QByteArray *tx_msg)
    9. {
    10.  
    11. uint16_t checksum;
    12. X_HDR hdr;
    13.  
    14. switch(seq)
    15. {
    16. case 1:
    17.  
    18. /* update the command ID, 1byte long
    19.   tx_msg->append(seq);
    20.  
    21.   /* update data to frame */
    22. hdr.id = 0x1234;
    23. hdr.type = 0x0;
    24.  
    25.  
    26. /* update data len field, which is of 2bytes. as my struct is of 4 bytes, this field will be filled with a value 4*/
    27. tx_msg->append(sizeof(hdr));
    28.  
    29.  
    30. /* append data of nbytes, here in this case it's 4 bytes */
    31. tx_msg->append((char *) &hdr,sizeof(hdr));
    32.  
    33. break;
    34. }
    35.  
    36. /* Again checksum field is of 2 bytes long in the serial frame */
    37. checksum = add_chksum(&hdr, sizeof(hdr));
    38. tx_msg->append(checksum);
    39. }
    40.  
    41.  
    42. void MainWindow::button_pressed()
    43. {
    44. QByteArray command;
    45.  
    46. /* Appending SOF 0xAF (1 byte) to the serial frame */
    47. command.append(0xAF);
    48. build_msg (1,&command);
    49.  
    50. /*Appending EOF 0xFF (1 byte) to the serial frame */
    51. command.append(0xFF);
    52.  
    53. /* Function writes command to serial port */
    54. writeData(command);
    55. }
    To copy to clipboard, switch view to plain text mode 

    My question is How can I make sure irrespective of value in the "len" and "checksum", I want to allocate 2bytes for each fields in the serial frame.
    Is this possible with above approach? What needs to be corrected here.

    Best Regards,
    Anita
    Last edited by d_stranz; 22nd January 2021 at 18:06. Reason: missing [code] tags

  4. #4
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    4,844
    Thanks
    270
    Thanked 786 Times in 776 Posts
    Qt products
    Qt5
    Platforms
    Windows Android

    Default Re: Assigning quint16_t to QByteArray while sending serial data frame from PC to devi

    I have twice edited your posts in this thread to add CODE tags to your source code listings. Please use them for your future posts. See my signature below if you don't know how.

    My question is How can I make sure irrespective of value in the "len" and "checksum", I want to allocate 2bytes for each fields in the serial frame.
    I told you in my previous answer: Do not append "sizeof( hdr )", append a quint16_t variable which contains the sizeof( hdr ) value. sizeof() will return the smallest representation of the number of bytes in the argument (in your case 4 for "hdr"), which fits into a single byte, so a single byte is what gets appended. If you want 2 bytes to be appended, then you have to append a 2 byte variable.
    <=== The Great Pumpkin says ===>
    Please use CODE tags when posting source code so it is more readable. Click "Go Advanced" and then the "#" icon to insert the tags. Paste your code between them.

  5. #5
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,692
    Thanks
    13
    Thanked 1,599 Times in 1,527 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Assigning quint16_t to QByteArray while sending serial data frame from PC to devi

    There is no QByteArray function to append() anything other than chars (bytes).

    The sizeof(hdr) is a size_t with the value 4 (probably). size_t is variously defined, but must be at least 16-bits long and often an unsigned 32 or 64-bit integer.
    At line 27 you append a single char with the value stored in the size_t (it is an implied cast). One byte in the array is what you get. As a length value it will be broken if the hdr ever exceeds 255 bytes.

    If you want to write a multi-byte integer using only QByteArray then you need to code breaking it into bytes and appending them in the correct order (whichever way round that is). Something like:
    Qt Code:
    1. size_t hdrlen = sizeof(hdr);
    2. tx_msg->append(hdrlen & 0xff)
    3. hdrlen = hdrlen >> 8;
    4. tx_msg->append(hdrlen & 0xff)
    To copy to clipboard, switch view to plain text mode 
    or you can go this way (making the result platform architecture sensitive... your other code already is):
    Qt Code:
    1. uint16_t hdrlen = sizeof(hdr);
    2. tx_msg->append((char *) &hdrlen, sizeof(hdrlen));
    To copy to clipboard, switch view to plain text mode 

    You could also (carefully) use QDataStream.

  6. The following user says thank you to ChrisW67 for this useful post:

    d_stranz (23rd January 2021)

  7. #6
    Join Date
    Jan 2021
    Posts
    20
    Thanks
    1
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Assigning quint16_t to QByteArray while sending serial data frame from PC to devi

    Quote Originally Posted by ChrisW67 View Post
    There is no QByteArray function to append() anything other than chars (bytes).

    The sizeof(hdr) is a size_t with the value 4 (probably). size_t is variously defined, but must be at least 16-bits long and often an unsigned 32 or 64-bit integer.
    At line 27 you append a single char with the value stored in the size_t (it is an implied cast). One byte in the array is what you get. As a length value it will be broken if the hdr ever exceeds 255 bytes.

    If you want to write a multi-byte integer using only QByteArray then you need to code breaking it into bytes and appending them in the correct order (whichever way round that is). Something like:
    Qt Code:
    1. size_t hdrlen = sizeof(hdr);
    2. tx_msg->append(hdrlen & 0xff)
    3. hdrlen = hdrlen >> 8;
    4. tx_msg->append(hdrlen & 0xff)
    To copy to clipboard, switch view to plain text mode 
    or you can go this way (making the result platform architecture sensitive... your other code already is):
    Qt Code:
    1. uint16_t hdrlen = sizeof(hdr);
    2. tx_msg->append((char *) &hdrlen, sizeof(hdrlen));
    To copy to clipboard, switch view to plain text mode 

    You could also (carefully) use QDataStream.
    Thanks Chris. I could figure out the first approach mentioned above.

Similar Threads

  1. sending data in hex with QByteArray
    By QJak in forum Newbie
    Replies: 3
    Last Post: 17th April 2018, 17:31
  2. Sending serial data over ethernet
    By awpitt13 in forum Newbie
    Replies: 2
    Last Post: 27th February 2017, 14:06
  3. Problem sending data over to serial port
    By hovuquocan1997 in forum Qt Programming
    Replies: 6
    Last Post: 28th July 2015, 18:49
  4. How to interrupt serial port sending?
    By redkit_redkit in forum Qt Programming
    Replies: 3
    Last Post: 9th April 2014, 13:58
  5. Replies: 1
    Last Post: 5th December 2013, 07:46

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.