Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Convert 2 bytes QByteArray read from serial port into a int
Forum Update on Monday, May 27th 2025

Convert 2 bytes QByteArray read from serial port into a int

Scheduled Pinned Locked Moved Unsolved General and Desktop
9 Posts 5 Posters 1.7k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    JorisC
    wrote on last edited by
    #1

    Dear all,

    I have read a lot about how to convert a QByteArray into a int but without success in my case... That's why I post on this topic

    First, I have an arduino (MEGA) code which send and int with seria.write() function. For that, I realize an "union"

    union INT{
      int value;
      byte stream[2];
    };
    
    INT my_int
    

    And I stream it ( my_int.value= 125) over serial port:

    void setup(){
    serial.begin(9600);
    my_int.value = 125;   //my_int.stream =[7D, 00]
    
    void loop(){
    
    for (int i = 0; i<2; i++){
     Serial.write(my_int.stream[i]);
    }
    
    }
    

    On Qt side, located in my computer, I receive correctly the byte stream thanks to QSerialPort and readAll() function. Then I store it in a QByteArray as mentionned in QIODevice Class.

    I have a serialport class (serialport.h & serialport.cpp). I have a slot called onReadData() which is triggered by &QSerialPort::readyRead() signal. This is the nominal way to do as explained in many tutorials about how to receive datas from serial port on QT.

    This slot looks like:

    void SerialPort::onReadData()
    {
    
        if(arduino->bytesAvailable()>0){        
    
            QByteArray incomingdata = arduino->readAll();           
           qDebug()<<"incomingdata  = " << incomingdata ;
           qDebug()<<"incomingdata in HEX format  = " << incomingdata.toHex();
    

    This is working well !

    1-qDebug() shows:  incomingdata = "}\x00" 
    2-qDebug() shows:  incomingdata in HEX format = "7d00" 
    

    My problems start NOW !
    From my QByteArray incomingdata, how can I get back my_int = 125 ?

    I believed a union function was possible but it's not the case with QObject
    I tried with QDatastream but without success. I have tried both BigEndian and LittleEndian Byteorder.

            QByteArray ba("7d00");
            QDataStream ds(ba);
            ds.setByteOrder(QDataStream::BigEndian);  //same fail with LittleEndian
            qint16 x
                    ds>>x;
            qDebug() << "x = "<< x;
    

    I also tried with memcpy method and i doesn't work ... In fact, I get a value but this is not 125...

            QByteArray ba("7d00");
            qint16  outIntVar;
            memcpy(&outIntVar, ba.data(), sizeof(qint16));
    

    So I hope someone can tell me how to do to reach my goal and also what I am doing wrong ...
    After succeeding in this step I will have a larger byte stream coming from my arduino with a bytes frame containing int and float.

    Thanks in advance for your help.

    Jo

    KroMignonK 1 Reply Last reply
    0
    • Kent-DorfmanK Offline
      Kent-DorfmanK Offline
      Kent-Dorfman
      wrote on last edited by Kent-Dorfman
      #2

      stuff to read up on...not just ask somoene to tell you how to do...

      data endian format
      native CPU word size
      sizeof(int) on each platform in question
      host byte order and network byte order

      and making the assumption that you will always be able to read exactly two bytes from the serial port is a bad idea. Data can arrive at any time, and in any quantity.

      1 Reply Last reply
      4
      • J JorisC

        Dear all,

        I have read a lot about how to convert a QByteArray into a int but without success in my case... That's why I post on this topic

        First, I have an arduino (MEGA) code which send and int with seria.write() function. For that, I realize an "union"

        union INT{
          int value;
          byte stream[2];
        };
        
        INT my_int
        

        And I stream it ( my_int.value= 125) over serial port:

        void setup(){
        serial.begin(9600);
        my_int.value = 125;   //my_int.stream =[7D, 00]
        
        void loop(){
        
        for (int i = 0; i<2; i++){
         Serial.write(my_int.stream[i]);
        }
        
        }
        

        On Qt side, located in my computer, I receive correctly the byte stream thanks to QSerialPort and readAll() function. Then I store it in a QByteArray as mentionned in QIODevice Class.

        I have a serialport class (serialport.h & serialport.cpp). I have a slot called onReadData() which is triggered by &QSerialPort::readyRead() signal. This is the nominal way to do as explained in many tutorials about how to receive datas from serial port on QT.

        This slot looks like:

        void SerialPort::onReadData()
        {
        
            if(arduino->bytesAvailable()>0){        
        
                QByteArray incomingdata = arduino->readAll();           
               qDebug()<<"incomingdata  = " << incomingdata ;
               qDebug()<<"incomingdata in HEX format  = " << incomingdata.toHex();
        

        This is working well !

        1-qDebug() shows:  incomingdata = "}\x00" 
        2-qDebug() shows:  incomingdata in HEX format = "7d00" 
        

        My problems start NOW !
        From my QByteArray incomingdata, how can I get back my_int = 125 ?

        I believed a union function was possible but it's not the case with QObject
        I tried with QDatastream but without success. I have tried both BigEndian and LittleEndian Byteorder.

                QByteArray ba("7d00");
                QDataStream ds(ba);
                ds.setByteOrder(QDataStream::BigEndian);  //same fail with LittleEndian
                qint16 x
                        ds>>x;
                qDebug() << "x = "<< x;
        

        I also tried with memcpy method and i doesn't work ... In fact, I get a value but this is not 125...

                QByteArray ba("7d00");
                qint16  outIntVar;
                memcpy(&outIntVar, ba.data(), sizeof(qint16));
        

        So I hope someone can tell me how to do to reach my goal and also what I am doing wrong ...
        After succeeding in this step I will have a larger byte stream coming from my arduino with a bytes frame containing int and float.

        Thanks in advance for your help.

        Jo

        KroMignonK Offline
        KroMignonK Offline
        KroMignon
        wrote on last edited by
        #3

        @JorisC said in Convert 2 bytes QByteArray read from serial port into a int:

        I believed a union function was possible but it's not the case with QObject

        First, you should know that int size depend on processor architecture.
        This means that for 16 bits processors, as on the Arduino board, int has 16 bits, but on you PC it will have 32bits!
        So this has nothing to do with Qt/QObject, this is processor/compiler specific.

        if you want it to work with any compiler, use short int, which will ever been 16 bits:

        union INT{
          short int value;
          byte stream[2];
        };
        

        Second: byte order may vary according to CPU architecture ==> cf. https://en.wikipedia.org/wiki/Endianness

        Third, a serial port is an asynchronous stream. When QSerialPort fires an event, it only means that it have received data, but this does not mean all data sent by Arduino have been received, maybe they will come with some delay.
        Up to you to handle this on the right way, there are many example available around internet.

        It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

        jeremy_kJ 1 Reply Last reply
        3
        • KroMignonK KroMignon

          @JorisC said in Convert 2 bytes QByteArray read from serial port into a int:

          I believed a union function was possible but it's not the case with QObject

          First, you should know that int size depend on processor architecture.
          This means that for 16 bits processors, as on the Arduino board, int has 16 bits, but on you PC it will have 32bits!
          So this has nothing to do with Qt/QObject, this is processor/compiler specific.

          if you want it to work with any compiler, use short int, which will ever been 16 bits:

          union INT{
            short int value;
            byte stream[2];
          };
          

          Second: byte order may vary according to CPU architecture ==> cf. https://en.wikipedia.org/wiki/Endianness

          Third, a serial port is an asynchronous stream. When QSerialPort fires an event, it only means that it have received data, but this does not mean all data sent by Arduino have been received, maybe they will come with some delay.
          Up to you to handle this on the right way, there are many example available around internet.

          jeremy_kJ Offline
          jeremy_kJ Offline
          jeremy_k
          wrote on last edited by
          #4

          @KroMignon said in Convert 2 bytes QByteArray read from serial port into a int:

          @JorisC said in Convert 2 bytes QByteArray read from serial port into a int:

          I believed a union function was possible but it's not the case with QObject

          What is a union function?

          First, you should know that int size depend on processor architecture.
          This means that for 16 bits processors, as on the Arduino board, int has 16 bits, but on you PC it will have 32bits!
          So this has nothing to do with Qt/QObject, this is processor/compiler specific.

          if you want it to work with any compiler, use short int, which will ever been 16 bits:

          A short int is at least 16 bits wide. It could be larger with a standard compliant compiler. In general, the integer types that don't explicitly specify a size have minimum but not maximum allowed widths.
          If the goal is exactly 16 bits, use int16_t or uint16_t (if available...)

          https://en.cppreference.com/w/cpp/language/types
          https://en.cppreference.com/w/cpp/types/integer

          Asking a question about code? http://eel.is/iso-c++/testcase/

          KroMignonK 1 Reply Last reply
          0
          • jeremy_kJ jeremy_k

            @KroMignon said in Convert 2 bytes QByteArray read from serial port into a int:

            @JorisC said in Convert 2 bytes QByteArray read from serial port into a int:

            I believed a union function was possible but it's not the case with QObject

            What is a union function?

            First, you should know that int size depend on processor architecture.
            This means that for 16 bits processors, as on the Arduino board, int has 16 bits, but on you PC it will have 32bits!
            So this has nothing to do with Qt/QObject, this is processor/compiler specific.

            if you want it to work with any compiler, use short int, which will ever been 16 bits:

            A short int is at least 16 bits wide. It could be larger with a standard compliant compiler. In general, the integer types that don't explicitly specify a size have minimum but not maximum allowed widths.
            If the goal is exactly 16 bits, use int16_t or uint16_t (if available...)

            https://en.cppreference.com/w/cpp/language/types
            https://en.cppreference.com/w/cpp/types/integer

            KroMignonK Offline
            KroMignonK Offline
            KroMignon
            wrote on last edited by
            #5

            @jeremy_k said in Convert 2 bytes QByteArray read from serial port into a int:

            A short int is at least 16 bits wide. It could be larger with a standard compliant compiler. In general, the integer types that don't explicitly specify a size have minimum but not maximum allowed widths.
            If the goal is exactly 16 bits, use int16_t or uint16_t (if available...)

            Yes, your are right, short int size may change but this implies that you setup your compiler to do it so.
            As you can see on the first link you give, for all compiler short int is 16 bits wide per default. ;)

            It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

            1 Reply Last reply
            0
            • J Offline
              J Offline
              JorisC
              wrote on last edited by
              #6

              Thanks to all for your time,

              I fully agree with what you told about int size and endianess problematic. I will set my int as uint16.
              I also can manage the serial reception in order to get the entire bytes stream.

              The question, if I refrase, is:
              What is the best way and best practice in Qt to convert the entire 2 byte stream representing my int (125) into this qint16 value.. Qdatastream? Memcpy?

              Christian EhrlicherC KroMignonK Kent-DorfmanK 3 Replies Last reply
              0
              • J JorisC

                Thanks to all for your time,

                I fully agree with what you told about int size and endianess problematic. I will set my int as uint16.
                I also can manage the serial reception in order to get the entire bytes stream.

                The question, if I refrase, is:
                What is the best way and best practice in Qt to convert the entire 2 byte stream representing my int (125) into this qint16 value.. Qdatastream? Memcpy?

                Christian EhrlicherC Offline
                Christian EhrlicherC Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on last edited by
                #7

                @JorisC This depends on the endianess of the data and your os.
                I would use boost::endian::big_to_native / little_to_native: https://www.boost.org/doc/libs/1_72_0/libs/endian/doc/html/endian.html#conversion_byte_reversal_functions

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                1
                • J JorisC

                  Thanks to all for your time,

                  I fully agree with what you told about int size and endianess problematic. I will set my int as uint16.
                  I also can manage the serial reception in order to get the entire bytes stream.

                  The question, if I refrase, is:
                  What is the best way and best practice in Qt to convert the entire 2 byte stream representing my int (125) into this qint16 value.. Qdatastream? Memcpy?

                  KroMignonK Offline
                  KroMignonK Offline
                  KroMignon
                  wrote on last edited by
                  #8

                  @JorisC said in Convert 2 bytes QByteArray read from serial port into a int:

                  What is the best way and best practice in Qt to convert the entire 2 byte stream representing my int (125) into this qint16 value.. Qdatastream? Memcpy?

                  "Best way" is always a little bit relative, in terms of performances, less lines of code or easy to understand...

                  As you will get the data in to QByteArray on Qt side, I think is to use qFromBigEndian<>() (cf. https://doc.qt.io/qt-5/qtendian.html#qFromBigEndian-1)
                  For example: ` value = qFromBigEndian<quint16>(ba);

                  It is an old maxim of mine that when you have excluded the impossible, whatever remains, however improbable, must be the truth. (Sherlock Holmes)

                  1 Reply Last reply
                  1
                  • J JorisC

                    Thanks to all for your time,

                    I fully agree with what you told about int size and endianess problematic. I will set my int as uint16.
                    I also can manage the serial reception in order to get the entire bytes stream.

                    The question, if I refrase, is:
                    What is the best way and best practice in Qt to convert the entire 2 byte stream representing my int (125) into this qint16 value.. Qdatastream? Memcpy?

                    Kent-DorfmanK Offline
                    Kent-DorfmanK Offline
                    Kent-Dorfman
                    wrote on last edited by Kent-Dorfman
                    #9

                    @JorisC said in Convert 2 bytes QByteArray read from serial port into a int:

                    The question, if I refrase, is:
                    What is the best way and best practice in Qt to convert the entire 2 byte stream representing my int (125) into this qint16 value.. Qdatastream? Memcpy?

                    assuming the following restriction:
                    specified and enforced little endian short int of 16 bits on both ends

                    I prefer
                    int v = 0;
                    memcpy(&v, &buffer[0], sizeof(short int));

                    or
                    v = buffer[0] | (buffer[1] << 8);
                    and it would be safer to explicitly cast the types of buffer[n] to avoid problems with upcasting and bit operations...but my example is lazy.

                    frame checking needs to be done on serial stream, either through inserting STX,ETX characters around the values, and/or, building in fixed and detectable idle periods between sending of values.

                    1 Reply Last reply
                    0

                    • Login

                    • Login or register to search.
                    • First post
                      Last post
                    0
                    • Categories
                    • Recent
                    • Tags
                    • Popular
                    • Users
                    • Groups
                    • Search
                    • Get Qt Extensions
                    • Unsolved