# G measurement – uncorrect values

Home Forums Forums Technical Support for BerryIMU G measurement – uncorrect values

Viewing 3 posts - 1 through 3 (of 3 total)
• Author
Posts
• #5872
Sten-Helge
Participant

Hi there,
According to the datasheet and your tutorials – when the accelerometer is horizontal and at rest, the value for Z should hover around 1 G.
When using a sensitive level of ±8g, the raw value for Z should hover around 4,475.
My readings from the below code snippet gives;

….
Loop 20 Xraw = -588 Yraw = -34 Zraw = 5304
Loop 20 Xraw = -520 Yraw = -67 Zraw = 5374
Loop 20 Xraw = -599 Yraw = -84 Zraw = 5460
Loop 20 Xraw = -549 Yraw = -70 Zraw = 5441
Loop 20 Xraw = -549 Yraw = -92 Zraw = 5341
Loop 20 Xraw = -517 Yraw = -91 Zraw = 5406
Loop 20 Xraw = -527 Yraw = -70 Zraw = 5281
Loop 20 Xraw = -538 Yraw = -73 Zraw = 5382
….

which gives – converted to G;

….
Loop 20 X = -0.139 G Y = -0.029 G Z = 1.184 G
Loop 20 X = -0.128 G Y = -0.020 G Z = 1.197 G
Loop 20 X = -0.136 G Y = -0.027 G Z = 1.228 G
Loop 20 X = -0.137 G Y = -0.028 G Z = 1.225 G
Loop 20 X = -0.118 G Y = -0.025 G Z = 1.190 G
Loop 20 X = -0.126 G Y = -0.024 G Z = 1.214 G
Loop 20 X = -0.137 G Y = -0.026 G Z = 1.210 G
Loop 20 X = -0.128 G Y = -0.024 G Z = 1.216 G
….

See below the used code for this test;

``````
int mymillis()
{
struct timeval tv;
gettimeofday(&tv, NULL);
return (tv.tv_sec) * 1000 + (tv.tv_usec)/1000;
}
void  readBlock(uint8_t command, uint8_t size, uint8_t *data)
{
int result = i2c_smbus_read_i2c_block_data(file, command, size, data);
if (result != size)
{
printf("Failed to read block from I2C.");
exit(1);
}
}
{
if (ioctl(file, I2C_SLAVE, addr) < 0) {
printf("Failed to select I2C device.");
}
}
void writeAccReg(uint8_t reg, uint8_t value)
{
int result = i2c_smbus_write_byte_data(file, reg, value);
if (result == -1)
{
printf ("Failed to write byte to I2C Acc.");
exit(1);
}
}
void enableIMU()
{
char filename;
sprintf(filename, "/dev/i2c-%d", 1);
file = open(filename, O_RDWR);
if (file<0) {
printf("Unable to open I2C bus!");
exit(1);
}
// Enable accelerometer.
writeAccReg(CTRL_REG1_XM, 0b01100111); //  z,y,x axis enabled, continuos update,  100Hz data rate
//writeAccReg(CTRL_REG2_XM, 0b00100000); // +/- 16G full scale
writeAccReg(CTRL_REG2_XM, 0b00010000); // +/- 8G full scale
//writeAccReg(CTRL_REG2_XM, 0b00000000); //+/- 2G full scale
}
{
uint8_t block;
*a = (int16_t)(block | block << 8);
*(a+1) = (int16_t)(block | block << 8);
*(a+2) = (int16_t)(block | block << 8);
}
int main(int argc, char *argv[])
{
int  accRaw;
int startInt  = mymillis();
struct  timeval tvBegin;
signal(SIGINT, INThandler);
enableIMU();
gettimeofday(&tvBegin, NULL);
while(1)
{
startInt = mymillis();

// +/- 2G full scale
//printf("X = %7.3f G\t" , ((accRaw * 0.061)/1000));
//printf(" Y =   %7.3f G\t" , ((accRaw * 0.061)/1000));
//printf(" Z =  %7.3f G\n" , ((accRaw * 0.061)/1000));

// +/- 8G full scale
printf("X = %7.3f G\t" , ((accRaw * 0.224)/1000));
printf(" Y =   %7.3f G\t" , ((accRaw * 0.224)/1000));
printf(" Z =  %7.3f G\n" , ((accRaw * 0.224)/1000));

//printf("Xraw = %d \t" , accRaw);
//printf(" Yraw =   %d \t" , accRaw);
//printf(" Zraw =  %d \n" , accRaw);
//Loop time
while(mymillis() - startInt < (DT*1000))
{
usleep(100);
//printf(".");
}
printf("Loop %d\t", mymillis()- startInt);
}
}
``````

May I kindly ask for your advice on how to proceed in order to get the proper values.

Thanks

#5882
Sten-Helge
Participant

According to the datasheet the settings for CTRL_REG2_XM register should be as follows for the different scales;

``````....
// Enable accelerometer.
writeAccReg(CTRL_REG1_XM, 0b01100111); //  z,y,x axis enabled, continuos update,  100Hz data rate

//writeAccReg(CTRL_REG2_XM, 0b00000000); //+/- 2G full scale
//writeAccReg(CTRL_REG2_XM, 0b00001000); //+/- 4G full scale
//writeAccReg(CTRL_REG2_XM, 0b00010000); // +/- 6G full scale
//writeAccReg(CTRL_REG2_XM, 0b00011000); // +/- 8G full scale
writeAccReg(CTRL_REG2_XM, 0b00100000); // +/- 16G full scale
....
....

// +/- 2G full scale
//printf("X = %7.2f G\t" , ((accRaw * 0.061)/1000));
//printf(" Y =   %7.2f G\t" , ((accRaw * 0.061)/1000));
//printf(" Z =  %7.2f G\n" , ((accRaw * 0.061)/1000));

// +/- 4G full scale
//printf("X = %7.2f G\t" , ((accRaw * 0.122)/1000));
//printf(" Y =   %7.2f G\t" , ((accRaw * 0.122)/1000));
//printf(" Z =  %7.2f G\n" , ((accRaw * 0.122)/1000));

// +/- 6G full scale
//printf("X = %7.2f G\t" , ((accRaw * 0.183)/1000));
//printf(" Y =   %7.2f G\t" , ((accRaw * 0.183)/1000));
//printf(" Z =  %7.2f G\n" , ((accRaw * 0.183)/1000));

// +/- 8G full scale
//printf("X = %7.3f G\t" , ((accRaw * 0.244)/1000));
//printf(" Y =   %7.3f G\t" , ((accRaw * 0.244)/1000));
//printf(" Z =  %7.3f G\n" , ((accRaw * 0.244)/1000));

// +/- 12G full scale
printf("X = %7.2f G\t" , ((accRaw * 0.732)/1000));
printf(" Y =   %7.2f G\t" , ((accRaw * 0.732)/1000));
printf(" Z =  %7.2f G\n" , ((accRaw * 0.732)/1000));

//printf("Xraw = %d \t" , accRaw);
//printf(" Yraw =   %d \t" , accRaw);
//printf(" Zraw =  %d \n" , accRaw);
....
``````

Thanks

#5883
Mark Williams
Keymaster

You are correct.. there is a typo in the code.

This;
`writeACC(CTRL_REG2_XM, 0b00010000) #+/- 8G full scale`
should be
`writeACC(CTRL_REG2_XM, 0b00011000) #+/- 8G full scale`

I have updated the page.

And your scales in CTRL_REG2_XM above are correct.

Mark --OzzMaker.com -- Viewing 3 posts - 1 through 3 (of 3 total)
• You must be logged in to reply to this topic.