Calibrating ITG3200 for Thermal Drift

Reference: http://mbed.org/users/gltest26/code/ITG3200/wiki/Thermal-Drift?c=4239

The ITG3200 gyro has linear thermal drift characteristics. The library built by James Watanabe has built in functionality to allow the user to calibrate their ITG3200. Below is the instructions to perform the calibration.

Materials:

Wiring:

mbed9-Dof
p27SCL
p28SDA
VoutVCC
GNDGND

Library Used:

Import libraryITG3200

Modified getOffset for calibrating Thermal Drift coefficients.

Procedure: Use the can of air to cool the ITG3200 gyro (sensor furthest away from pins on 9-dof board), then reset the board and allow to warm up and sit still. The code calibrates 120 times (1/sec) printing the calibration offsets and temperature readings to a .csv file on the local file system. The output is printed to the pc serial output and LED1 blinks while it is working. LED1 turns off after the last sample and the file is closed. Open the .csv file with excel and select the whole table. Then select the Scatter Chart in the Insert ribbon. Right click on each group of samples and select "Add Trendline". In the menu that appears select "Display Equation on chart" located near the bottom of the page. Do this for each of the three lines. The equations you get have two numbers, the first located before the x is the slope and the second is the offset. These are the values used by the setCalibrationCurve() function.

#include "mbed.h"
#include "ITG3200.h"

int main()
{
    DigitalOut myled(LED1);
    LocalFileSystem local("local");               // Create the local filesystem under the name "local"
    ITG3200 gyro(p28, p27); // sda, scl - gyro

    gyro.setLpBandwidth(LPFBW_5HZ); // lowest rate low-pass filter, needed to reduce noise
    
    Serial pc(USBTX, USBRX);

    pc.baud(9600);

    myled = 0;
    FILE *fp = fopen("/local/itg3200.csv", "w");  // Open "itg3200.csv" for writing
    fputs("Temp, X, Y, Z\r\n", fp);               // place the header at the top

    float temperature = 0.0;
    int gyro_readings[3];

    for(int i = 0; i < 120; i++) { // 120 seconds - 120 samples
        myled = 1;
        gyro.calibrate(1.0); // calibrate, remember the gyro should NOT be moving during this test
        myled = 0;
        gyro.getOffset(gyro_readings);
        temperature = gyro.getTemperature();
        pc.printf("%3d,%f,%d,%d,%d\r\n",i,temperature,gyro_readings[0],gyro_readings[1],gyro_readings[2]);
        fprintf(fp, "%f,%d,%d,%d\r\n",temperature,gyro_readings[0],gyro_readings[1],gyro_readings[2]);
    }
    fclose(fp);
    myled = 0;
}

Sample test:

/media/uploads/tylerjw/test_chart.png

AxisOffsetSlope
X99.491-1.0076
Y-44.9150.9298
Z-29.8410.4685

This test was performed twice and the offset and slope values were averaged. To test the outputs the above code was modified to output the calibrated gyro values to a CSV file in a similar manner as before. Note: The function call to get the gyro vales includes the second parameter ITG3200::Calibration. The result was a mean, median and mode value of 0 on all three outputs. The max rage was 5.

#include "mbed.h"
#include "ITG3200.h"

int main()
{
    DigitalOut myled(LED1);
    LocalFileSystem local("local");               // Create the local filesystem under the name "local"
    ITG3200 gyro(p28, p27); // sda, scl - gyro
    const float offset[3] = {99.5, -45.0, -29.7}; // taken from itg3200.xls curve fit test
    const float slope[3] = {-1.05, 0.95, 0.47};
    
    gyro.setCalibrationCurve(offset, slope);
    gyro.setLpBandwidth(LPFBW_5HZ); // lowest rate low-pass filter
    
    Serial pc(USBTX, USBRX);

    pc.baud(9600);

    myled = 0;
    FILE *fp = fopen("/local/itg3200.csv", "w");  // Open "itg3200.csv" for writing
    fputs("Temp, X, Y, Z\r\n", fp);               // place the header at the top

    float temperature = 0.0;
    int gyro_readings[3];

    for(int i = 0; i < 120; i++) { // 60 seconds - 120 samples
        myled = 1;
        wait(0.5);
        myled = 0;
        gyro.getGyroXYZ(gyro_readings, ITG3200::Calibration);
        temperature = gyro.getTemperature();
        pc.printf("%3d,%f,%d,%d,%d\r\n",i,temperature,gyro_readings[0],gyro_readings[1],gyro_readings[2]);
        fprintf(fp, "%f,%d,%d,%d\r\n",temperature,gyro_readings[0],gyro_readings[1],gyro_readings[2]);
    }
    fclose(fp);
    myled = 0;
}

Modification of Library: The library was modified to allow simpler sytax when accessing the offset values. Below are the changes:

Old code in ITG3200.h:

const int *getOffset()const{
     return offset;
}

New code:

void getOffset(int offset_copy[3])const{
   if(offset_copy) {
       for(int i = 0; i < 3; i++)
           offset_copy[i] = offset[i];
   }
}


Please log in to post comments.