fsdfds
Dependencies: BLE_API mbed-dev-bin nRF51822
Fork of microbit-dal by
MicroBitCompass.h
00001 /* 00002 The MIT License (MIT) 00003 00004 Copyright (c) 2016 British Broadcasting Corporation. 00005 This software is provided by Lancaster University by arrangement with the BBC. 00006 00007 Permission is hereby granted, free of charge, to any person obtaining a 00008 copy of this software and associated documentation files (the "Software"), 00009 to deal in the Software without restriction, including without limitation 00010 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00011 and/or sell copies of the Software, and to permit persons to whom the 00012 Software is furnished to do so, subject to the following conditions: 00013 00014 The above copyright notice and this permission notice shall be included in 00015 all copies or substantial portions of the Software. 00016 00017 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00018 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00019 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 00020 THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00021 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00022 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00023 DEALINGS IN THE SOFTWARE. 00024 */ 00025 00026 #ifndef MICROBIT_COMPASS_H 00027 #define MICROBIT_COMPASS_H 00028 00029 #include "mbed.h" 00030 #include "MicroBitConfig.h" 00031 #include "MicroBitComponent.h" 00032 #include "MicroBitCoordinateSystem.h" 00033 #include "MicroBitAccelerometer.h" 00034 #include "MicroBitStorage.h" 00035 00036 /** 00037 * Relevant pin assignments 00038 */ 00039 #define MICROBIT_PIN_COMPASS_DATA_READY P0_29 00040 00041 /** 00042 * I2C constants 00043 */ 00044 #define MAG3110_DEFAULT_ADDR 0x1D 00045 00046 /** 00047 * MAG3110 Register map 00048 */ 00049 #define MAG_DR_STATUS 0x00 00050 #define MAG_OUT_X_MSB 0x01 00051 #define MAG_OUT_X_LSB 0x02 00052 #define MAG_OUT_Y_MSB 0x03 00053 #define MAG_OUT_Y_LSB 0x04 00054 #define MAG_OUT_Z_MSB 0x05 00055 #define MAG_OUT_Z_LSB 0x06 00056 #define MAG_WHOAMI 0x07 00057 #define MAG_SYSMOD 0x08 00058 #define MAG_OFF_X_MSB 0x09 00059 #define MAG_OFF_X_LSB 0x0A 00060 #define MAG_OFF_Y_MSB 0x0B 00061 #define MAG_OFF_Y_LSB 0x0C 00062 #define MAG_OFF_Z_MSB 0x0D 00063 #define MAG_OFF_Z_LSB 0x0E 00064 #define MAG_DIE_TEMP 0x0F 00065 #define MAG_CTRL_REG1 0x10 00066 #define MAG_CTRL_REG2 0x11 00067 00068 /** 00069 * Configuration options 00070 */ 00071 struct MAG3110SampleRateConfig 00072 { 00073 uint32_t sample_period; 00074 uint8_t ctrl_reg1; 00075 }; 00076 00077 extern const MAG3110SampleRateConfig MAG3110SampleRate[]; 00078 00079 #define MAG3110_SAMPLE_RATES 11 00080 00081 /** 00082 * Compass events 00083 */ 00084 #define MICROBIT_COMPASS_EVT_CAL_REQUIRED 1 // DEPRECATED 00085 #define MICROBIT_COMPASS_EVT_CAL_START 2 // DEPRECATED 00086 #define MICROBIT_COMPASS_EVT_CAL_END 3 // DEPRECATED 00087 00088 #define MICROBIT_COMPASS_EVT_DATA_UPDATE 4 00089 #define MICROBIT_COMPASS_EVT_CONFIG_NEEDED 5 00090 #define MICROBIT_COMPASS_EVT_CALIBRATE 6 00091 00092 /** 00093 * Status Bits 00094 */ 00095 #define MICROBIT_COMPASS_STATUS_CALIBRATED 2 00096 #define MICROBIT_COMPASS_STATUS_CALIBRATING 4 00097 #define MICROBIT_COMPASS_STATUS_ADDED_TO_IDLE 8 00098 00099 /** 00100 * Term to convert sample data into SI units 00101 */ 00102 #define MAG3110_NORMALIZE_SAMPLE(x) (100*x) 00103 00104 /** 00105 * MAG3110 MAGIC ID value 00106 * Returned from the MAG_WHO_AM_I register for ID purposes. 00107 */ 00108 #define MAG3110_WHOAMI_VAL 0xC4 00109 00110 struct CompassSample 00111 { 00112 int x; 00113 int y; 00114 int z; 00115 00116 CompassSample() 00117 { 00118 this->x = 0; 00119 this->y = 0; 00120 this->z = 0; 00121 } 00122 00123 CompassSample(int x, int y, int z) 00124 { 00125 this->x = x; 00126 this->y = y; 00127 this->z = z; 00128 } 00129 00130 bool operator==(const CompassSample& other) const 00131 { 00132 return x == other.x && y == other.y && z == other.z; 00133 } 00134 00135 bool operator!=(const CompassSample& other) const 00136 { 00137 return !(x == other.x && y == other.y && z == other.z); 00138 } 00139 }; 00140 00141 /** 00142 * Class definition for MicroBit Compass. 00143 * 00144 * Represents an implementation of the Freescale MAG3110 I2C Magnetmometer. 00145 * Also includes basic caching, calibration and on demand activation. 00146 */ 00147 class MicroBitCompass : public MicroBitComponent 00148 { 00149 uint16_t address; // I2C address of the magnetmometer. 00150 uint16_t samplePeriod; // The time between samples, in millseconds. 00151 00152 CompassSample average; // Centre point of sample data. 00153 CompassSample sample; // The latest sample data recorded. 00154 DigitalIn int1; // Data ready interrupt. 00155 MicroBitI2C& i2c; // The I2C interface the sensor is connected to. 00156 MicroBitAccelerometer* accelerometer; // The accelerometer to use for tilt compensation. 00157 MicroBitStorage* storage; // An instance of MicroBitStorage used for persistence. 00158 00159 public: 00160 00161 /** 00162 * Constructor. 00163 * Create a software representation of an e-compass. 00164 * 00165 * @param _i2c an instance of i2c, which the compass is accessible from. 00166 * 00167 * @param _accelerometer an instance of the accelerometer, used for tilt compensation. 00168 * 00169 * @param _storage an instance of MicroBitStorage, used to persist calibration data across resets. 00170 * 00171 * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR. 00172 * 00173 * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR. 00174 * 00175 * @code 00176 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00177 * 00178 * MicroBitAccelerometer accelerometer(i2c); 00179 * 00180 * MicroBitStorage storage; 00181 * 00182 * MicroBitCompass compass(i2c, accelerometer, storage); 00183 * @endcode 00184 */ 00185 MicroBitCompass(MicroBitI2C& _i2c, MicroBitAccelerometer& _accelerometer, MicroBitStorage& _storage, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS); 00186 00187 /** 00188 * Constructor. 00189 * Create a software representation of an e-compass. 00190 * 00191 * @param _i2c an instance of i2c, which the compass is accessible from. 00192 * 00193 * @param _accelerometer an instance of the accelerometer, used for tilt compensation. 00194 * 00195 * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR. 00196 * 00197 * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR. 00198 * 00199 * @code 00200 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00201 * 00202 * MicroBitAccelerometer accelerometer(i2c); 00203 * 00204 * MicroBitCompass compass(i2c, accelerometer, storage); 00205 * @endcode 00206 */ 00207 MicroBitCompass(MicroBitI2C& _i2c, MicroBitAccelerometer& _accelerometer, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS); 00208 00209 /** 00210 * Constructor. 00211 * Create a software representation of an e-compass. 00212 * 00213 * @param _i2c an instance of i2c, which the compass is accessible from. 00214 * 00215 * @param _storage an instance of MicroBitStorage, used to persist calibration data across resets. 00216 * 00217 * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR. 00218 * 00219 * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR. 00220 * 00221 * @code 00222 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00223 * 00224 * MicroBitStorage storage; 00225 * 00226 * MicroBitCompass compass(i2c, storage); 00227 * @endcode 00228 */ 00229 MicroBitCompass(MicroBitI2C& _i2c, MicroBitStorage& _storage, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS); 00230 00231 /** 00232 * Constructor. 00233 * Create a software representation of an e-compass. 00234 * 00235 * @param _i2c an instance of i2c, which the compass is accessible from. 00236 * 00237 * @param address the default address for the compass register on the i2c bus. Defaults to MAG3110_DEFAULT_ADDR. 00238 * 00239 * @param id the ID of the new MicroBitCompass object. Defaults to MAG3110_DEFAULT_ADDR. 00240 * 00241 * @code 00242 * MicroBitI2C i2c(I2C_SDA0, I2C_SCL0); 00243 * 00244 * MicroBitCompass compass(i2c); 00245 * @endcode 00246 */ 00247 MicroBitCompass(MicroBitI2C& _i2c, uint16_t address = MAG3110_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_COMPASS); 00248 00249 /** 00250 * Configures the compass for the sample rate defined in this object. 00251 * The nearest values are chosen to those defined that are supported by the hardware. 00252 * The instance variables are then updated to reflect reality. 00253 * 00254 * @return MICROBIT_OK or MICROBIT_I2C_ERROR if the magnetometer could not be configured. 00255 */ 00256 int configure(); 00257 00258 /** 00259 * Attempts to set the sample rate of the compass to the specified value (in ms). 00260 * 00261 * @param period the requested time between samples, in milliseconds. 00262 * 00263 * @return MICROBIT_OK or MICROBIT_I2C_ERROR if the magnetometer could not be updated. 00264 * 00265 * @code 00266 * // sample rate is now 20 ms. 00267 * compass.setPeriod(20); 00268 * @endcode 00269 * 00270 * @note The requested rate may not be possible on the hardware. In this case, the 00271 * nearest lower rate is chosen. 00272 */ 00273 int setPeriod(int period); 00274 00275 /** 00276 * Reads the currently configured sample rate of the compass. 00277 * 00278 * @return The time between samples, in milliseconds. 00279 */ 00280 int getPeriod(); 00281 00282 /** 00283 * Gets the current heading of the device, relative to magnetic north. 00284 * 00285 * If the compass is not calibrated, it will raise the MICROBIT_COMPASS_EVT_CALIBRATE event. 00286 * 00287 * Users wishing to implement their own calibration algorithms should listen for this event, 00288 * using MESSAGE_BUS_LISTENER_IMMEDIATE model. This ensures that calibration is complete before 00289 * the user program continues. 00290 * 00291 * @return the current heading, in degrees. Or MICROBIT_CALIBRATION_IN_PROGRESS if the compass is calibrating. 00292 * 00293 * @code 00294 * compass.heading(); 00295 * @endcode 00296 */ 00297 int heading(); 00298 00299 /** 00300 * Attempts to read the 8 bit ID from the magnetometer, this can be used for 00301 * validation purposes. 00302 * 00303 * @return the 8 bit ID returned by the magnetometer, or MICROBIT_I2C_ERROR if the request fails. 00304 * 00305 * @code 00306 * compass.whoAmI(); 00307 * @endcode 00308 */ 00309 int whoAmI(); 00310 00311 /** 00312 * Reads the value of the X axis from the latest update retrieved from the magnetometer. 00313 * 00314 * @param system The coordinate system to use. By default, a simple cartesian system is provided. 00315 * 00316 * @return The magnetic force measured in the X axis, in nano teslas. 00317 * 00318 * @code 00319 * compass.getX(); 00320 * @endcode 00321 */ 00322 int getX(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN); 00323 00324 /** 00325 * Reads the value of the Y axis from the latest update retrieved from the magnetometer. 00326 * 00327 * @param system The coordinate system to use. By default, a simple cartesian system is provided. 00328 * 00329 * @return The magnetic force measured in the Y axis, in nano teslas. 00330 * 00331 * @code 00332 * compass.getY(); 00333 * @endcode 00334 */ 00335 int getY(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN); 00336 00337 /** 00338 * Reads the value of the Z axis from the latest update retrieved from the magnetometer. 00339 * 00340 * @param system The coordinate system to use. By default, a simple cartesian system is provided. 00341 * 00342 * @return The magnetic force measured in the Z axis, in nano teslas. 00343 * 00344 * @code 00345 * compass.getZ(); 00346 * @endcode 00347 */ 00348 int getZ(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN); 00349 00350 /** 00351 * Determines the overall magnetic field strength based on the latest update from the magnetometer. 00352 * 00353 * @return The magnetic force measured across all axis, in nano teslas. 00354 * 00355 * @code 00356 * compass.getFieldStrength(); 00357 * @endcode 00358 */ 00359 int getFieldStrength(); 00360 00361 /** 00362 * Reads the current die temperature of the compass. 00363 * 00364 * @return the temperature in degrees celsius, or MICROBIT_I2C_ERROR if the temperature reading could not be retreived 00365 * from the accelerometer. 00366 */ 00367 int readTemperature(); 00368 00369 /** 00370 * Perform a calibration of the compass. 00371 * 00372 * This method will be called automatically if a user attempts to read a compass value when 00373 * the compass is uncalibrated. It can also be called at any time by the user. 00374 * 00375 * The method will only return once the compass has been calibrated. 00376 * 00377 * @return MICROBIT_OK, MICROBIT_I2C_ERROR if the magnetometer could not be accessed, 00378 * or MICROBIT_CALIBRATION_REQUIRED if the calibration algorithm failed to complete successfully. 00379 * 00380 * @note THIS MUST BE CALLED TO GAIN RELIABLE VALUES FROM THE COMPASS 00381 */ 00382 int calibrate(); 00383 00384 /** 00385 * Configure the compass to use the calibration data that is supplied to this call. 00386 * 00387 * Calibration data is comprised of the perceived zero offset of each axis of the compass. 00388 * 00389 * After calibration this should now take into account trimming errors in the magnetometer, 00390 * and any "hard iron" offsets on the device. 00391 * 00392 * @param calibration A CompassSample containing the offsets for the x, y and z axis. 00393 */ 00394 void setCalibration(CompassSample calibration); 00395 00396 /** 00397 * Provides the calibration data currently in use by the compass. 00398 * 00399 * More specifically, the x, y and z zero offsets of the compass. 00400 * 00401 * @return calibration A CompassSample containing the offsets for the x, y and z axis. 00402 */ 00403 CompassSample getCalibration(); 00404 00405 /** 00406 * Updates the local sample, only if the compass indicates that 00407 * data is stale. 00408 * 00409 * @note Can be used to trigger manual updates, if the device is running without a scheduler. 00410 * Also called internally by all get[X,Y,Z]() member functions. 00411 */ 00412 int updateSample(); 00413 00414 /** 00415 * Periodic callback from MicroBit idle thread. 00416 * 00417 * Calls updateSample(). 00418 */ 00419 virtual void idleTick(); 00420 00421 /** 00422 * Returns 0 or 1. 1 indicates that the compass is calibrated, zero means the compass requires calibration. 00423 */ 00424 int isCalibrated(); 00425 00426 /** 00427 * Returns 0 or 1. 1 indicates that the compass is calibrating, zero means the compass is not currently calibrating. 00428 */ 00429 int isCalibrating(); 00430 00431 /** 00432 * Clears the calibration held in persistent storage, and sets the calibrated flag to zero. 00433 */ 00434 void clearCalibration(); 00435 00436 /** 00437 * Destructor for MicroBitCompass, where we deregister this instance from the array of fiber components. 00438 */ 00439 ~MicroBitCompass(); 00440 00441 private: 00442 00443 /** 00444 * Issues a standard, 2 byte I2C command write to the accelerometer. 00445 * 00446 * Blocks the calling thread until complete. 00447 * 00448 * @param reg The address of the register to write to. 00449 * 00450 * @param value The value to write. 00451 * 00452 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed. 00453 */ 00454 int writeCommand(uint8_t reg, uint8_t value); 00455 00456 /** 00457 * Issues a read command, copying data into the specified buffer. 00458 * 00459 * Blocks the calling thread until complete. 00460 * 00461 * @param reg The address of the register to access. 00462 * 00463 * @param buffer Memory area to read the data into. 00464 * 00465 * @param length The number of bytes to read. 00466 * 00467 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed. 00468 */ 00469 int readCommand(uint8_t reg, uint8_t* buffer, int length); 00470 00471 /** 00472 * Issues a read of a given address, and returns the value. 00473 * 00474 * Blocks the calling thread until complete. 00475 * 00476 * @param reg The address of the 16 bit register to access. 00477 * 00478 * @return The register value, interpreted as a 16 but signed value, or MICROBIT_I2C_ERROR if the magnetometer could not be accessed. 00479 */ 00480 int read16(uint8_t reg); 00481 00482 /** 00483 * Issues a read of a given address, and returns the value. 00484 * 00485 * Blocks the calling thread until complete. 00486 * 00487 * @param reg The address of the 16 bit register to access. 00488 * 00489 * @return The register value, interpreted as a 8 bit unsigned value, or MICROBIT_I2C_ERROR if the magnetometer could not be accessed. 00490 */ 00491 int read8(uint8_t reg); 00492 00493 /** 00494 * Calculates a tilt compensated bearing of the device, using the accelerometer. 00495 */ 00496 int tiltCompensatedBearing(); 00497 00498 /** 00499 * Calculates a non-tilt compensated bearing of the device. 00500 */ 00501 int basicBearing(); 00502 00503 /** 00504 * An initialisation member function used by the many constructors of MicroBitCompass. 00505 * 00506 * @param id the unique identifier for this compass instance. 00507 * 00508 * @param address the base address of the magnetometer on the i2c bus. 00509 */ 00510 void init(uint16_t id, uint16_t address); 00511 }; 00512 00513 #endif
Generated on Wed Jul 13 2022 00:58:03 by 1.7.2