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:
- mbed LPC1768
- Sparkfun 9-Dof Sensor stick
- Microsoft Excel 2010
- Can of Air(compressed gas duster)
- Breadboard and jumper wires
Wiring:
| mbed | 9-Dof |
|---|---|
| p27 | SCL |
| p28 | SDA |
| Vout | VCC |
| GND | GND |
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:
| Axis | Offset | Slope |
|---|---|---|
| X | 99.491 | -1.0076 |
| Y | -44.915 | 0.9298 |
| Z | -29.841 | 0.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.
