Attempting to publish a tree
Dependencies: BLE_API mbed-dev-bin nRF51822
Fork of microbit-dal by
MicroBitAccelerometer.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_ACCELEROMETER_H 00027 #define MICROBIT_ACCELEROMETER_H 00028 00029 #include "mbed.h" 00030 #include "MicroBitConfig.h" 00031 #include "MicroBitComponent.h" 00032 #include "MicroBitCoordinateSystem.h" 00033 #include "MicroBitI2C.h" 00034 00035 /** 00036 * Relevant pin assignments 00037 */ 00038 #define MICROBIT_PIN_ACCEL_DATA_READY P0_28 00039 00040 /** 00041 * Status flags 00042 */ 00043 #define MICROBIT_ACCEL_PITCH_ROLL_VALID 0x02 00044 #define MICROBIT_ACCEL_ADDED_TO_IDLE 0x04 00045 00046 /** 00047 * I2C constants 00048 */ 00049 #define MMA8653_DEFAULT_ADDR 0x3A 00050 00051 /** 00052 * MMA8653 Register map (partial) 00053 */ 00054 #define MMA8653_STATUS 0x00 00055 #define MMA8653_OUT_X_MSB 0x01 00056 #define MMA8653_WHOAMI 0x0D 00057 #define MMA8653_XYZ_DATA_CFG 0x0E 00058 #define MMA8653_CTRL_REG1 0x2A 00059 #define MMA8653_CTRL_REG2 0x2B 00060 #define MMA8653_CTRL_REG3 0x2C 00061 #define MMA8653_CTRL_REG4 0x2D 00062 #define MMA8653_CTRL_REG5 0x2E 00063 00064 00065 /** 00066 * MMA8653 constants 00067 */ 00068 #define MMA8653_WHOAMI_VAL 0x5A 00069 00070 #define MMA8653_SAMPLE_RANGES 3 00071 #define MMA8653_SAMPLE_RATES 8 00072 00073 /** 00074 * Accelerometer events 00075 */ 00076 #define MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE 1 00077 00078 /** 00079 * Gesture events 00080 */ 00081 #define MICROBIT_ACCELEROMETER_EVT_TILT_UP 1 00082 #define MICROBIT_ACCELEROMETER_EVT_TILT_DOWN 2 00083 #define MICROBIT_ACCELEROMETER_EVT_TILT_LEFT 3 00084 #define MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT 4 00085 #define MICROBIT_ACCELEROMETER_EVT_FACE_UP 5 00086 #define MICROBIT_ACCELEROMETER_EVT_FACE_DOWN 6 00087 #define MICROBIT_ACCELEROMETER_EVT_FREEFALL 7 00088 #define MICROBIT_ACCELEROMETER_EVT_3G 8 00089 #define MICROBIT_ACCELEROMETER_EVT_6G 9 00090 #define MICROBIT_ACCELEROMETER_EVT_8G 10 00091 #define MICROBIT_ACCELEROMETER_EVT_SHAKE 11 00092 00093 /** 00094 * Gesture recogniser constants 00095 */ 00096 #define MICROBIT_ACCELEROMETER_REST_TOLERANCE 200 00097 #define MICROBIT_ACCELEROMETER_TILT_TOLERANCE 200 00098 #define MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE 400 00099 #define MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE 1000 00100 #define MICROBIT_ACCELEROMETER_3G_TOLERANCE 3072 00101 #define MICROBIT_ACCELEROMETER_6G_TOLERANCE 6144 00102 #define MICROBIT_ACCELEROMETER_8G_TOLERANCE 8192 00103 #define MICROBIT_ACCELEROMETER_GESTURE_DAMPING 10 00104 #define MICROBIT_ACCELEROMETER_SHAKE_DAMPING 10 00105 00106 #define MICROBIT_ACCELEROMETER_REST_THRESHOLD (MICROBIT_ACCELEROMETER_REST_TOLERANCE * MICROBIT_ACCELEROMETER_REST_TOLERANCE) 00107 #define MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD (MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE * MICROBIT_ACCELEROMETER_FREEFALL_TOLERANCE) 00108 #define MICROBIT_ACCELEROMETER_3G_THRESHOLD (MICROBIT_ACCELEROMETER_3G_TOLERANCE * MICROBIT_ACCELEROMETER_3G_TOLERANCE) 00109 #define MICROBIT_ACCELEROMETER_6G_THRESHOLD (MICROBIT_ACCELEROMETER_6G_TOLERANCE * MICROBIT_ACCELEROMETER_6G_TOLERANCE) 00110 #define MICROBIT_ACCELEROMETER_8G_THRESHOLD (MICROBIT_ACCELEROMETER_8G_TOLERANCE * MICROBIT_ACCELEROMETER_8G_TOLERANCE) 00111 #define MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD 4 00112 00113 struct MMA8653Sample 00114 { 00115 int16_t x; 00116 int16_t y; 00117 int16_t z; 00118 }; 00119 00120 struct MMA8653SampleRateConfig 00121 { 00122 uint32_t sample_period; 00123 uint8_t ctrl_reg1; 00124 }; 00125 00126 struct MMA8653SampleRangeConfig 00127 { 00128 uint8_t sample_range; 00129 uint8_t xyz_data_cfg; 00130 }; 00131 00132 00133 extern const MMA8653SampleRangeConfig MMA8653SampleRange[]; 00134 extern const MMA8653SampleRateConfig MMA8653SampleRate[]; 00135 00136 enum BasicGesture 00137 { 00138 GESTURE_NONE, 00139 GESTURE_UP, 00140 GESTURE_DOWN, 00141 GESTURE_LEFT, 00142 GESTURE_RIGHT, 00143 GESTURE_FACE_UP, 00144 GESTURE_FACE_DOWN, 00145 GESTURE_FREEFALL, 00146 GESTURE_3G, 00147 GESTURE_6G, 00148 GESTURE_8G, 00149 GESTURE_SHAKE 00150 }; 00151 00152 struct ShakeHistory 00153 { 00154 uint16_t shaken:1, 00155 x:1, 00156 y:1, 00157 z:1, 00158 count:4, 00159 timer:8; 00160 }; 00161 00162 /** 00163 * Class definition for MicroBit Accelerometer. 00164 * 00165 * Represents an implementation of the Freescale MMA8653 3 axis accelerometer 00166 * Also includes basic data caching and on demand activation. 00167 */ 00168 class MicroBitAccelerometer : public MicroBitComponent 00169 { 00170 uint16_t address; // I2C address of this accelerometer. 00171 uint16_t samplePeriod; // The time between samples, in milliseconds. 00172 uint8_t sampleRange; // The sample range of the accelerometer in g. 00173 MMA8653Sample sample; // The last sample read. 00174 DigitalIn int1; // Data ready interrupt. 00175 float pitch; // Pitch of the device, in radians. 00176 MicroBitI2C& i2c; // The I2C interface to use. 00177 float roll; // Roll of the device, in radians. 00178 uint8_t sigma; // the number of ticks that the instantaneous gesture has been stable. 00179 BasicGesture lastGesture; // the last, stable gesture recorded. 00180 BasicGesture currentGesture; // the instantaneous, unfiltered gesture detected. 00181 ShakeHistory shake; // State information needed to detect shake events. 00182 00183 public: 00184 00185 /** 00186 * Constructor. 00187 * Create a software abstraction of an accelerometer. 00188 * 00189 * @param _i2c an instance of MicroBitI2C used to communicate with the onboard accelerometer. 00190 * 00191 * @param address the default I2C address of the accelerometer. Defaults to: MMA8653_DEFAULT_ADDR. 00192 * 00193 * @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER 00194 * 00195 * @code 00196 * MicroBitI2C i2c = MicroBitI2C(I2C_SDA0, I2C_SCL0); 00197 * 00198 * MicroBitAccelerometer accelerometer = MicroBitAccelerometer(i2c); 00199 * @endcode 00200 */ 00201 MicroBitAccelerometer(MicroBitI2C &_i2c, uint16_t address = MMA8653_DEFAULT_ADDR, uint16_t id = MICROBIT_ID_ACCELEROMETER); 00202 00203 /** 00204 * Configures the accelerometer for G range and sample rate defined 00205 * in this object. The nearest values are chosen to those defined 00206 * that are supported by the hardware. The instance variables are then 00207 * updated to reflect reality. 00208 * 00209 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured. 00210 */ 00211 int configure(); 00212 00213 /** 00214 * Reads the acceleration data from the accelerometer, and stores it in our buffer. 00215 * This only happens if the accelerometer indicates that it has new data via int1. 00216 * 00217 * On first use, this member function will attempt to add this component to the 00218 * list of fiber components in order to constantly update the values stored 00219 * by this object. 00220 * 00221 * This technique is called lazy instantiation, and it means that we do not 00222 * obtain the overhead from non-chalantly adding this component to fiber components. 00223 * 00224 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the read request fails. 00225 */ 00226 int updateSample(); 00227 00228 /** 00229 * Attempts to set the sample rate of the accelerometer to the specified value (in ms). 00230 * 00231 * @param period the requested time between samples, in milliseconds. 00232 * 00233 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails. 00234 * 00235 * @code 00236 * // sample rate is now 20 ms. 00237 * accelerometer.setPeriod(20); 00238 * @endcode 00239 * 00240 * @note The requested rate may not be possible on the hardware. In this case, the 00241 * nearest lower rate is chosen. 00242 */ 00243 int setPeriod(int period); 00244 00245 /** 00246 * Reads the currently configured sample rate of the accelerometer. 00247 * 00248 * @return The time between samples, in milliseconds. 00249 */ 00250 int getPeriod(); 00251 00252 /** 00253 * Attempts to set the sample range of the accelerometer to the specified value (in g). 00254 * 00255 * @param range The requested sample range of samples, in g. 00256 * 00257 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails. 00258 * 00259 * @code 00260 * // the sample range of the accelerometer is now 8G. 00261 * accelerometer.setRange(8); 00262 * @endcode 00263 * 00264 * @note The requested range may not be possible on the hardware. In this case, the 00265 * nearest lower range is chosen. 00266 */ 00267 int setRange(int range); 00268 00269 /** 00270 * Reads the currently configured sample range of the accelerometer. 00271 * 00272 * @return The sample range, in g. 00273 */ 00274 int getRange(); 00275 00276 /** 00277 * Attempts to read the 8 bit ID from the accelerometer, this can be used for 00278 * validation purposes. 00279 * 00280 * @return the 8 bit ID returned by the accelerometer, or MICROBIT_I2C_ERROR if the request fails. 00281 * 00282 * @code 00283 * accelerometer.whoAmI(); 00284 * @endcode 00285 */ 00286 int whoAmI(); 00287 00288 /** 00289 * Reads the value of the X axis from the latest update retrieved from the accelerometer. 00290 * 00291 * @param system The coordinate system to use. By default, a simple cartesian system is provided. 00292 * 00293 * @return The force measured in the X axis, in milli-g. 00294 * 00295 * @code 00296 * accelerometer.getX(); 00297 * @endcode 00298 */ 00299 int getX(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN); 00300 00301 /** 00302 * Reads the value of the Y axis from the latest update retrieved from the accelerometer. 00303 * 00304 * @return The force measured in the Y axis, in milli-g. 00305 * 00306 * @code 00307 * accelerometer.getY(); 00308 * @endcode 00309 */ 00310 int getY(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN); 00311 00312 /** 00313 * Reads the value of the Z axis from the latest update retrieved from the accelerometer. 00314 * 00315 * @return The force measured in the Z axis, in milli-g. 00316 * 00317 * @code 00318 * accelerometer.getZ(); 00319 * @endcode 00320 */ 00321 int getZ(MicroBitCoordinateSystem system = SIMPLE_CARTESIAN); 00322 00323 /** 00324 * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer. 00325 * 00326 * @return The pitch of the device, in degrees. 00327 * 00328 * @code 00329 * accelerometer.getPitch(); 00330 * @endcode 00331 */ 00332 int getPitch(); 00333 00334 /** 00335 * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer. 00336 * 00337 * @return The pitch of the device, in radians. 00338 * 00339 * @code 00340 * accelerometer.getPitchRadians(); 00341 * @endcode 00342 */ 00343 float getPitchRadians(); 00344 00345 /** 00346 * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer. 00347 * 00348 * @return The roll of the device, in degrees. 00349 * 00350 * @code 00351 * accelerometer.getRoll(); 00352 * @endcode 00353 */ 00354 int getRoll(); 00355 00356 /** 00357 * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer. 00358 * 00359 * @return The roll of the device, in radians. 00360 * 00361 * @code 00362 * accelerometer.getRollRadians(); 00363 * @endcode 00364 */ 00365 float getRollRadians(); 00366 00367 /** 00368 * Retrieves the last recorded gesture. 00369 * 00370 * @return The last gesture that was detected. 00371 * 00372 * Example: 00373 * @code 00374 * MicroBitDisplay display; 00375 * 00376 * if (accelerometer.getGesture() == SHAKE) 00377 * display.scroll("SHAKE!"); 00378 * @endcode 00379 */ 00380 BasicGesture getGesture(); 00381 00382 /** 00383 * A periodic callback invoked by the fiber scheduler idle thread. 00384 * 00385 * Internally calls updateSample(). 00386 */ 00387 virtual void idleTick(); 00388 00389 /** 00390 * Returns 0 or 1. 1 indicates data is waiting to be read, zero means data is not ready to be read. 00391 * 00392 * We check if any data is ready for reading by checking the interrupt flag on the accelerometer. 00393 */ 00394 virtual int isIdleCallbackNeeded(); 00395 00396 /** 00397 * Destructor for MicroBitButton, where we deregister this instance from the array of fiber components. 00398 */ 00399 ~MicroBitAccelerometer(); 00400 00401 private: 00402 00403 /** 00404 * Issues a standard, 2 byte I2C command write to the accelerometer. 00405 * 00406 * Blocks the calling thread until complete. 00407 * 00408 * @param reg The address of the register to write to. 00409 * 00410 * @param value The value to write. 00411 * 00412 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed. 00413 */ 00414 int writeCommand(uint8_t reg, uint8_t value); 00415 00416 /** 00417 * Issues a read command, copying data into the specified buffer. 00418 * 00419 * Blocks the calling thread until complete. 00420 * 00421 * @param reg The address of the register to access. 00422 * 00423 * @param buffer Memory area to read the data into. 00424 * 00425 * @param length The number of bytes to read. 00426 * 00427 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed. 00428 */ 00429 int readCommand(uint8_t reg, uint8_t* buffer, int length); 00430 00431 /** 00432 * Recalculate roll and pitch values for the current sample. 00433 * 00434 * @note We only do this at most once per sample, as the necessary trigonemteric functions are rather 00435 * heavyweight for a CPU without a floating point unit. 00436 */ 00437 void recalculatePitchRoll(); 00438 00439 /** 00440 * Updates the basic gesture recognizer. This performs instantaneous pose recognition, and also some low pass filtering to promote 00441 * stability. 00442 */ 00443 void updateGesture(); 00444 00445 /** 00446 * A service function. 00447 * It calculates the current scalar acceleration of the device (x^2 + y^2 + z^2). 00448 * It does not, however, square root the result, as this is a relatively high cost operation. 00449 * 00450 * This is left to application code should it be needed. 00451 * 00452 * @return the sum of the square of the acceleration of the device across all axes. 00453 */ 00454 int instantaneousAccelerationSquared(); 00455 00456 /** 00457 * Service function. 00458 * Determines a 'best guess' posture of the device based on instantaneous data. 00459 * 00460 * This makes no use of historic data, and forms this input to the filter implemented in updateGesture(). 00461 * 00462 * @return A 'best guess' of the current posture of the device, based on instanataneous data. 00463 */ 00464 BasicGesture instantaneousPosture(); 00465 }; 00466 00467 #endif
Generated on Tue Jul 12 2022 19:58:09 by 1.7.2