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