Well, I am using this holiday in Brazil to improve my skills in C. I have learned how to use I2C and how to communicate with the MPU9255 (with help from this question). The last trouble I am facing is that the sensor is returning wrong values. The value returned is floating from 0 to 65000, but it is not linear.
I think that is because I am making some confusion on the data types or bytes merge on my code. Can someone help me revising my code?
uint8_t Test[] = "\n AccelX: \n";
HAL_UART_Transmit(&huart1,Test,sizeof(Test),100);
//SET X_HIGH REGISTER ADDRESS
i2cData = 0x3B;
HAL_I2C_Master_Transmit(&hi2c1, adressMPU, &i2cData, 1, 100);
//REQUEST 6 BYTES OF DATA (ACCEL X, Y AND Z)
HAL_I2C_Master_Receive(&hi2c1, adressMPU, receive_buffer, 6, 100);
AccelX = (char)receive_buffer[0]<<8 | (char)receive_buffer[1];
AccelY = (char)receive_buffer[2]<<8 | (char)receive_buffer[3];
AccelZ = (char)receive_buffer[4]<<8 | (char)receive_buffer[5];
//PRINTA NA SERIAL 1
len = sprintf(buffer, " %i\r\n", AccelX); //sprintf will return the length of 'buffer'
HAL_UART_Transmit(&huart1, (uint8_t *)buffer, len, 1000);
HAL_Delay(500);
Update:
I just noted one thing: from 0 to 16768, the sensor measurements are right, but when I upside the axis, the sensor goes from 65536 to ~49000 when should be from 0 to -16768. Surely is a conversion error, but I still not can see where exactly is the error.
Answer
The MPU-9255 is giving you a 16-bit, signed integer. Your code is interpreting it as unsigned.
An unsigned, 16-bit number can represent values from 0 to 65535. A signed 16-bit number represents -32768 to +32767.
Here is an 8-bit example from Wikipedia:
To make the conversion, first look at the high bit. If it is \$0\$, then no conversion is necessary. If it is \$1\$, then \$signed = (unsigned - 2^N)\$, where \$N\$ is the number of bits. Sixteen, in your case.
Here is a simple method for 16 bits:
uint16_t unsignedAccelX;
int16_t signedAccelX;
if (unsignedAccelX < 32768)
{
signedAccelX = unsignedAccelX;
}
else
{
signedAccelX = unsignedAccelX - 65536;
}
There are many more elegant and/or efficient ways of doing this. There is some discussion here.
Good luck!
No comments:
Post a Comment