Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Help needed in converting 2 8 bit data into 16 bit

Help needed in converting 2 8 bit data into 16 bit

Scheduled Pinned Locked Moved Unsolved Mobile and Embedded
6 Posts 4 Posters 520 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.
  • V Offline
    V Offline
    Vignesh R
    wrote on 7 May 2024, 02:19 last edited by
    #1

    Hello everyone,
    I am currently working on a project where I transmit data using serial communication via a raspberry Pi Pico. The data that I am primarily transmitting is acceleration and roughly lies in the range of -50 .00to +50.00( the decimal value is also need). What I have done is that I multiply these floating point values by 100 (which in essence converts it into a interger).Which I split into 2 8 bit part and store it in a struct. Eg. the sensor reading is save -34.12. I multiply by 100 get 3412. Split it into 2 parts and store it in a struct. I transmit all this data stored in the struct . I have attached the struct that I am transmitting below.

    struct SensorData{
    
        uint8_t T1 ;
        uint8_t T2 ;
        uint8_t T3 ;
    
    
        uint8_t  B0AccXMSB ;  // MSB of Acceleration obtained from sensor 0
        uint8_t  B0AccXLSB ;    // LSB of Acceleration obtained from sensor 0
        uint8_t  B0AccYMSB ;
        uint8_t  B0AccYLSB ;
        uint8_t  B0AccZMSB ;
        uint8_t  B0AccZLSB ;
    
    };
    

    The reason I split all the values into 2 part ( i.e the Most significant byte and least significant bytes) is I can transmitting more that 8 bits at a time via serial communication. So split it into 2 parts.

    The problem I am having is in converting this back these 2 8 bit values to a signed 16(or 32, i just want my value back) bit value.

    My attempt at this was

        AccX = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccXMSB) << 8) | static_cast<uint16_t>(temp.B0AccXLSB));
    

    What happens is that for the majority of the time this code works fine but sometimes it fails. It is hard to explain in words so I am attaching an image of what is happening .
    3b7fea55-fff6-4c74-a099-3193fc531502-image.png

    As you can see at certain intervals like 0 -200 , 500-700 it flat lines. This should not happen the data is noisy and it should have a sinusoidal pattern.

    I did my own debugging and I was able to at least ascertain that there is data packet loss and it has no errors in it. My guess is that my fault lies in

    1. The way i convert my 2 8 bit data into 16bit
    2. The way I receive the serial data.
      Where am I going wrong
      I am attaching a snippet of my code below
    //function to get the data from serial port
    void MainWindow::readData()
    {
        while(COMPORT->bytesAvailable())
        {
            data = COMPORT->readAll();
            memcpy(&temp,data, sizeof(temp));
    
            if( FirstVal <= 4 ) // Eliminate first 5 values as they are errorneous
            {
                FirstVal++;
            }
            if( FirstVal >= 5 )
            {
                emit NewDataRecieved();
            }
        }
    }
    
    
    void MainWindow::ParseAcc()
    {
    
        AccX = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccXMSB) << 8) | static_cast<uint16_t>(temp.B0AccXLSB));
        AccY = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccYMSB) << 8) | static_cast<uint16_t>(temp.B0AccYLSB));
        AccZ = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccZMSB) << 8) | static_cast<uint16_t>(temp.B0AccZLSB));
    
           SensorData.B0AccX.append(AccX / 100.0);
           SensorData.B0AccY.append(AccY / 100.0);
           SensorData.B0AccZ.append(AccZ / 100.0);
    
    
    }
    

    Thanks in advance for the help.

    J J 2 Replies Last reply 7 May 2024, 05:42
    0
    • V Vignesh R
      7 May 2024, 02:19

      Hello everyone,
      I am currently working on a project where I transmit data using serial communication via a raspberry Pi Pico. The data that I am primarily transmitting is acceleration and roughly lies in the range of -50 .00to +50.00( the decimal value is also need). What I have done is that I multiply these floating point values by 100 (which in essence converts it into a interger).Which I split into 2 8 bit part and store it in a struct. Eg. the sensor reading is save -34.12. I multiply by 100 get 3412. Split it into 2 parts and store it in a struct. I transmit all this data stored in the struct . I have attached the struct that I am transmitting below.

      struct SensorData{
      
          uint8_t T1 ;
          uint8_t T2 ;
          uint8_t T3 ;
      
      
          uint8_t  B0AccXMSB ;  // MSB of Acceleration obtained from sensor 0
          uint8_t  B0AccXLSB ;    // LSB of Acceleration obtained from sensor 0
          uint8_t  B0AccYMSB ;
          uint8_t  B0AccYLSB ;
          uint8_t  B0AccZMSB ;
          uint8_t  B0AccZLSB ;
      
      };
      

      The reason I split all the values into 2 part ( i.e the Most significant byte and least significant bytes) is I can transmitting more that 8 bits at a time via serial communication. So split it into 2 parts.

      The problem I am having is in converting this back these 2 8 bit values to a signed 16(or 32, i just want my value back) bit value.

      My attempt at this was

          AccX = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccXMSB) << 8) | static_cast<uint16_t>(temp.B0AccXLSB));
      

      What happens is that for the majority of the time this code works fine but sometimes it fails. It is hard to explain in words so I am attaching an image of what is happening .
      3b7fea55-fff6-4c74-a099-3193fc531502-image.png

      As you can see at certain intervals like 0 -200 , 500-700 it flat lines. This should not happen the data is noisy and it should have a sinusoidal pattern.

      I did my own debugging and I was able to at least ascertain that there is data packet loss and it has no errors in it. My guess is that my fault lies in

      1. The way i convert my 2 8 bit data into 16bit
      2. The way I receive the serial data.
        Where am I going wrong
        I am attaching a snippet of my code below
      //function to get the data from serial port
      void MainWindow::readData()
      {
          while(COMPORT->bytesAvailable())
          {
              data = COMPORT->readAll();
              memcpy(&temp,data, sizeof(temp));
      
              if( FirstVal <= 4 ) // Eliminate first 5 values as they are errorneous
              {
                  FirstVal++;
              }
              if( FirstVal >= 5 )
              {
                  emit NewDataRecieved();
              }
          }
      }
      
      
      void MainWindow::ParseAcc()
      {
      
          AccX = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccXMSB) << 8) | static_cast<uint16_t>(temp.B0AccXLSB));
          AccY = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccYMSB) << 8) | static_cast<uint16_t>(temp.B0AccYLSB));
          AccZ = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccZMSB) << 8) | static_cast<uint16_t>(temp.B0AccZLSB));
      
             SensorData.B0AccX.append(AccX / 100.0);
             SensorData.B0AccY.append(AccY / 100.0);
             SensorData.B0AccZ.append(AccZ / 100.0);
      
      
      }
      

      Thanks in advance for the help.

      J Offline
      J Offline
      jsulm
      Lifetime Qt Champion
      wrote on 7 May 2024, 05:42 last edited by
      #2

      @Vignesh-R The problem could be that you're simply writing bytes into your SensorData - but SensorData is not packed! Either declare it as packed (#pragma pack (1)), or write a function to manually set the struct fields from the binary data.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      3
      • V Vignesh R
        7 May 2024, 02:19

        Hello everyone,
        I am currently working on a project where I transmit data using serial communication via a raspberry Pi Pico. The data that I am primarily transmitting is acceleration and roughly lies in the range of -50 .00to +50.00( the decimal value is also need). What I have done is that I multiply these floating point values by 100 (which in essence converts it into a interger).Which I split into 2 8 bit part and store it in a struct. Eg. the sensor reading is save -34.12. I multiply by 100 get 3412. Split it into 2 parts and store it in a struct. I transmit all this data stored in the struct . I have attached the struct that I am transmitting below.

        struct SensorData{
        
            uint8_t T1 ;
            uint8_t T2 ;
            uint8_t T3 ;
        
        
            uint8_t  B0AccXMSB ;  // MSB of Acceleration obtained from sensor 0
            uint8_t  B0AccXLSB ;    // LSB of Acceleration obtained from sensor 0
            uint8_t  B0AccYMSB ;
            uint8_t  B0AccYLSB ;
            uint8_t  B0AccZMSB ;
            uint8_t  B0AccZLSB ;
        
        };
        

        The reason I split all the values into 2 part ( i.e the Most significant byte and least significant bytes) is I can transmitting more that 8 bits at a time via serial communication. So split it into 2 parts.

        The problem I am having is in converting this back these 2 8 bit values to a signed 16(or 32, i just want my value back) bit value.

        My attempt at this was

            AccX = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccXMSB) << 8) | static_cast<uint16_t>(temp.B0AccXLSB));
        

        What happens is that for the majority of the time this code works fine but sometimes it fails. It is hard to explain in words so I am attaching an image of what is happening .
        3b7fea55-fff6-4c74-a099-3193fc531502-image.png

        As you can see at certain intervals like 0 -200 , 500-700 it flat lines. This should not happen the data is noisy and it should have a sinusoidal pattern.

        I did my own debugging and I was able to at least ascertain that there is data packet loss and it has no errors in it. My guess is that my fault lies in

        1. The way i convert my 2 8 bit data into 16bit
        2. The way I receive the serial data.
          Where am I going wrong
          I am attaching a snippet of my code below
        //function to get the data from serial port
        void MainWindow::readData()
        {
            while(COMPORT->bytesAvailable())
            {
                data = COMPORT->readAll();
                memcpy(&temp,data, sizeof(temp));
        
                if( FirstVal <= 4 ) // Eliminate first 5 values as they are errorneous
                {
                    FirstVal++;
                }
                if( FirstVal >= 5 )
                {
                    emit NewDataRecieved();
                }
            }
        }
        
        
        void MainWindow::ParseAcc()
        {
        
            AccX = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccXMSB) << 8) | static_cast<uint16_t>(temp.B0AccXLSB));
            AccY = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccYMSB) << 8) | static_cast<uint16_t>(temp.B0AccYLSB));
            AccZ = static_cast<int16_t>((static_cast<uint16_t>(temp.B0AccZMSB) << 8) | static_cast<uint16_t>(temp.B0AccZLSB));
        
               SensorData.B0AccX.append(AccX / 100.0);
               SensorData.B0AccY.append(AccY / 100.0);
               SensorData.B0AccZ.append(AccZ / 100.0);
        
        
        }
        

        Thanks in advance for the help.

        J Offline
        J Offline
        J.Hilk
        Moderators
        wrote on 7 May 2024, 07:30 last edited by
        #3

        @Vignesh-R you're also not checking if you received all bytes. There is no guarantee that all bytes are available when readyRead is emitted. Make sure your data has the correct size and append the next data package if you don't


        Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


        Q: What's that?
        A: It's blue light.
        Q: What does it do?
        A: It turns blue.

        1 Reply Last reply
        2
        • V Offline
          V Offline
          Vignesh R
          wrote on 7 May 2024, 20:06 last edited by
          #4

          @jsulm I packed my struct after your suggestion. There is very little to no improvement. I still get the same result.

          Also to clarify a few things SensorData and temp are 2 different structs. And are defined as below.

          #pragma pack(1)
          typedef struct  {
          
              QVector<double>  Time      ;
              QVector<double>  B0AccX    ;
              QVector<double>  B0AccY    ;
              QVector<double>  B0AccZ    ;  
          
          } Sensor;
          
          #pragma pack(1)
          typedef  struct  {
              uint8_t T1 ;
              uint8_t T2 ;
              uint8_t T3 ;
          
              uint8_t  B0AccXMSB ;
              uint8_t  B0AccXLSB ;
              uint8_t  B0AccYMSB ;
              uint8_t  B0AccYLSB ;
              uint8_t  B0AccZMSB ;
              uint8_t  B0AccZLSB ;
          } Temp;
          

          I copy the data I received onto the strut temp ((which is defined as Temp temp)
          , parse it then store it in SensorData(which is defined as Sensor SensorData.

          Is it possible that the error lies in how I receive the data from serial port ?
          Also will logging these data into a text file cause issues? I am asking this because is am plotting these values from a text file.

          M J 2 Replies Last reply 7 May 2024, 20:54
          0
          • V Vignesh R
            7 May 2024, 20:06

            @jsulm I packed my struct after your suggestion. There is very little to no improvement. I still get the same result.

            Also to clarify a few things SensorData and temp are 2 different structs. And are defined as below.

            #pragma pack(1)
            typedef struct  {
            
                QVector<double>  Time      ;
                QVector<double>  B0AccX    ;
                QVector<double>  B0AccY    ;
                QVector<double>  B0AccZ    ;  
            
            } Sensor;
            
            #pragma pack(1)
            typedef  struct  {
                uint8_t T1 ;
                uint8_t T2 ;
                uint8_t T3 ;
            
                uint8_t  B0AccXMSB ;
                uint8_t  B0AccXLSB ;
                uint8_t  B0AccYMSB ;
                uint8_t  B0AccYLSB ;
                uint8_t  B0AccZMSB ;
                uint8_t  B0AccZLSB ;
            } Temp;
            

            I copy the data I received onto the strut temp ((which is defined as Temp temp)
            , parse it then store it in SensorData(which is defined as Sensor SensorData.

            Is it possible that the error lies in how I receive the data from serial port ?
            Also will logging these data into a text file cause issues? I am asking this because is am plotting these values from a text file.

            M Offline
            M Offline
            mpergand
            wrote on 7 May 2024, 20:54 last edited by
            #5

            @Vignesh-R said in Help needed in converting 2 8 bit data into 16 bit:

            Is it possible that the error lies in how I receive the data from serial port ?

            Hi,

            I think you should use the debugger to look how your struct data looks like in memory.

            1 Reply Last reply
            0
            • V Vignesh R
              7 May 2024, 20:06

              @jsulm I packed my struct after your suggestion. There is very little to no improvement. I still get the same result.

              Also to clarify a few things SensorData and temp are 2 different structs. And are defined as below.

              #pragma pack(1)
              typedef struct  {
              
                  QVector<double>  Time      ;
                  QVector<double>  B0AccX    ;
                  QVector<double>  B0AccY    ;
                  QVector<double>  B0AccZ    ;  
              
              } Sensor;
              
              #pragma pack(1)
              typedef  struct  {
                  uint8_t T1 ;
                  uint8_t T2 ;
                  uint8_t T3 ;
              
                  uint8_t  B0AccXMSB ;
                  uint8_t  B0AccXLSB ;
                  uint8_t  B0AccYMSB ;
                  uint8_t  B0AccYLSB ;
                  uint8_t  B0AccZMSB ;
                  uint8_t  B0AccZLSB ;
              } Temp;
              

              I copy the data I received onto the strut temp ((which is defined as Temp temp)
              , parse it then store it in SensorData(which is defined as Sensor SensorData.

              Is it possible that the error lies in how I receive the data from serial port ?
              Also will logging these data into a text file cause issues? I am asking this because is am plotting these values from a text file.

              J Offline
              J Offline
              jsulm
              Lifetime Qt Champion
              wrote on 8 May 2024, 06:45 last edited by
              #6

              @Vignesh-R said in Help needed in converting 2 8 bit data into 16 bit:

              Is it possible that the error lies in how I receive the data from serial port ?

              See post from @J-Hilk

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0

              6/6

              8 May 2024, 06:45

              • Login

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