Interface library for STMicro LSM303DLH 3-axis magnetometer w/ 3-axis acceleromter. Computes magnetic heading.

Dependents:   AVC_20110423

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers LSM303DLH.h Source File

LSM303DLH.h

00001 #include "mbed.h"
00002 #include "vector.h"
00003 
00004 #ifndef M_PI
00005 #define M_PI 3.14159265358979323846
00006 #endif
00007 
00008 /** Tilt-compensated compass interface Library for the STMicro LSM303DLH 3-axis magnetometer, 3-axis acceleromter
00009  *
00010  * Michael Shimniok http://bot-thoughts.com
00011  *
00012  * Based on test program by @tosihisa and 
00013  *
00014  * Pololu sample library for LSM303DLH breakout by ryantm:
00015  *
00016  * Copyright (c) 2011 Pololu Corporation. For more information, see
00017  *
00018  * http://www.pololu.com/
00019  * http://forum.pololu.com/
00020  *
00021  * Permission is hereby granted, free of charge, to any person
00022  * obtaining a copy of this software and associated documentation
00023  * files (the "Software"), to deal in the Software without
00024  * restriction, including without limitation the rights to use,
00025  * copy, modify, merge, publish, distribute, sublicense, and/or sell
00026  * copies of the Software, and to permit persons to whom the
00027  * Software is furnished to do so, subject to the following
00028  * conditions:
00029  *
00030  * The above copyright notice and this permission notice shall be
00031  * included in all copies or substantial portions of the Software.
00032  * 
00033  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
00034  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
00035  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
00036  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
00037  * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
00038  * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
00039  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00040  * OTHER DEALINGS IN THE SOFTWARE.
00041  *
00042  * @code
00043  * #include "mbed.h"
00044  * #include "LSM303DLH.h"
00045  *
00046  * Serial debug(USBTX,USBRX);
00047  * LSM303DLH compass(p28, p27);
00048  *
00049  * int main() {
00050  *   float hdg;
00051  *   debug.format(8,Serial::None,1);
00052  *   debug.baud(115200);
00053  *   debug.printf("LSM303DLH Test\x0d\x0a");
00054  *   compass.setOffset(29.50, -0.50, 4.00); // example calibration
00055  *   compass.setScale(1.00, 1.03, 1.21);    // example calibration
00056  *   while(1) {
00057  *     hdg = compass.heading();
00058  *     debug.printf("Heading: %.2f\n", hdg);
00059  *     wait(0.1);
00060  *   }
00061  * }
00062  * @endcode
00063  */
00064 class LSM303DLH {
00065     public:
00066         /** Create a new interface for an LSM303DLH
00067          *
00068          * @param sda is the pin for the I2C SDA line
00069          * @param scl is the pin for the I2C SCL line
00070          */
00071         LSM303DLH(PinName sda, PinName scl);
00072 
00073         /** sets the x, y, and z offset corrections for hard iron calibration
00074          * 
00075          * Calibration details here:
00076          *  http://mbed.org/users/shimniok/notebook/quick-and-dirty-3d-compass-calibration/
00077          *
00078          * If you gather raw magnetometer data and find, for example, x is offset
00079          * by hard iron by -20 then pass +20 to this member function to correct
00080          * for hard iron.
00081          *
00082          * @param x is the offset correction for the x axis
00083          * @param y is the offset correction for the y axis
00084          * @param z is the offset correction for the z axis
00085          */
00086         void setOffset(float x, float y, float z);
00087         
00088         /** sets the scale factor for the x, y, and z axes
00089          *
00090          * Calibratio details here:
00091          *  http://mbed.org/users/shimniok/notebook/quick-and-dirty-3d-compass-calibration/
00092          *
00093          * Sensitivity of the three axes is never perfectly identical and this
00094          * function can help to correct differences in sensitivity.  You're
00095          * supplying a multipler such that x, y and z will be normalized to the
00096          * same max/min values
00097          */
00098         void setScale(float x, float y, float z);
00099 
00100         /** read the raw accelerometer and compass values
00101          *
00102          * @param a is the accelerometer 3d vector, written by the function
00103          * @param m is the magnetometer 3d vector, written by the function
00104          */
00105         void read(vector &a, vector &m);
00106         
00107         /** returns the magnetic heading with respect to the y axis
00108          *
00109          */
00110         float heading(void);
00111         
00112         /** returns the heading with respect to the specified vector
00113          *
00114          */
00115         float heading(vector from);
00116     
00117         /** sets the I2C bus frequency
00118          *
00119          * @param frequency is the I2C bus/clock frequency, either standard (100000) or fast (400000)
00120          */
00121         void frequency(int hz);
00122     
00123     private:
00124         I2C _compass;
00125         float _offset_x;
00126         float _offset_y;
00127         float _offset_z;
00128         float _scale_x;
00129         float _scale_y;
00130         float _scale_z;
00131         long _filt_ax;
00132         long _filt_ay;
00133         long _filt_az;
00134        
00135         bool write_reg(int addr_i2c,int addr_reg, char v);
00136         bool read_reg(int addr_i2c,int addr_reg, char *v);
00137         bool read_reg_short(int addr_i2c,int addr_reg, short *v);
00138 };