7 years ago.

Combined ADXL345 and ITG3200 output data

Question Update: I have implemented the calibration function below from A.Berk.

void calibrateAccelerometer(void) {
    
     //Take a number of readings and average them
     //to calculate any bias the accelerometer may have.
     for (int i = 0; i < 32; i++) {

        accelerometer.getOutput(readings);

        a_x += (int16_t) readings[0];
        a_y += (int16_t) readings[1];
        a_z += (int16_t) readings[2];

        //50Hz data rate.
        wait(0.02);
        }

     a_x /= 128;
     a_y /= 128;
     a_z /= 128;

     //At 4mg/LSB, 250 LSBs is 1g.
     a_xBias = a_x;
     a_yBias = a_y;
     a_zBias = (a_z - 250);

     a_x = 0;
     a_y = 0;
     a_z = 0;   

}

Using this code snippet in my main program

 while (1){
        calibrateAccelerometer();
        wait(0.1);
        accelerometer.getOutput(readings);
        
        int Ax_nb = (int16_t)readings[0];
        int Ay_nb = (int16_t)readings[1];
        int Az_nb = (int16_t)readings[2];
        
        int Ax = (int16_t)readings[0] - a_xBias;
        int Ay = (int16_t)readings[1] - a_yBias;
        int Az = (int16_t)readings[2] - a_zBias;
        
        int Gx = gyro.getGyroX();
        int Gy = gyro.getGyroY();
        int Gz = gyro.getGyroZ();
        
        //pc.printf("%i, %i, %i\n", (int16_t)readings[0], (int16_t)readings[1], (int16_t)readings[2]);
              
        lcd.cls();
        //lcd.printf("ITG3200 DevID 0x%02X\n",gyro.getWhoAmI()); //was gyro1.getWhoAmI()
        //lcd.printf("ADXL DevID is: 0x%02X\n", accelerometer.getDeviceID());
        
        //Output of ADXL345 without calibration function
        lcd.printf("Ax%i Ay%i Az%i\n", Ax_nb, Ay_nb, Az_nb);
        
        //Output of ADXL345 with calibration function
        lcd.printf("AxB%i AyB%i AzB%i\n", Ax, Ay, Az);
        
        //lcd.printf("Gx%i Gy%i Gz%i\n\r", Gx, Gy, Gz);
        //lcd.printf("Temperature %2.1f \n",gyro.getTemperature());
        wait(0.5);
   

I get the following results for my ADXL345 blue tacked down on a horizontal surface. Ax (-10 to -12 range) Ay (18 to 24 range) Az (246 to 248 range) AxB (-8 to -10 range) AyB (14 to 20 range) AzB (435 to 437 range)

I've read the manual about offset but I'm at a loss to interpret what these values mean in terms of 'g' I expected after calibration AxB and AxY yo be '0' and AxZ to be '1'

Many thanks for any tips / suggestions / pointers to articles to read or examples.

Do you have any idea what kind of accuracy you require for your use case? Do you even need calibration?

If yes, what kind of results are you getting for the bias values in your calibration function?

posted by Erik - 10 Mar 2017

USING OFFSET REGISTERS The ADXL345 has offset registers that facilitate offset calibration. The data format for the offset registers is 8-bit, twos compliment. The resolution of the offset registers is about 15.6 mg/LSB. If offset calibration must be finer than 15.6 mg/LSB, the calibration needs to be done at the processor. The offset register adds the value written in the register to measured acceleration. For example, if the offset is +156 mg, then −156 mg should be written to offset register. Figure 9 shows the typical offset calibration sequence. For this routine, X/Y axes errors are zero when 0 g input is applied, whereas Z-axis errors are zero when 1 g input is applied. Greater accuracy can be achieved if it is possible to rotate the ADXL345 at calibration.

Hi Eric, I've read the advice note AN-177 page 6 (See above) about Offset registers so I believe my device is set to +/-16g 13 bit mode 0x31. What I basically want to do is interpret what the integers being displayed for the 3 axis mean? Are they values of mg or are they values of g after calibration and if my sensors is horizontally static why such a small offset value after calibration? Why is the Ax and Ay axis not 0? The bias values after running the calibration function are of the order -2 for x, -4 for y and strangely 189 for z?

posted by Derek Calland 10 Mar 2017

1 Answer

7 years ago.

You can get the sensitivity of the output from the datasheet. For example in the part you copied regarding offset calibration in the device itself, each LSB is 15.6mg. For yours it is probably different: The z-axis is roughly 250, and so is the offset substracted from the Z-axis. So most likely, 250 equal 1g, so the sensitivity is 4mg/LSB. If you would get out 100 for example, that means you experience 0.4g on that axis.

Now why you are offset calibration does not work. You add the first 32 samples, but then in the end you divide by 128. To take average you need to divide by the number of samples, so also 32. That is why your x and y offsets are not properly cancelled.

But still the question: How large are the offsets you can tolerate in your application? Maybe offset is no problem at all for you.

Accepted Answer

Thanks for everything again Erik!! I found 3 previous questions which have helped enormously in understanding what the number I'm looking at means.......each integer represents 0.004g so in the Ax case with your advice of divide by 32 AxB is now -2 to 2 at rest which equates to only -0.008 to 0.008g and AyB 8 to 20 which equates to 0.032g and 0.08g the AzB case is almost perfect at 1g (255 to 261 * 0.004g). I have an idea in mind to test all these devices for a control loop stability exercise on a rover or quadcopter for example, but I want to first understand what all the differant sensors provide in terms of information. I want to use accelerometer, gyro, compass and GPS all together at some point. Aaron Berks page on Dead Reckoning is very interesting for me to review. But thanks again Erik every bit helps!

posted by Derek Calland 10 Mar 2017