HMC5883 Digital compass Library

Dependents:   sensor Cansat_program Cansat_program2 compass_cal ... more

Fork of HMC5883L by Tyler Weaver

Committer:
xeta05
Date:
Tue Dec 10 10:58:28 2013 +0000
Revision:
5:c9ce1eeaf001
Parent:
3:14d274e0f9de
*Corrected the XZY order instead of the previous XYZ to match the datasheet.;  *  Added Declination compensation by a define

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tylerjw 0:8b84d61cee94 1 /*
tylerjw 0:8b84d61cee94 2 * @file HMC5883L.h
xeta05 5:c9ce1eeaf001 3 * @author Oskar Lopez de Gamboa
tylerjw 0:8b84d61cee94 4 *
tylerjw 0:8b84d61cee94 5 * @section LICENSE
tylerjw 0:8b84d61cee94 6 *
tylerjw 0:8b84d61cee94 7 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software
tylerjw 0:8b84d61cee94 8 * and associated documentation files (the "Software"), to deal in the Software without restriction,
tylerjw 0:8b84d61cee94 9 * including without limitation the rights to use, copy, modify, merge, publish, distribute,
tylerjw 0:8b84d61cee94 10 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
tylerjw 0:8b84d61cee94 11 * furnished to do so, subject to the following conditions:
tylerjw 0:8b84d61cee94 12 *
tylerjw 0:8b84d61cee94 13 * The above copyright notice and this permission notice shall be included in all copies or
tylerjw 0:8b84d61cee94 14 * substantial portions of the Software.
tylerjw 0:8b84d61cee94 15 *
tylerjw 0:8b84d61cee94 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
tylerjw 0:8b84d61cee94 17 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
tylerjw 0:8b84d61cee94 18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
tylerjw 0:8b84d61cee94 19 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
tylerjw 0:8b84d61cee94 20 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
tylerjw 0:8b84d61cee94 21 *
tylerjw 0:8b84d61cee94 22 * @section DESCRIPTION
tylerjw 0:8b84d61cee94 23 *
tylerjw 0:8b84d61cee94 24 * HMC5883L 3-Axis Digital Compas IC
xeta05 5:c9ce1eeaf001 25 * The library done by Tyler Weaver with:
tylerjw 0:8b84d61cee94 26 *
xeta05 5:c9ce1eeaf001 27 * *Corrected the XZY order instead of the previous XYZ to match the datasheet.
xeta05 5:c9ce1eeaf001 28 * *Added Declination compensation by a define
xeta05 5:c9ce1eeaf001 29 *
tylerjw 0:8b84d61cee94 30 *
tylerjw 0:8b84d61cee94 31 */
tylerjw 0:8b84d61cee94 32
tylerjw 0:8b84d61cee94 33 #ifndef HMC5883L_H
tylerjw 0:8b84d61cee94 34 #define HMC5883L_H
tylerjw 0:8b84d61cee94 35
tylerjw 0:8b84d61cee94 36 #include "mbed.h"
tylerjw 0:8b84d61cee94 37
tylerjw 0:8b84d61cee94 38 /*
tylerjw 0:8b84d61cee94 39 * Defines
tylerjw 0:8b84d61cee94 40 */
tylerjw 0:8b84d61cee94 41
tylerjw 0:8b84d61cee94 42 //-----------
tylerjw 0:8b84d61cee94 43 // Registers
tylerjw 0:8b84d61cee94 44 //-----------
tylerjw 0:8b84d61cee94 45 #define CONFIG_A_REG 0x00
tylerjw 0:8b84d61cee94 46 #define CONFIG_B_REG 0x01
tylerjw 0:8b84d61cee94 47 #define MODE_REG 0x02
tylerjw 0:8b84d61cee94 48 #define OUTPUT_REG 0x03
tylerjw 0:8b84d61cee94 49 #define STATUS_REG 0x09
tylerjw 0:8b84d61cee94 50
tylerjw 0:8b84d61cee94 51 // configuration register a
tylerjw 0:8b84d61cee94 52 #define AVG1_SAMPLES 0x00
tylerjw 0:8b84d61cee94 53 #define AVG2_SAMPLES 0x20
tylerjw 0:8b84d61cee94 54 #define AVG4_SAMPLES 0x80
tylerjw 0:8b84d61cee94 55 #define AVG8_SAMPLES 0xC0
tylerjw 0:8b84d61cee94 56
tylerjw 0:8b84d61cee94 57 #define OUTPUT_RATE_0_75 0x00
tylerjw 0:8b84d61cee94 58 #define OUTPUT_RATE_1_5 0x04
tylerjw 0:8b84d61cee94 59 #define OUTPUT_RATE_3 0x08
tylerjw 0:8b84d61cee94 60 #define OUTPUT_RATE_7_5 0x0C
tylerjw 0:8b84d61cee94 61 #define OUTPUT_RATE_15 0x10
tylerjw 0:8b84d61cee94 62 #define OUTPUT_RATE_30 0x14
tylerjw 0:8b84d61cee94 63 #define OUTPUT_RATE_75 0x18
tylerjw 0:8b84d61cee94 64
tylerjw 0:8b84d61cee94 65 #define NORMAL_MEASUREMENT 0x00
tylerjw 0:8b84d61cee94 66 #define POSITIVE_BIAS 0x01
tylerjw 0:8b84d61cee94 67 #define NEGATIVE_BIAS 0x02
tylerjw 0:8b84d61cee94 68
tylerjw 0:8b84d61cee94 69 // mode register
tylerjw 0:8b84d61cee94 70 #define CONTINUOUS_MODE 0x00
tylerjw 0:8b84d61cee94 71 #define SINGLE_MODE 0x01
tylerjw 0:8b84d61cee94 72 #define IDLE_MODE 0x02
tylerjw 0:8b84d61cee94 73
tylerjw 0:8b84d61cee94 74 // status register
tylerjw 0:8b84d61cee94 75 #define STATUS_LOCK 0x02
tylerjw 0:8b84d61cee94 76 #define STATUS_READY 0x01
tylerjw 0:8b84d61cee94 77
tylerjw 1:8a1357c351c6 78 // Utility
tylerjw 1:8a1357c351c6 79 #ifndef M_PI
tylerjw 1:8a1357c351c6 80 #define M_PI 3.1415926535897932384626433832795
tylerjw 1:8a1357c351c6 81 #endif
tylerjw 1:8a1357c351c6 82
tylerjw 2:8eb755577f83 83 #define PI2 (2*M_PI)
tylerjw 1:8a1357c351c6 84 #define RAD_TO_DEG (180.0/M_PI)
tylerjw 1:8a1357c351c6 85 #define DEG_TO_RAD (M_PI/180.0)
tylerjw 1:8a1357c351c6 86
xeta05 5:c9ce1eeaf001 87 // Once you have your heading, you must then add your 'Declination Angle',
xeta05 5:c9ce1eeaf001 88 // which is the 'Error' of the magnetic field in your location.
xeta05 5:c9ce1eeaf001 89 // Find yours here: http://www.magnetic-declination.com/
xeta05 5:c9ce1eeaf001 90 // Mine is: -1° 13' WEST which is -1.2167 Degrees, or (which we need)
xeta05 5:c9ce1eeaf001 91 // 0,021234839232597676519238237683278 radians, I will use 0.02123
xeta05 5:c9ce1eeaf001 92 // If you cannot find your Declination, put 0, your compass will be slightly off.
xeta05 5:c9ce1eeaf001 93
xeta05 5:c9ce1eeaf001 94 #define DECLINATION_ANGLE -0.02123
xeta05 5:c9ce1eeaf001 95 //#define DECLINATION_ANGLE 0
xeta05 5:c9ce1eeaf001 96
xeta05 5:c9ce1eeaf001 97
tylerjw 0:8b84d61cee94 98 /**
tylerjw 0:8b84d61cee94 99 * The HMC5883L 3-Axis Digital Compass IC
tylerjw 0:8b84d61cee94 100 */
tylerjw 0:8b84d61cee94 101 class HMC5883L
tylerjw 0:8b84d61cee94 102 {
tylerjw 0:8b84d61cee94 103
tylerjw 0:8b84d61cee94 104 public:
tylerjw 0:8b84d61cee94 105
tylerjw 0:8b84d61cee94 106 /**
tylerjw 0:8b84d61cee94 107 * The I2C address that can be passed directly to i2c object (it's already shifted 1 bit left).
tylerjw 0:8b84d61cee94 108 */
tylerjw 0:8b84d61cee94 109 static const int I2C_ADDRESS = 0x3D;
tylerjw 0:8b84d61cee94 110
tylerjw 0:8b84d61cee94 111 /**
tylerjw 0:8b84d61cee94 112 * Constructor.
tylerjw 0:8b84d61cee94 113 *
tylerjw 1:8a1357c351c6 114 * Calls init function
tylerjw 0:8b84d61cee94 115 *
tylerjw 0:8b84d61cee94 116 * @param sda - mbed pin to use for the SDA I2C line.
tylerjw 0:8b84d61cee94 117 * @param scl - mbed pin to use for the SCL I2C line.
tylerjw 0:8b84d61cee94 118 */
tylerjw 0:8b84d61cee94 119 HMC5883L(PinName sda, PinName scl);
tylerjw 0:8b84d61cee94 120
tylerjw 0:8b84d61cee94 121 /**
tylerjw 0:8b84d61cee94 122 * Constructor that accepts external i2c interface object.
tylerjw 1:8a1357c351c6 123 *
tylerjw 1:8a1357c351c6 124 * Calls init function
tylerjw 0:8b84d61cee94 125 *
tylerjw 0:8b84d61cee94 126 * @param i2c The I2C interface object to use.
tylerjw 0:8b84d61cee94 127 */
tylerjw 0:8b84d61cee94 128 HMC5883L(I2C &i2c) : i2c_(i2c) {
tylerjw 0:8b84d61cee94 129 init();
tylerjw 0:8b84d61cee94 130 }
tylerjw 0:8b84d61cee94 131
tylerjw 0:8b84d61cee94 132 ~HMC5883L();
tylerjw 0:8b84d61cee94 133
tylerjw 0:8b84d61cee94 134 /**
tylerjw 0:8b84d61cee94 135 * Initalize function called by all constructors.
tylerjw 0:8b84d61cee94 136 *
tylerjw 0:8b84d61cee94 137 * Place startup code in here.
tylerjw 0:8b84d61cee94 138 */
tylerjw 0:8b84d61cee94 139 void init();
tylerjw 0:8b84d61cee94 140
tylerjw 0:8b84d61cee94 141 /**
tylerjw 0:8b84d61cee94 142 * Function for setting configuration register A
tylerjw 0:8b84d61cee94 143 *
tylerjw 0:8b84d61cee94 144 * Defined constants should be ored together to create value.
tylerjw 0:8b84d61cee94 145 * Defualt is 0x10 - 1 Sample per output, 15Hz Data output rate, normal measurement mode
tylerjw 0:8b84d61cee94 146 *
tylerjw 0:8b84d61cee94 147 * Refer to datasheet for instructions for setting Configuration Register A.
tylerjw 0:8b84d61cee94 148 *
tylerjw 0:8b84d61cee94 149 * @param config the value to place in Configuration Register A
tylerjw 0:8b84d61cee94 150 */
tylerjw 0:8b84d61cee94 151 void setConfigurationA(char);
tylerjw 0:8b84d61cee94 152
tylerjw 0:8b84d61cee94 153 /**
tylerjw 0:8b84d61cee94 154 * Function for retrieving the contents of configuration register A
tylerjw 0:8b84d61cee94 155 *
tylerjw 0:8b84d61cee94 156 * @returns Configuration Register A
tylerjw 0:8b84d61cee94 157 */
tylerjw 0:8b84d61cee94 158 char getConfigurationA();
tylerjw 0:8b84d61cee94 159
tylerjw 0:8b84d61cee94 160 /**
tylerjw 0:8b84d61cee94 161 * Function for setting configuration register B
tylerjw 0:8b84d61cee94 162 *
tylerjw 0:8b84d61cee94 163 * Configuration Register B is for setting the device gain.
tylerjw 0:8b84d61cee94 164 * Default value is 0x20
tylerjw 0:8b84d61cee94 165 *
tylerjw 0:8b84d61cee94 166 * Refer to datasheet for instructions for setting Configuration Register B
tylerjw 0:8b84d61cee94 167 *
tylerjw 0:8b84d61cee94 168 * @param config the value to place in Configuration Register B
tylerjw 0:8b84d61cee94 169 */
tylerjw 0:8b84d61cee94 170 void setConfigurationB(char);
tylerjw 0:8b84d61cee94 171
tylerjw 0:8b84d61cee94 172 /**
tylerjw 0:8b84d61cee94 173 * Function for retrieving the contents of configuration register B
tylerjw 0:8b84d61cee94 174 *
tylerjw 0:8b84d61cee94 175 * @returns Configuration Register B
tylerjw 0:8b84d61cee94 176 */
tylerjw 0:8b84d61cee94 177 char getConfigurationB();
tylerjw 0:8b84d61cee94 178
tylerjw 0:8b84d61cee94 179 /**
tylerjw 0:8b84d61cee94 180 * Funciton for setting the mode register
tylerjw 0:8b84d61cee94 181 *
tylerjw 1:8a1357c351c6 182 * Constants: CONTINUOUS_MODE, SINGLE_MODE, IDLE_MODE
tylerjw 0:8b84d61cee94 183 *
tylerjw 0:8b84d61cee94 184 * When you send a the Single-Measurement Mode instruction to the mode register
tylerjw 0:8b84d61cee94 185 * a single measurement is made, the RDY bit is set in the status register,
tylerjw 0:8b84d61cee94 186 * and the mode is placed in idle mode.
tylerjw 0:8b84d61cee94 187 *
tylerjw 0:8b84d61cee94 188 * When in Continous-Measurement Mode the device continuously performs measurements
tylerjw 0:8b84d61cee94 189 * and places the results in teh data register. After being placed in this mode
tylerjw 0:8b84d61cee94 190 * it takes two periods at the rate set in the data output rate before the first
tylerjw 0:8b84d61cee94 191 * sample is avaliable.
tylerjw 0:8b84d61cee94 192 *
tylerjw 0:8b84d61cee94 193 * Refer to datasheet for more detailed instructions for setting the mode register.
tylerjw 0:8b84d61cee94 194 *
tylerjw 0:8b84d61cee94 195 * @param mode the value for setting in the Mode Register
tylerjw 0:8b84d61cee94 196 */
tylerjw 0:8b84d61cee94 197 void setMode(char);
tylerjw 0:8b84d61cee94 198
tylerjw 0:8b84d61cee94 199 /**
tylerjw 0:8b84d61cee94 200 * Function for retrieving the contents of mode register
tylerjw 0:8b84d61cee94 201 *
tylerjw 0:8b84d61cee94 202 * @returns mode register
tylerjw 0:8b84d61cee94 203 */
tylerjw 0:8b84d61cee94 204 char getMode();
tylerjw 0:8b84d61cee94 205
tylerjw 0:8b84d61cee94 206 /**
tylerjw 0:8b84d61cee94 207 * Function for retriaval of the raw data
xeta05 5:c9ce1eeaf001 208 * Caution!! the HMC5883L gives you the data in XZY order
tylerjw 0:8b84d61cee94 209 *
xeta05 5:c9ce1eeaf001 210 * @param output buffer that is at least 3 in length
tylerjw 0:8b84d61cee94 211 */
tylerjw 3:14d274e0f9de 212 void getXYZ(int16_t raw[3]);
tylerjw 0:8b84d61cee94 213
tylerjw 0:8b84d61cee94 214 /**
tylerjw 0:8b84d61cee94 215 * Function for retrieving the contents of status register
tylerjw 0:8b84d61cee94 216 *
tylerjw 1:8a1357c351c6 217 * Bit1: LOCK, Bit0: RDY
tylerjw 0:8b84d61cee94 218 *
tylerjw 0:8b84d61cee94 219 * @returns status register
tylerjw 0:8b84d61cee94 220 */
tylerjw 0:8b84d61cee94 221 char getStatus();
tylerjw 1:8a1357c351c6 222
tylerjw 1:8a1357c351c6 223 /**
tylerjw 1:8a1357c351c6 224 * Function for getting radian heading using 2-dimensional calculation.
tylerjw 1:8a1357c351c6 225 *
tylerjw 1:8a1357c351c6 226 * Compass must be held flat and away from an magnetic field generating
tylerjw 1:8a1357c351c6 227 * devices such as cell phones and speakers.
tylerjw 1:8a1357c351c6 228 *
xeta05 5:c9ce1eeaf001 229 *
tylerjw 1:8a1357c351c6 230 *
tylerjw 1:8a1357c351c6 231 * @returns heading in radians
tylerjw 1:8a1357c351c6 232 */
tylerjw 1:8a1357c351c6 233 double getHeadingXY();
tylerjw 1:8a1357c351c6 234
tylerjw 1:8a1357c351c6 235 /**
tylerjw 1:8a1357c351c6 236 * Function for getting degree heading using 2-dimensional calculation.
tylerjw 1:8a1357c351c6 237 *
tylerjw 1:8a1357c351c6 238 * Compass must be held flat and away from an magnetic field generating
tylerjw 1:8a1357c351c6 239 * devices such as cell phones and speakers.
tylerjw 1:8a1357c351c6 240 *
xeta05 5:c9ce1eeaf001 241 *
tylerjw 1:8a1357c351c6 242 *
tylerjw 1:8a1357c351c6 243 * @returns heading in degrees
tylerjw 1:8a1357c351c6 244 */
tylerjw 1:8a1357c351c6 245 double getHeadingXYDeg() {
tylerjw 1:8a1357c351c6 246 return (getHeadingXY() * RAD_TO_DEG);
tylerjw 1:8a1357c351c6 247 }
tylerjw 0:8b84d61cee94 248
tylerjw 0:8b84d61cee94 249 private:
tylerjw 0:8b84d61cee94 250
tylerjw 0:8b84d61cee94 251 I2C &i2c_;
tylerjw 0:8b84d61cee94 252
tylerjw 0:8b84d61cee94 253 /**
tylerjw 0:8b84d61cee94 254 * The raw buffer for allocating I2C object in its own without heap memory.
tylerjw 0:8b84d61cee94 255 */
tylerjw 0:8b84d61cee94 256 char i2cRaw[sizeof(I2C)];
tylerjw 0:8b84d61cee94 257 };
tylerjw 0:8b84d61cee94 258
tylerjw 0:8b84d61cee94 259 #endif // HMC5883L