Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of dgps by
adapt/compass.h@66:5d43988d100c, 2014-05-05 (annotated)
- Committer:
- dylanembed123
- Date:
- Mon May 05 13:20:35 2014 +0000
- Revision:
- 66:5d43988d100c
- Parent:
- 10:c4745ddaaf6a
Final Project;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
krobertson | 10:c4745ddaaf6a | 1 | /** |
krobertson | 10:c4745ddaaf6a | 2 | * \brief Adaptor for the LSM303 integrated compass and accelerometer |
krobertson | 10:c4745ddaaf6a | 3 | **/ |
krobertson | 10:c4745ddaaf6a | 4 | |
krobertson | 10:c4745ddaaf6a | 5 | #ifndef _COMPASS_H_ |
krobertson | 10:c4745ddaaf6a | 6 | #define _COMPASS_H_ |
krobertson | 10:c4745ddaaf6a | 7 | |
krobertson | 10:c4745ddaaf6a | 8 | #include "mbed.h" |
krobertson | 10:c4745ddaaf6a | 9 | #include <SPI.h> |
krobertson | 10:c4745ddaaf6a | 10 | #include <stdint.h> |
krobertson | 10:c4745ddaaf6a | 11 | |
krobertson | 10:c4745ddaaf6a | 12 | typedef unsigned char byte; |
krobertson | 10:c4745ddaaf6a | 13 | |
krobertson | 10:c4745ddaaf6a | 14 | class Compass{ |
krobertson | 10:c4745ddaaf6a | 15 | public: |
krobertson | 10:c4745ddaaf6a | 16 | |
krobertson | 10:c4745ddaaf6a | 17 | template <typename T> struct vector{ |
krobertson | 10:c4745ddaaf6a | 18 | T x, y, z; |
krobertson | 10:c4745ddaaf6a | 19 | }; |
krobertson | 10:c4745ddaaf6a | 20 | |
krobertson | 10:c4745ddaaf6a | 21 | /** |
krobertson | 10:c4745ddaaf6a | 22 | * \brief LSM303 devices |
krobertson | 10:c4745ddaaf6a | 23 | **/ |
krobertson | 10:c4745ddaaf6a | 24 | enum deviceType { device_DLH, device_DLM, device_DLHC, device_D, device_auto }; |
krobertson | 10:c4745ddaaf6a | 25 | |
krobertson | 10:c4745ddaaf6a | 26 | /** |
krobertson | 10:c4745ddaaf6a | 27 | * \brief register addresses |
krobertson | 10:c4745ddaaf6a | 28 | **/ |
krobertson | 10:c4745ddaaf6a | 29 | enum regAddr{ |
krobertson | 10:c4745ddaaf6a | 30 | TEMP_OUT_L = 0x05, // D |
krobertson | 10:c4745ddaaf6a | 31 | TEMP_OUT_H = 0x06, // D |
krobertson | 10:c4745ddaaf6a | 32 | |
krobertson | 10:c4745ddaaf6a | 33 | STATUS_M = 0x07, // D |
krobertson | 10:c4745ddaaf6a | 34 | |
krobertson | 10:c4745ddaaf6a | 35 | INT_CTRL_M = 0x12, // D |
krobertson | 10:c4745ddaaf6a | 36 | INT_SRC_M = 0x13, // D |
krobertson | 10:c4745ddaaf6a | 37 | INT_THS_L_M = 0x14, // D |
krobertson | 10:c4745ddaaf6a | 38 | INT_THS_H_M = 0x15, // D |
krobertson | 10:c4745ddaaf6a | 39 | |
krobertson | 10:c4745ddaaf6a | 40 | OFFSET_X_L_M = 0x16, // D |
krobertson | 10:c4745ddaaf6a | 41 | OFFSET_X_H_M = 0x17, // D |
krobertson | 10:c4745ddaaf6a | 42 | OFFSET_Y_L_M = 0x18, // D |
krobertson | 10:c4745ddaaf6a | 43 | OFFSET_Y_H_M = 0x19, // D |
krobertson | 10:c4745ddaaf6a | 44 | OFFSET_Z_L_M = 0x1A, // D |
krobertson | 10:c4745ddaaf6a | 45 | OFFSET_Z_H_M = 0x1B, // D |
krobertson | 10:c4745ddaaf6a | 46 | REFERENCE_X = 0x1C, // D |
krobertson | 10:c4745ddaaf6a | 47 | REFERENCE_Y = 0x1D, // D |
krobertson | 10:c4745ddaaf6a | 48 | REFERENCE_Z = 0x1E, // D |
krobertson | 10:c4745ddaaf6a | 49 | |
krobertson | 10:c4745ddaaf6a | 50 | CTRL0 = 0x1F, // D |
krobertson | 10:c4745ddaaf6a | 51 | CTRL1 = 0x20, // D |
krobertson | 10:c4745ddaaf6a | 52 | CTRL_REG1_A = 0x20, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 53 | CTRL2 = 0x21, // D |
krobertson | 10:c4745ddaaf6a | 54 | CTRL_REG2_A = 0x21, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 55 | CTRL3 = 0x22, // D |
krobertson | 10:c4745ddaaf6a | 56 | CTRL_REG3_A = 0x22, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 57 | CTRL4 = 0x23, // D |
krobertson | 10:c4745ddaaf6a | 58 | CTRL_REG4_A = 0x23, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 59 | CTRL5 = 0x24, // D |
krobertson | 10:c4745ddaaf6a | 60 | CTRL_REG5_A = 0x24, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 61 | CTRL6 = 0x25, // D |
krobertson | 10:c4745ddaaf6a | 62 | CTRL_REG6_A = 0x25, // DLHC |
krobertson | 10:c4745ddaaf6a | 63 | HP_FILTER_RESET_A = 0x25, // DLH, DLM |
krobertson | 10:c4745ddaaf6a | 64 | CTRL7 = 0x26, // D |
krobertson | 10:c4745ddaaf6a | 65 | REFERENCE_A = 0x26, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 66 | STATUS_A = 0x27, // D |
krobertson | 10:c4745ddaaf6a | 67 | STATUS_REG_A = 0x27, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 68 | |
krobertson | 10:c4745ddaaf6a | 69 | OUT_X_L_A = 0x28, |
krobertson | 10:c4745ddaaf6a | 70 | OUT_X_H_A = 0x29, |
krobertson | 10:c4745ddaaf6a | 71 | OUT_Y_L_A = 0x2A, |
krobertson | 10:c4745ddaaf6a | 72 | OUT_Y_H_A = 0x2B, |
krobertson | 10:c4745ddaaf6a | 73 | OUT_Z_L_A = 0x2C, |
krobertson | 10:c4745ddaaf6a | 74 | OUT_Z_H_A = 0x2D, |
krobertson | 10:c4745ddaaf6a | 75 | |
krobertson | 10:c4745ddaaf6a | 76 | FIFO_CTRL = 0x2E, // D |
krobertson | 10:c4745ddaaf6a | 77 | FIFO_CTRL_REG_A = 0x2E, // DLHC |
krobertson | 10:c4745ddaaf6a | 78 | FIFO_SRC = 0x2F, // D |
krobertson | 10:c4745ddaaf6a | 79 | FIFO_SRC_REG_A = 0x2F, // DLHC |
krobertson | 10:c4745ddaaf6a | 80 | |
krobertson | 10:c4745ddaaf6a | 81 | IG_CFG1 = 0x30, // D |
krobertson | 10:c4745ddaaf6a | 82 | INT1_CFG_A = 0x30, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 83 | IG_SRC1 = 0x31, // D |
krobertson | 10:c4745ddaaf6a | 84 | INT1_SRC_A = 0x31, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 85 | IG_THS1 = 0x32, // D |
krobertson | 10:c4745ddaaf6a | 86 | INT1_THS_A = 0x32, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 87 | IG_DUR1 = 0x33, // D |
krobertson | 10:c4745ddaaf6a | 88 | INT1_DURATION_A = 0x33, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 89 | IG_CFG2 = 0x34, // D |
krobertson | 10:c4745ddaaf6a | 90 | INT2_CFG_A = 0x34, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 91 | IG_SRC2 = 0x35, // D |
krobertson | 10:c4745ddaaf6a | 92 | INT2_SRC_A = 0x35, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 93 | IG_THS2 = 0x36, // D |
krobertson | 10:c4745ddaaf6a | 94 | INT2_THS_A = 0x36, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 95 | IG_DUR2 = 0x37, // D |
krobertson | 10:c4745ddaaf6a | 96 | INT2_DURATION_A = 0x37, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 97 | |
krobertson | 10:c4745ddaaf6a | 98 | CLICK_CFG = 0x38, // D |
krobertson | 10:c4745ddaaf6a | 99 | CLICK_CFG_A = 0x38, // DLHC |
krobertson | 10:c4745ddaaf6a | 100 | CLICK_SRC = 0x39, // D |
krobertson | 10:c4745ddaaf6a | 101 | CLICK_SRC_A = 0x39, // DLHC |
krobertson | 10:c4745ddaaf6a | 102 | CLICK_THS = 0x3A, // D |
krobertson | 10:c4745ddaaf6a | 103 | CLICK_THS_A = 0x3A, // DLHC |
krobertson | 10:c4745ddaaf6a | 104 | TIME_LIMIT = 0x3B, // D |
krobertson | 10:c4745ddaaf6a | 105 | TIME_LIMIT_A = 0x3B, // DLHC |
krobertson | 10:c4745ddaaf6a | 106 | TIME_LATENCY = 0x3C, // D |
krobertson | 10:c4745ddaaf6a | 107 | TIME_LATENCY_A = 0x3C, // DLHC |
krobertson | 10:c4745ddaaf6a | 108 | TIME_WINDOW = 0x3D, // D |
krobertson | 10:c4745ddaaf6a | 109 | TIME_WINDOW_A = 0x3D, // DLHC |
krobertson | 10:c4745ddaaf6a | 110 | |
krobertson | 10:c4745ddaaf6a | 111 | Act_THS = 0x3E, // D |
krobertson | 10:c4745ddaaf6a | 112 | Act_DUR = 0x3F, // D |
krobertson | 10:c4745ddaaf6a | 113 | |
krobertson | 10:c4745ddaaf6a | 114 | CRA_REG_M = 0x00, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 115 | CRB_REG_M = 0x01, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 116 | MR_REG_M = 0x02, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 117 | |
krobertson | 10:c4745ddaaf6a | 118 | SR_REG_M = 0x09, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 119 | IRA_REG_M = 0x0A, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 120 | IRB_REG_M = 0x0B, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 121 | IRC_REG_M = 0x0C, // DLH, DLM, DLHC |
krobertson | 10:c4745ddaaf6a | 122 | |
krobertson | 10:c4745ddaaf6a | 123 | WHO_AM_I_M = 0x0F, // DLM |
krobertson | 10:c4745ddaaf6a | 124 | WHO_AM_I = 0x0F, // D |
krobertson | 10:c4745ddaaf6a | 125 | |
krobertson | 10:c4745ddaaf6a | 126 | TEMP_OUT_H_M = 0x31, // DLHC |
krobertson | 10:c4745ddaaf6a | 127 | TEMP_OUT_L_M = 0x32, // DLHC |
krobertson | 10:c4745ddaaf6a | 128 | |
krobertson | 10:c4745ddaaf6a | 129 | |
krobertson | 10:c4745ddaaf6a | 130 | // dummy addresses for registers in different locations on different devices; |
krobertson | 10:c4745ddaaf6a | 131 | // the library translates these based on device type |
krobertson | 10:c4745ddaaf6a | 132 | // value with sign flipped is used as index into translated_regs array |
krobertson | 10:c4745ddaaf6a | 133 | |
krobertson | 10:c4745ddaaf6a | 134 | OUT_X_H_M = -1, |
krobertson | 10:c4745ddaaf6a | 135 | OUT_X_L_M = -2, |
krobertson | 10:c4745ddaaf6a | 136 | OUT_Y_H_M = -3, |
krobertson | 10:c4745ddaaf6a | 137 | OUT_Y_L_M = -4, |
krobertson | 10:c4745ddaaf6a | 138 | OUT_Z_H_M = -5, |
krobertson | 10:c4745ddaaf6a | 139 | OUT_Z_L_M = -6, |
krobertson | 10:c4745ddaaf6a | 140 | // update dummy_reg_count if registers are added here! |
krobertson | 10:c4745ddaaf6a | 141 | |
krobertson | 10:c4745ddaaf6a | 142 | // device-specific register addresses |
krobertson | 10:c4745ddaaf6a | 143 | DLH_OUT_X_H_M = 0x03, |
krobertson | 10:c4745ddaaf6a | 144 | DLH_OUT_X_L_M = 0x04, |
krobertson | 10:c4745ddaaf6a | 145 | DLH_OUT_Y_H_M = 0x05, |
krobertson | 10:c4745ddaaf6a | 146 | DLH_OUT_Y_L_M = 0x06, |
krobertson | 10:c4745ddaaf6a | 147 | DLH_OUT_Z_H_M = 0x07, |
krobertson | 10:c4745ddaaf6a | 148 | DLH_OUT_Z_L_M = 0x08, |
krobertson | 10:c4745ddaaf6a | 149 | |
krobertson | 10:c4745ddaaf6a | 150 | DLM_OUT_X_H_M = 0x03, |
krobertson | 10:c4745ddaaf6a | 151 | DLM_OUT_X_L_M = 0x04, |
krobertson | 10:c4745ddaaf6a | 152 | DLM_OUT_Z_H_M = 0x05, |
krobertson | 10:c4745ddaaf6a | 153 | DLM_OUT_Z_L_M = 0x06, |
krobertson | 10:c4745ddaaf6a | 154 | DLM_OUT_Y_H_M = 0x07, |
krobertson | 10:c4745ddaaf6a | 155 | DLM_OUT_Y_L_M = 0x08, |
krobertson | 10:c4745ddaaf6a | 156 | |
krobertson | 10:c4745ddaaf6a | 157 | DLHC_OUT_X_H_M = 0x03, |
krobertson | 10:c4745ddaaf6a | 158 | DLHC_OUT_X_L_M = 0x04, |
krobertson | 10:c4745ddaaf6a | 159 | DLHC_OUT_Z_H_M = 0x05, |
krobertson | 10:c4745ddaaf6a | 160 | DLHC_OUT_Z_L_M = 0x06, |
krobertson | 10:c4745ddaaf6a | 161 | DLHC_OUT_Y_H_M = 0x07, |
krobertson | 10:c4745ddaaf6a | 162 | DLHC_OUT_Y_L_M = 0x08, |
krobertson | 10:c4745ddaaf6a | 163 | |
krobertson | 10:c4745ddaaf6a | 164 | D_OUT_X_L_M = 0x08, |
krobertson | 10:c4745ddaaf6a | 165 | D_OUT_X_H_M = 0x09, |
krobertson | 10:c4745ddaaf6a | 166 | D_OUT_Y_L_M = 0x0A, |
krobertson | 10:c4745ddaaf6a | 167 | D_OUT_Y_H_M = 0x0B, |
krobertson | 10:c4745ddaaf6a | 168 | D_OUT_Z_L_M = 0x0C, |
krobertson | 10:c4745ddaaf6a | 169 | D_OUT_Z_H_M = 0x0D |
krobertson | 10:c4745ddaaf6a | 170 | }; |
krobertson | 10:c4745ddaaf6a | 171 | |
krobertson | 10:c4745ddaaf6a | 172 | /** |
krobertson | 10:c4745ddaaf6a | 173 | * \brief accelerometer readings |
krobertson | 10:c4745ddaaf6a | 174 | **/ |
krobertson | 10:c4745ddaaf6a | 175 | vector<int16_t> a; |
krobertson | 10:c4745ddaaf6a | 176 | /** |
krobertson | 10:c4745ddaaf6a | 177 | * \brief magnetometer readings |
krobertson | 10:c4745ddaaf6a | 178 | **/ |
krobertson | 10:c4745ddaaf6a | 179 | vector<int16_t> m; |
krobertson | 10:c4745ddaaf6a | 180 | /** |
krobertson | 10:c4745ddaaf6a | 181 | * \brief maximum magnetometer values (calibration values) |
krobertson | 10:c4745ddaaf6a | 182 | **/ |
krobertson | 10:c4745ddaaf6a | 183 | vector<int16_t> m_max; |
krobertson | 10:c4745ddaaf6a | 184 | /** |
krobertson | 10:c4745ddaaf6a | 185 | * \brief minimum magnetometer values (calibration values) |
krobertson | 10:c4745ddaaf6a | 186 | **/ |
krobertson | 10:c4745ddaaf6a | 187 | vector<int16_t> m_min; |
krobertson | 10:c4745ddaaf6a | 188 | |
krobertson | 10:c4745ddaaf6a | 189 | /** |
krobertson | 10:c4745ddaaf6a | 190 | * \brief Compass constructor |
krobertson | 10:c4745ddaaf6a | 191 | **/ |
krobertson | 10:c4745ddaaf6a | 192 | Compass(void); |
krobertson | 10:c4745ddaaf6a | 193 | |
krobertson | 10:c4745ddaaf6a | 194 | /** |
krobertson | 10:c4745ddaaf6a | 195 | * \brief setup SPI, determine device type, and setup register addresses for device |
krobertson | 10:c4745ddaaf6a | 196 | **/ |
krobertson | 10:c4745ddaaf6a | 197 | bool init(deviceType device = device_auto); |
krobertson | 10:c4745ddaaf6a | 198 | |
krobertson | 10:c4745ddaaf6a | 199 | /** |
krobertson | 10:c4745ddaaf6a | 200 | * \brief get the device type |
krobertson | 10:c4745ddaaf6a | 201 | **/ |
krobertson | 10:c4745ddaaf6a | 202 | int getDeviceType(void) { return _device; } |
krobertson | 10:c4745ddaaf6a | 203 | |
krobertson | 10:c4745ddaaf6a | 204 | /** |
krobertson | 10:c4745ddaaf6a | 205 | * \brief enable default settings (writes default values to control registers) |
krobertson | 10:c4745ddaaf6a | 206 | **/ |
krobertson | 10:c4745ddaaf6a | 207 | void enableDefault(void); |
krobertson | 10:c4745ddaaf6a | 208 | |
krobertson | 10:c4745ddaaf6a | 209 | /** |
krobertson | 10:c4745ddaaf6a | 210 | * \brief write to an accelerometer register |
krobertson | 10:c4745ddaaf6a | 211 | **/ |
krobertson | 10:c4745ddaaf6a | 212 | void writeAccReg(regAddr reg, int value); |
krobertson | 10:c4745ddaaf6a | 213 | int readAccReg(regAddr reg); |
krobertson | 10:c4745ddaaf6a | 214 | void writeMagReg(regAddr reg, int value); |
krobertson | 10:c4745ddaaf6a | 215 | int readMagReg(regAddr reg); |
krobertson | 10:c4745ddaaf6a | 216 | |
krobertson | 10:c4745ddaaf6a | 217 | void writeReg(regAddr reg, int value); |
krobertson | 10:c4745ddaaf6a | 218 | int readReg(regAddr reg); |
krobertson | 10:c4745ddaaf6a | 219 | |
krobertson | 10:c4745ddaaf6a | 220 | void readAcc(void); |
krobertson | 10:c4745ddaaf6a | 221 | void readMag(void); |
krobertson | 10:c4745ddaaf6a | 222 | void read(void); |
krobertson | 10:c4745ddaaf6a | 223 | |
krobertson | 10:c4745ddaaf6a | 224 | float get_heading(void); |
krobertson | 10:c4745ddaaf6a | 225 | template <typename T> float get_heading(vector<T> from); |
krobertson | 10:c4745ddaaf6a | 226 | |
krobertson | 10:c4745ddaaf6a | 227 | // vector functions |
krobertson | 10:c4745ddaaf6a | 228 | template <typename Ta, typename Tb, typename To> static void vector_cross(const vector<Ta> *a, const vector<Tb> *b, vector<To> *out); |
krobertson | 10:c4745ddaaf6a | 229 | template <typename Ta, typename Tb> static float vector_dot(const vector<Ta> *a,const vector<Tb> *b); |
krobertson | 10:c4745ddaaf6a | 230 | static void vector_normalize(vector<float> *a); |
krobertson | 10:c4745ddaaf6a | 231 | |
krobertson | 10:c4745ddaaf6a | 232 | deviceType _device; // chip type (DLH, DLM, or DLHC) |
krobertson | 10:c4745ddaaf6a | 233 | |
krobertson | 10:c4745ddaaf6a | 234 | private: |
krobertson | 10:c4745ddaaf6a | 235 | static const int dummy_reg_count = 6; |
krobertson | 10:c4745ddaaf6a | 236 | regAddr translated_regs[dummy_reg_count + 1]; // index 0 not used |
krobertson | 10:c4745ddaaf6a | 237 | |
krobertson | 10:c4745ddaaf6a | 238 | int testReg(regAddr reg); |
krobertson | 10:c4745ddaaf6a | 239 | }; |
krobertson | 10:c4745ddaaf6a | 240 | |
krobertson | 10:c4745ddaaf6a | 241 | #endif |