Home › Forums › Forums › Technical Support for BerryIMU › G measurement – uncorrect values
- This topic has 2 replies, 2 voices, and was last updated 6 years, 5 months ago by Mark Williams.
- AuthorPosts
- December 19, 2016 at 10:05 pm #5872Sten-HelgeParticipant
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); } } void selectDevice(int file, int addr) { if (ioctl(file, I2C_SLAVE, addr) < 0) { printf("Failed to select I2C device."); } } void writeAccReg(uint8_t reg, uint8_t value) { selectDevice(file,ACC_ADDRESS); 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[20]; 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 } void readACC(int *a) { uint8_t block[6]; selectDevice(file,ACC_ADDRESS); readBlock(0x80 | OUT_X_L_A, sizeof(block), block); *a = (int16_t)(block[0] | block[1] << 8); *(a+1) = (int16_t)(block[2] | block[3] << 8); *(a+2) = (int16_t)(block[4] | block[5] << 8); } int main(int argc, char *argv[]) { int accRaw[3]; int startInt = mymillis(); struct timeval tvBegin; signal(SIGINT, INThandler); enableIMU(); gettimeofday(&tvBegin, NULL); while(1) { startInt = mymillis(); //read ACC and GYR data readACC(accRaw); // +/- 2G full scale //printf("X = %7.3f G\t" , ((accRaw[0] * 0.061)/1000)); //printf(" Y = %7.3f G\t" , ((accRaw[1] * 0.061)/1000)); //printf(" Z = %7.3f G\n" , ((accRaw[2] * 0.061)/1000)); // +/- 8G full scale printf("X = %7.3f G\t" , ((accRaw[0] * 0.224)/1000)); printf(" Y = %7.3f G\t" , ((accRaw[1] * 0.224)/1000)); printf(" Z = %7.3f G\n" , ((accRaw[2] * 0.224)/1000)); //printf("Xraw = %d \t" , accRaw[0]); //printf(" Yraw = %d \t" , accRaw[1]); //printf(" Zraw = %d \n" , accRaw[2]); //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
December 21, 2016 at 8:30 am #5882Sten-HelgeParticipantAccording 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 .... .... //read ACC values readACC(accRaw); // +/- 2G full scale //printf("X = %7.2f G\t" , ((accRaw[0] * 0.061)/1000)); //printf(" Y = %7.2f G\t" , ((accRaw[1] * 0.061)/1000)); //printf(" Z = %7.2f G\n" , ((accRaw[2] * 0.061)/1000)); // +/- 4G full scale //printf("X = %7.2f G\t" , ((accRaw[0] * 0.122)/1000)); //printf(" Y = %7.2f G\t" , ((accRaw[1] * 0.122)/1000)); //printf(" Z = %7.2f G\n" , ((accRaw[2] * 0.122)/1000)); // +/- 6G full scale //printf("X = %7.2f G\t" , ((accRaw[0] * 0.183)/1000)); //printf(" Y = %7.2f G\t" , ((accRaw[1] * 0.183)/1000)); //printf(" Z = %7.2f G\n" , ((accRaw[2] * 0.183)/1000)); // +/- 8G full scale //printf("X = %7.3f G\t" , ((accRaw[0] * 0.244)/1000)); //printf(" Y = %7.3f G\t" , ((accRaw[1] * 0.244)/1000)); //printf(" Z = %7.3f G\n" , ((accRaw[2] * 0.244)/1000)); // +/- 12G full scale printf("X = %7.2f G\t" , ((accRaw[0] * 0.732)/1000)); printf(" Y = %7.2f G\t" , ((accRaw[1] * 0.732)/1000)); printf(" Z = %7.2f G\n" , ((accRaw[2] * 0.732)/1000)); //printf("Xraw = %d \t" , accRaw[0]); //printf(" Yraw = %d \t" , accRaw[1]); //printf(" Zraw = %d \n" , accRaw[2]); ....
Please advice if not correct.
Thanks
December 21, 2016 at 10:14 pm #5883Mark WilliamsKeymasterYou 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 --
- AuthorPosts
- You must be logged in to reply to this topic.