Hello,
I just received my MinIMU-9 and wanted to access it with a raspberryPi.
I started with the accelerometer. After some testing I now get partly reasonable results:
Accelerometer: X: -0.000977 Y: -0.000977 Z: -0.002930
Accelerometer: X: -0.011719 Y: -0.030275 Z: -0.001953
Accelerometer: X: 0.003906 Y: -0.040042 Z: -0.001953
Accelerometer: X: -0.003906 Y: -0.015626 Z: -0.003906
Accelerometer: X: 0.015626 Y: -0.006836 Z: -1.056705
Accelerometer: X: -0.004883 Y: -0.001953 Z: -1.040103
Accelerometer: X: -0.005860 Y: -0.028322 Z: -0.002930
Accelerometer: X: -0.003906 Y: -0.002930 Z: -0.001953
Accelerometer: X: 0.019532 Y: -0.030275 Z: -0.004883
Accelerometer: X: 0.003906 Y: -0.006836 Z: -1.009827
Accelerometer: X: -0.007813 Y: -0.001953 Z: -1.031313
Accelerometer: X: -0.005860 Y: -0.001953 Z: -0.002930
Accelerometer: X: 0.005860 Y: -0.027345 Z: -1.027406
Accelerometer: X: -0.004883 Y: -0.041018 Z: -1.014710
Accelerometer: X: 0.003906 Y: -0.030275 Z: -1.044009
Accelerometer: X: 0.003906 Y: -0.028322 Z: -1.042056
Accelerometer: X: -0.005860 Y: -0.005860 Z: -1.029360
Accelerometer: X: -0.007813 Y: -0.004883 Z: -0.007813
Accelerometer: X: -0.004883 Y: -0.001953 Z: -1.042056
Accelerometer: X: -0.004883 Y: -0.003906 Z: -1.030336
Accelerometer: X: 0.005860 Y: -0.002930 Z: -0.005860
Accelerometer: X: -0.006836 Y: -0.041018 Z: -1.042056
Accelerometer: X: -0.004883 Y: -0.001953 Z: -1.040103
Accelerometer: X: -0.005860 Y: -0.005860 Z: -0.006836
Accelerometer: X: 0.000000 Y: -0.028322 Z: -1.043032
Accelerometer: X: -0.000977 Y: -0.002930 Z: -0.007813
Accelerometer: X: -0.006836 Y: -0.002930 Z: -0.003906
Accelerometer: X: -0.004883 Y: -0.028322 Z: -1.028383
Accelerometer: X: 0.000000 Y: -0.004883 Z: -0.006836
Accelerometer: X: -0.003906 Y: -0.028322 Z: -1.010804
Accelerometer: X: 0.000000 Y: -0.002930 Z: -0.005860
Accelerometer: X: -0.007813 Y: -0.015626 Z: -1.028383
Accelerometer: X: -0.005860 Y: -0.044925 Z: -1.028383
As expected the acceleration measured in Z-direction is around -1 g. When I turn my bread board than it shows up on the other axis’ as expected.
My problems are the “holes” between these correct values. As you can see between several -1g-values are several one around 0g.
I already enabled the BDU bit changed the period of the read loop between 100ms and 1s and tried higher output frequencies for the chip (50 Hz, 100 Hz and 400 Hz so far), but nothing helped.
Here is the important part of the code for interfacing the sensor I use:
Initializing
int facc;
const float accelerometerGainSI = 0x3fff; /*!< constant to get SI units from the accelerometer output */
int accelerometerInit(char deviceName[])
{
//initialize i2c-device
facc = open(deviceName, O_RDWR | O_NOCTTY | O_NDELAY);
if (facc == -1)
{
printf("open_port: Unable to open i2c-bus");
return FALSE; //0 == error
}
if (ioctl(facc, I2C_SLAVE, LSM303_LIN_ACC_ADDR) < 0)
{
printf("Failed to acquire bus access and/or talk to slave.\n");
return FALSE; // 0 == error
}
// LSM303 configuration settings
int8_t LSM303_CTRL_REG1_set = (1<<PM0); // Set Power Mode to normal
LSM303_CTRL_REG1_set |= (1<<DR0); // Set output data rate to 100 Hz (maybe 50 Hz enough?) //0b00100111; // (Atheel recommends: 0b00100111) enable: normal power mode, highest filter cut-off freq, Z-Y-X axes
LSM303_CTRL_REG1_set |= (1<<Zen) | (1<<Yen) | (1<<Xen); // Enable x,y and z axis of the accelerometer
/*
Enable block data update (BDU)
Use Full scale of +-2g (FS1 and FS0 = 0)
*/
int8_t LSM303_CTRL_REG4_set = (1<<BDU) | (1<<BLE);
/* set LSM303 CTRL REG1 register
create an array of 2 bytes
1st byte: Register address
2nd byte: value to write to register
*/
int8_t reg[2];
reg[0] = LSM303_CTRL_REG1_A;
reg[1] = LSM303_CTRL_REG1_set;
//Update register with new value
if (write(facc, reg, 2) != 2)
{
printf("Failed to set REG1\n");
return FALSE; //0 == error;
}
// set LSM303 CTRL REG4 register
reg[0] = LSM303_CTRL_REG4_A;
reg[1] = LSM303_CTRL_REG4_set;
if (write(facc, reg, 2) != 2)
{
printf("Failed to set REG4\n");
return FALSE; //0 == error;
}
return TRUE;
}
Read out
int accelerometerReadSI(float xyz[3])
{
int status = accelerometerReadMeasurements(xyz);
xyz[0] /= accelerometerGainSI;
xyz[1] /= accelerometerGainSI;
xyz[2] /= accelerometerGainSI;
return status;
}
int accelerometerReadMeasurements(float xyz[3])
{
/*
start register is OUT_X_L_A.
For multiple read, the MSB has to be set. Then the client will
auto increment the register address.
*/
int8_t readReg = LSM303_OUT_X_L_A | LSM303_SUB_ADDR_multiple_read;
//Tell the client to expect multiple reading from start register
if (write(facc, &readReg, 1) != 1)
{
printf("Failed set read register\n");
return FALSE; //0 == error;
}
int8_t buffer[6]; ///< buffer to hold 2 bytes of data for every axis
//Read data for all 3 axis at once
if(read(facc, buffer, 6) != 6)
{
printf("Read accelerometer xyz failed\n");
return FALSE;
}
//convert to float
xyz[0] = (float) ((buffer[0]<<8 | buffer[1]));
xyz[1] = (float) ((buffer[2]<<8 | buffer[3]));
xyz[2] = (float) ((buffer[4]<<8 | buffer[5]));
return TRUE;
}
It would be gread if someone would have a suggestion. I will try to implement the magnetometer tomorrow. Maybe I will stumble upon a mistake which would fix my problem.
Best regards,
Jan