Fork

Fork of HMC5883L by Oskar Lopez de Gamboa

Committer:
Condo2k4
Date:
Tue Mar 08 13:13:00 2016 +0000
Revision:
6:511a8b8d2cf8
Parent:
5:c9ce1eeaf001
Initial import

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)
Condo2k4 6:511a8b8d2cf8 91 // 0,021234839232597676519238237683278 radians, so I would 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
Condo2k4 6:511a8b8d2cf8 94 #ifndef DECLINATION_ANGLE
Condo2k4 6:511a8b8d2cf8 95 #define DECLINATION_ANGLE 0
Condo2k4 6:511a8b8d2cf8 96 #endif
xeta05 5:c9ce1eeaf001 97
xeta05 5:c9ce1eeaf001 98
tylerjw 0:8b84d61cee94 99 /**
tylerjw 0:8b84d61cee94 100 * The HMC5883L 3-Axis Digital Compass IC
tylerjw 0:8b84d61cee94 101 */
tylerjw 0:8b84d61cee94 102 class HMC5883L
tylerjw 0:8b84d61cee94 103 {
tylerjw 0:8b84d61cee94 104
tylerjw 0:8b84d61cee94 105 public:
tylerjw 0:8b84d61cee94 106
tylerjw 0:8b84d61cee94 107 /**
tylerjw 0:8b84d61cee94 108 * The I2C address that can be passed directly to i2c object (it's already shifted 1 bit left).
tylerjw 0:8b84d61cee94 109 */
tylerjw 0:8b84d61cee94 110 static const int I2C_ADDRESS = 0x3D;
tylerjw 0:8b84d61cee94 111
tylerjw 0:8b84d61cee94 112 /**
tylerjw 0:8b84d61cee94 113 * Constructor.
tylerjw 0:8b84d61cee94 114 *
tylerjw 1:8a1357c351c6 115 * Calls init function
tylerjw 0:8b84d61cee94 116 *
tylerjw 0:8b84d61cee94 117 * @param sda - mbed pin to use for the SDA I2C line.
tylerjw 0:8b84d61cee94 118 * @param scl - mbed pin to use for the SCL I2C line.
tylerjw 0:8b84d61cee94 119 */
tylerjw 0:8b84d61cee94 120 HMC5883L(PinName sda, PinName scl);
tylerjw 0:8b84d61cee94 121
tylerjw 0:8b84d61cee94 122 /**
tylerjw 0:8b84d61cee94 123 * Constructor that accepts external i2c interface object.
tylerjw 1:8a1357c351c6 124 *
tylerjw 1:8a1357c351c6 125 * Calls init function
tylerjw 0:8b84d61cee94 126 *
tylerjw 0:8b84d61cee94 127 * @param i2c The I2C interface object to use.
tylerjw 0:8b84d61cee94 128 */
tylerjw 0:8b84d61cee94 129 HMC5883L(I2C &i2c) : i2c_(i2c) {
tylerjw 0:8b84d61cee94 130 init();
tylerjw 0:8b84d61cee94 131 }
tylerjw 0:8b84d61cee94 132
tylerjw 0:8b84d61cee94 133 ~HMC5883L();
tylerjw 0:8b84d61cee94 134
tylerjw 0:8b84d61cee94 135 /**
tylerjw 0:8b84d61cee94 136 * Initalize function called by all constructors.
tylerjw 0:8b84d61cee94 137 *
tylerjw 0:8b84d61cee94 138 * Place startup code in here.
tylerjw 0:8b84d61cee94 139 */
tylerjw 0:8b84d61cee94 140 void init();
tylerjw 0:8b84d61cee94 141
tylerjw 0:8b84d61cee94 142 /**
tylerjw 0:8b84d61cee94 143 * Function for setting configuration register A
tylerjw 0:8b84d61cee94 144 *
tylerjw 0:8b84d61cee94 145 * Defined constants should be ored together to create value.
tylerjw 0:8b84d61cee94 146 * Defualt is 0x10 - 1 Sample per output, 15Hz Data output rate, normal measurement mode
tylerjw 0:8b84d61cee94 147 *
tylerjw 0:8b84d61cee94 148 * Refer to datasheet for instructions for setting Configuration Register A.
tylerjw 0:8b84d61cee94 149 *
tylerjw 0:8b84d61cee94 150 * @param config the value to place in Configuration Register A
tylerjw 0:8b84d61cee94 151 */
tylerjw 0:8b84d61cee94 152 void setConfigurationA(char);
tylerjw 0:8b84d61cee94 153
tylerjw 0:8b84d61cee94 154 /**
tylerjw 0:8b84d61cee94 155 * Function for retrieving the contents of configuration register A
tylerjw 0:8b84d61cee94 156 *
tylerjw 0:8b84d61cee94 157 * @returns Configuration Register A
tylerjw 0:8b84d61cee94 158 */
tylerjw 0:8b84d61cee94 159 char getConfigurationA();
tylerjw 0:8b84d61cee94 160
tylerjw 0:8b84d61cee94 161 /**
tylerjw 0:8b84d61cee94 162 * Function for setting configuration register B
tylerjw 0:8b84d61cee94 163 *
tylerjw 0:8b84d61cee94 164 * Configuration Register B is for setting the device gain.
tylerjw 0:8b84d61cee94 165 * Default value is 0x20
tylerjw 0:8b84d61cee94 166 *
tylerjw 0:8b84d61cee94 167 * Refer to datasheet for instructions for setting Configuration Register B
tylerjw 0:8b84d61cee94 168 *
tylerjw 0:8b84d61cee94 169 * @param config the value to place in Configuration Register B
tylerjw 0:8b84d61cee94 170 */
tylerjw 0:8b84d61cee94 171 void setConfigurationB(char);
tylerjw 0:8b84d61cee94 172
tylerjw 0:8b84d61cee94 173 /**
tylerjw 0:8b84d61cee94 174 * Function for retrieving the contents of configuration register B
tylerjw 0:8b84d61cee94 175 *
tylerjw 0:8b84d61cee94 176 * @returns Configuration Register B
tylerjw 0:8b84d61cee94 177 */
tylerjw 0:8b84d61cee94 178 char getConfigurationB();
tylerjw 0:8b84d61cee94 179
tylerjw 0:8b84d61cee94 180 /**
tylerjw 0:8b84d61cee94 181 * Funciton for setting the mode register
tylerjw 0:8b84d61cee94 182 *
tylerjw 1:8a1357c351c6 183 * Constants: CONTINUOUS_MODE, SINGLE_MODE, IDLE_MODE
tylerjw 0:8b84d61cee94 184 *
tylerjw 0:8b84d61cee94 185 * When you send a the Single-Measurement Mode instruction to the mode register
tylerjw 0:8b84d61cee94 186 * a single measurement is made, the RDY bit is set in the status register,
tylerjw 0:8b84d61cee94 187 * and the mode is placed in idle mode.
tylerjw 0:8b84d61cee94 188 *
tylerjw 0:8b84d61cee94 189 * When in Continous-Measurement Mode the device continuously performs measurements
tylerjw 0:8b84d61cee94 190 * and places the results in teh data register. After being placed in this mode
tylerjw 0:8b84d61cee94 191 * it takes two periods at the rate set in the data output rate before the first
tylerjw 0:8b84d61cee94 192 * sample is avaliable.
tylerjw 0:8b84d61cee94 193 *
tylerjw 0:8b84d61cee94 194 * Refer to datasheet for more detailed instructions for setting the mode register.
tylerjw 0:8b84d61cee94 195 *
tylerjw 0:8b84d61cee94 196 * @param mode the value for setting in the Mode Register
tylerjw 0:8b84d61cee94 197 */
tylerjw 0:8b84d61cee94 198 void setMode(char);
tylerjw 0:8b84d61cee94 199
tylerjw 0:8b84d61cee94 200 /**
tylerjw 0:8b84d61cee94 201 * Function for retrieving the contents of mode register
tylerjw 0:8b84d61cee94 202 *
tylerjw 0:8b84d61cee94 203 * @returns mode register
tylerjw 0:8b84d61cee94 204 */
tylerjw 0:8b84d61cee94 205 char getMode();
tylerjw 0:8b84d61cee94 206
tylerjw 0:8b84d61cee94 207 /**
tylerjw 0:8b84d61cee94 208 * Function for retriaval of the raw data
xeta05 5:c9ce1eeaf001 209 * Caution!! the HMC5883L gives you the data in XZY order
tylerjw 0:8b84d61cee94 210 *
xeta05 5:c9ce1eeaf001 211 * @param output buffer that is at least 3 in length
tylerjw 0:8b84d61cee94 212 */
tylerjw 3:14d274e0f9de 213 void getXYZ(int16_t raw[3]);
tylerjw 0:8b84d61cee94 214
tylerjw 0:8b84d61cee94 215 /**
tylerjw 0:8b84d61cee94 216 * Function for retrieving the contents of status register
tylerjw 0:8b84d61cee94 217 *
tylerjw 1:8a1357c351c6 218 * Bit1: LOCK, Bit0: RDY
tylerjw 0:8b84d61cee94 219 *
tylerjw 0:8b84d61cee94 220 * @returns status register
tylerjw 0:8b84d61cee94 221 */
tylerjw 0:8b84d61cee94 222 char getStatus();
tylerjw 1:8a1357c351c6 223
tylerjw 1:8a1357c351c6 224 /**
tylerjw 1:8a1357c351c6 225 * Function for getting radian heading using 2-dimensional calculation.
tylerjw 1:8a1357c351c6 226 *
tylerjw 1:8a1357c351c6 227 * Compass must be held flat and away from an magnetic field generating
tylerjw 1:8a1357c351c6 228 * devices such as cell phones and speakers.
tylerjw 1:8a1357c351c6 229 *
xeta05 5:c9ce1eeaf001 230 *
tylerjw 1:8a1357c351c6 231 *
tylerjw 1:8a1357c351c6 232 * @returns heading in radians
tylerjw 1:8a1357c351c6 233 */
tylerjw 1:8a1357c351c6 234 double getHeadingXY();
tylerjw 1:8a1357c351c6 235
tylerjw 1:8a1357c351c6 236 /**
tylerjw 1:8a1357c351c6 237 * Function for getting degree heading using 2-dimensional calculation.
tylerjw 1:8a1357c351c6 238 *
tylerjw 1:8a1357c351c6 239 * Compass must be held flat and away from an magnetic field generating
tylerjw 1:8a1357c351c6 240 * devices such as cell phones and speakers.
tylerjw 1:8a1357c351c6 241 *
xeta05 5:c9ce1eeaf001 242 *
tylerjw 1:8a1357c351c6 243 *
tylerjw 1:8a1357c351c6 244 * @returns heading in degrees
tylerjw 1:8a1357c351c6 245 */
tylerjw 1:8a1357c351c6 246 double getHeadingXYDeg() {
tylerjw 1:8a1357c351c6 247 return (getHeadingXY() * RAD_TO_DEG);
tylerjw 1:8a1357c351c6 248 }
tylerjw 0:8b84d61cee94 249
tylerjw 0:8b84d61cee94 250 private:
tylerjw 0:8b84d61cee94 251
tylerjw 0:8b84d61cee94 252 I2C &i2c_;
tylerjw 0:8b84d61cee94 253
tylerjw 0:8b84d61cee94 254 /**
tylerjw 0:8b84d61cee94 255 * The raw buffer for allocating I2C object in its own without heap memory.
tylerjw 0:8b84d61cee94 256 */
tylerjw 0:8b84d61cee94 257 char i2cRaw[sizeof(I2C)];
tylerjw 0:8b84d61cee94 258 };
tylerjw 0:8b84d61cee94 259
tylerjw 0:8b84d61cee94 260 #endif // HMC5883L