Help needed in converting 2 8 bit data into 16 bit
-
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 .
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
- The way i convert my 2 8 bit data into 16bit
- 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.
-
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 .
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
- The way i convert my 2 8 bit data into 16bit
- 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.
@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.
-
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 .
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
- The way i convert my 2 8 bit data into 16bit
- 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.
@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 -
@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. -
@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.@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.
-
@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.@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