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.