fork
Dependencies: BLE_API mbed-dev-bin nRF51822
Fork of microbit-dal by
MicroBitAccelerometer.cpp
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 /** 00027 * Class definition for MicroBit Accelerometer. 00028 * 00029 * Represents an implementation of the Freescale MMA8653 3 axis accelerometer 00030 * Also includes basic data caching and on demand activation. 00031 */ 00032 #include "MicroBitConfig.h" 00033 #include "MicroBitAccelerometer.h" 00034 #include "ErrorNo.h" 00035 #include "MicroBitConfig.h" 00036 #include "MicroBitEvent.h" 00037 #include "MicroBitCompat.h" 00038 #include "MicroBitFiber.h" 00039 00040 /** 00041 * Configures the accelerometer for G range and sample rate defined 00042 * in this object. The nearest values are chosen to those defined 00043 * that are supported by the hardware. The instance variables are then 00044 * updated to reflect reality. 00045 * 00046 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured. 00047 */ 00048 int MicroBitAccelerometer::configure() 00049 { 00050 const MMA8653SampleRangeConfig *actualSampleRange; 00051 const MMA8653SampleRateConfig *actualSampleRate; 00052 int result; 00053 00054 // First find the nearest sample rate to that specified. 00055 actualSampleRate = &MMA8653SampleRate[MMA8653_SAMPLE_RATES-1]; 00056 for (int i=MMA8653_SAMPLE_RATES-1; i>=0; i--) 00057 { 00058 if(MMA8653SampleRate[i].sample_period < this->samplePeriod * 1000) 00059 break; 00060 00061 actualSampleRate = &MMA8653SampleRate[i]; 00062 } 00063 00064 // Now find the nearest sample range to that specified. 00065 actualSampleRange = &MMA8653SampleRange[MMA8653_SAMPLE_RANGES-1]; 00066 for (int i=MMA8653_SAMPLE_RANGES-1; i>=0; i--) 00067 { 00068 if(MMA8653SampleRange[i].sample_range < this->sampleRange) 00069 break; 00070 00071 actualSampleRange = &MMA8653SampleRange[i]; 00072 } 00073 00074 // OK, we have the correct data. Update our local state. 00075 this->samplePeriod = actualSampleRate->sample_period / 1000; 00076 this->sampleRange = actualSampleRange->sample_range; 00077 00078 // Now configure the accelerometer accordingly. 00079 // First place the device into standby mode, so it can be configured. 00080 result = writeCommand(MMA8653_CTRL_REG1, 0x00); 00081 if (result != 0) 00082 return MICROBIT_I2C_ERROR; 00083 00084 // Enable high precisiosn mode. This consumes a bit more power, but still only 184 uA! 00085 result = writeCommand(MMA8653_CTRL_REG2, 0x10); 00086 if (result != 0) 00087 return MICROBIT_I2C_ERROR; 00088 00089 // Enable the INT1 interrupt pin. 00090 result = writeCommand(MMA8653_CTRL_REG4, 0x01); 00091 if (result != 0) 00092 return MICROBIT_I2C_ERROR; 00093 00094 // Select the DATA_READY event source to be routed to INT1 00095 result = writeCommand(MMA8653_CTRL_REG5, 0x01); 00096 if (result != 0) 00097 return MICROBIT_I2C_ERROR; 00098 00099 // Configure for the selected g range. 00100 result = writeCommand(MMA8653_XYZ_DATA_CFG, actualSampleRange->xyz_data_cfg); 00101 if (result != 0) 00102 return MICROBIT_I2C_ERROR; 00103 00104 // Bring the device back online, with 10bit wide samples at the requested frequency. 00105 result = writeCommand(MMA8653_CTRL_REG1, actualSampleRate->ctrl_reg1 | 0x01); 00106 if (result != 0) 00107 return MICROBIT_I2C_ERROR; 00108 00109 return MICROBIT_OK; 00110 } 00111 00112 /** 00113 * Issues a standard, 2 byte I2C command write to the accelerometer. 00114 * 00115 * Blocks the calling thread until complete. 00116 * 00117 * @param reg The address of the register to write to. 00118 * 00119 * @param value The value to write. 00120 * 00121 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed. 00122 */ 00123 int MicroBitAccelerometer::writeCommand(uint8_t reg, uint8_t value) 00124 { 00125 uint8_t command[2]; 00126 command[0] = reg; 00127 command[1] = value; 00128 00129 return i2c.write(address, (const char *)command, 2); 00130 } 00131 00132 /** 00133 * Issues a read command, copying data into the specified buffer. 00134 * 00135 * Blocks the calling thread until complete. 00136 * 00137 * @param reg The address of the register to access. 00138 * 00139 * @param buffer Memory area to read the data into. 00140 * 00141 * @param length The number of bytes to read. 00142 * 00143 * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed. 00144 */ 00145 int MicroBitAccelerometer::readCommand(uint8_t reg, uint8_t* buffer, int length) 00146 { 00147 int result; 00148 00149 if (buffer == NULL || length <= 0 ) 00150 return MICROBIT_INVALID_PARAMETER; 00151 00152 result = i2c.write(address, (const char *)®, 1, true); 00153 if (result !=0) 00154 return MICROBIT_I2C_ERROR; 00155 00156 result = i2c.read(address, (char *)buffer, length); 00157 if (result !=0) 00158 return MICROBIT_I2C_ERROR; 00159 00160 return MICROBIT_OK; 00161 } 00162 00163 /** 00164 * Constructor. 00165 * Create a software abstraction of an accelerometer. 00166 * 00167 * @param _i2c an instance of MicroBitI2C used to communicate with the onboard accelerometer. 00168 * 00169 * @param address the default I2C address of the accelerometer. Defaults to: MMA8653_DEFAULT_ADDR. 00170 * 00171 * @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER 00172 * 00173 * @code 00174 * MicroBitI2C i2c = MicroBitI2C(I2C_SDA0, I2C_SCL0); 00175 * 00176 * MicroBitAccelerometer accelerometer = MicroBitAccelerometer(i2c); 00177 * @endcode 00178 */ 00179 MicroBitAccelerometer::MicroBitAccelerometer(MicroBitI2C& _i2c, uint16_t address, uint16_t id) : sample(), int1(MICROBIT_PIN_ACCEL_DATA_READY), i2c(_i2c) 00180 { 00181 // Store our identifiers. 00182 this->id = id; 00183 this->status = 0; 00184 this->address = address; 00185 00186 // Update our internal state for 50Hz at +/- 2g (50Hz has a period af 20ms). 00187 this->samplePeriod = 20; 00188 this->sampleRange = 2; 00189 00190 // Initialise gesture history 00191 this->sigma = 0; 00192 this->lastGesture = GESTURE_NONE; 00193 this->currentGesture = GESTURE_NONE; 00194 this->shake.x = 0; 00195 this->shake.y = 0; 00196 this->shake.z = 0; 00197 this->shake.count = 0; 00198 this->shake.timer = 0; 00199 00200 // Configure and enable the accelerometer. 00201 if (this->configure() == MICROBIT_OK) 00202 status |= MICROBIT_COMPONENT_RUNNING; 00203 } 00204 00205 /** 00206 * Attempts to read the 8 bit ID from the accelerometer, this can be used for 00207 * validation purposes. 00208 * 00209 * @return the 8 bit ID returned by the accelerometer, or MICROBIT_I2C_ERROR if the request fails. 00210 * 00211 * @code 00212 * accelerometer.whoAmI(); 00213 * @endcode 00214 */ 00215 int MicroBitAccelerometer::whoAmI() 00216 { 00217 uint8_t data; 00218 int result; 00219 00220 result = readCommand(MMA8653_WHOAMI, &data, 1); 00221 if (result !=0) 00222 return MICROBIT_I2C_ERROR; 00223 00224 return (int)data; 00225 } 00226 00227 /** 00228 * Reads the acceleration data from the accelerometer, and stores it in our buffer. 00229 * This only happens if the accelerometer indicates that it has new data via int1. 00230 * 00231 * On first use, this member function will attempt to add this component to the 00232 * list of fiber components in order to constantly update the values stored 00233 * by this object. 00234 * 00235 * This technique is called lazy instantiation, and it means that we do not 00236 * obtain the overhead from non-chalantly adding this component to fiber components. 00237 * 00238 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the read request fails. 00239 */ 00240 int MicroBitAccelerometer::updateSample() 00241 { 00242 if(!(status & MICROBIT_ACCEL_ADDED_TO_IDLE)) 00243 { 00244 fiber_add_idle_component(this); 00245 status |= MICROBIT_ACCEL_ADDED_TO_IDLE; 00246 } 00247 00248 // Poll interrupt line from accelerometer. 00249 // n.b. Default is Active LO. Interrupt is cleared in data read. 00250 if(!int1) 00251 { 00252 int8_t data[6]; 00253 int result; 00254 00255 result = readCommand(MMA8653_OUT_X_MSB, (uint8_t *)data, 6); 00256 if (result !=0) 00257 return MICROBIT_I2C_ERROR; 00258 00259 // read MSB values... 00260 sample.x = data[0]; 00261 sample.y = data[2]; 00262 sample.z = data[4]; 00263 00264 // Normalize the data in the 0..1024 range. 00265 sample.x *= 8; 00266 sample.y *= 8; 00267 sample.z *= 8; 00268 00269 #if CONFIG_ENABLED(USE_ACCEL_LSB) 00270 // Add in LSB values. 00271 sample.x += (data[1] / 64); 00272 sample.y += (data[3] / 64); 00273 sample.z += (data[5] / 64); 00274 #endif 00275 00276 // Scale into millig (approx!) 00277 sample.x *= this->sampleRange; 00278 sample.y *= this->sampleRange; 00279 sample.z *= this->sampleRange; 00280 00281 // Indicate that pitch and roll data is now stale, and needs to be recalculated if needed. 00282 status &= ~MICROBIT_ACCEL_PITCH_ROLL_VALID; 00283 00284 // Update gesture tracking 00285 updateGesture(); 00286 00287 // Indicate that a new sample is available 00288 MicroBitEvent e(id, MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE); 00289 } 00290 00291 return MICROBIT_OK; 00292 }; 00293 00294 /** 00295 * A service function. 00296 * It calculates the current scalar acceleration of the device (x^2 + y^2 + z^2). 00297 * It does not, however, square root the result, as this is a relatively high cost operation. 00298 * 00299 * This is left to application code should it be needed. 00300 * 00301 * @return the sum of the square of the acceleration of the device across all axes. 00302 */ 00303 int MicroBitAccelerometer::instantaneousAccelerationSquared() 00304 { 00305 updateSample(); 00306 00307 // Use pythagoras theorem to determine the combined force acting on the device. 00308 return (int)sample.x*(int)sample.x + (int)sample.y*(int)sample.y + (int)sample.z*(int)sample.z; 00309 } 00310 00311 /** 00312 * Service function. 00313 * Determines a 'best guess' posture of the device based on instantaneous data. 00314 * 00315 * This makes no use of historic data, and forms this input to the filter implemented in updateGesture(). 00316 * 00317 * @return A 'best guess' of the current posture of the device, based on instanataneous data. 00318 */ 00319 BasicGesture MicroBitAccelerometer::instantaneousPosture() 00320 { 00321 int force = instantaneousAccelerationSquared(); 00322 bool shakeDetected = false; 00323 00324 // Test for shake events. 00325 // We detect a shake by measuring zero crossings in each axis. In other words, if we see a strong acceleration to the left followed by 00326 // a string acceleration to the right, then we can infer a shake. Similarly, we can do this for each acxis (left/right, up/down, in/out). 00327 // 00328 // If we see enough zero crossings in succession (MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD), then we decide that the device 00329 // has been shaken. 00330 if ((getX() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.x) || (getX() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.x)) 00331 { 00332 shakeDetected = true; 00333 shake.x = !shake.x; 00334 } 00335 00336 if ((getY() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.y) || (getY() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.y)) 00337 { 00338 shakeDetected = true; 00339 shake.y = !shake.y; 00340 } 00341 00342 if ((getZ() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.z) || (getZ() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.z)) 00343 { 00344 shakeDetected = true; 00345 shake.z = !shake.z; 00346 } 00347 00348 if (shakeDetected && shake.count < MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD && ++shake.count == MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD) 00349 shake.shaken = 1; 00350 00351 if (++shake.timer >= MICROBIT_ACCELEROMETER_SHAKE_DAMPING) 00352 { 00353 shake.timer = 0; 00354 if (shake.count > 0) 00355 { 00356 if(--shake.count == 0) 00357 shake.shaken = 0; 00358 } 00359 } 00360 00361 if (shake.shaken) 00362 return GESTURE_SHAKE; 00363 00364 if (force < MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD) 00365 return GESTURE_FREEFALL; 00366 00367 if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD) 00368 return GESTURE_3G; 00369 00370 if (force > MICROBIT_ACCELEROMETER_6G_THRESHOLD) 00371 return GESTURE_6G; 00372 00373 if (force > MICROBIT_ACCELEROMETER_8G_THRESHOLD) 00374 return GESTURE_8G; 00375 00376 // Determine our posture. 00377 if (getX() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) 00378 return GESTURE_LEFT; 00379 00380 if (getX() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) 00381 return GESTURE_RIGHT; 00382 00383 if (getY() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) 00384 return GESTURE_DOWN; 00385 00386 if (getY() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) 00387 return GESTURE_UP; 00388 00389 if (getZ() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) 00390 return GESTURE_FACE_UP; 00391 00392 if (getZ() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) 00393 return GESTURE_FACE_DOWN; 00394 00395 return GESTURE_NONE; 00396 } 00397 00398 /** 00399 * Updates the basic gesture recognizer. This performs instantaneous pose recognition, and also some low pass filtering to promote 00400 * stability. 00401 */ 00402 void MicroBitAccelerometer::updateGesture() 00403 { 00404 // Determine what it looks like we're doing based on the latest sample... 00405 BasicGesture g = instantaneousPosture(); 00406 00407 // Perform some low pass filtering to reduce jitter from any detected effects 00408 if (g == currentGesture) 00409 { 00410 if (sigma < MICROBIT_ACCELEROMETER_GESTURE_DAMPING) 00411 sigma++; 00412 } 00413 else 00414 { 00415 currentGesture = g; 00416 sigma = 0; 00417 } 00418 00419 // If we've reached threshold, update our record and raise the relevant event... 00420 if (currentGesture != lastGesture && sigma >= MICROBIT_ACCELEROMETER_GESTURE_DAMPING) 00421 { 00422 lastGesture = currentGesture; 00423 MicroBitEvent e(MICROBIT_ID_GESTURE, lastGesture); 00424 } 00425 } 00426 00427 /** 00428 * Attempts to set the sample rate of the accelerometer to the specified value (in ms). 00429 * 00430 * @param period the requested time between samples, in milliseconds. 00431 * 00432 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails. 00433 * 00434 * @code 00435 * // sample rate is now 20 ms. 00436 * accelerometer.setPeriod(20); 00437 * @endcode 00438 * 00439 * @note The requested rate may not be possible on the hardware. In this case, the 00440 * nearest lower rate is chosen. 00441 */ 00442 int MicroBitAccelerometer::setPeriod(int period) 00443 { 00444 this->samplePeriod = period; 00445 return this->configure(); 00446 } 00447 00448 /** 00449 * Reads the currently configured sample rate of the accelerometer. 00450 * 00451 * @return The time between samples, in milliseconds. 00452 */ 00453 int MicroBitAccelerometer::getPeriod() 00454 { 00455 return (int)samplePeriod; 00456 } 00457 00458 /** 00459 * Attempts to set the sample range of the accelerometer to the specified value (in g). 00460 * 00461 * @param range The requested sample range of samples, in g. 00462 * 00463 * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails. 00464 * 00465 * @code 00466 * // the sample range of the accelerometer is now 8G. 00467 * accelerometer.setRange(8); 00468 * @endcode 00469 * 00470 * @note The requested range may not be possible on the hardware. In this case, the 00471 * nearest lower range is chosen. 00472 */ 00473 int MicroBitAccelerometer::setRange(int range) 00474 { 00475 this->sampleRange = range; 00476 return this->configure(); 00477 } 00478 00479 /** 00480 * Reads the currently configured sample range of the accelerometer. 00481 * 00482 * @return The sample range, in g. 00483 */ 00484 int MicroBitAccelerometer::getRange() 00485 { 00486 return (int)sampleRange; 00487 } 00488 00489 /** 00490 * Reads the value of the X axis from the latest update retrieved from the accelerometer. 00491 * 00492 * @param system The coordinate system to use. By default, a simple cartesian system is provided. 00493 * 00494 * @return The force measured in the X axis, in milli-g. 00495 * 00496 * @code 00497 * accelerometer.getX(); 00498 * @endcode 00499 */ 00500 int MicroBitAccelerometer::getX(MicroBitCoordinateSystem system) 00501 { 00502 updateSample(); 00503 00504 switch (system) 00505 { 00506 case SIMPLE_CARTESIAN: 00507 return -sample.x; 00508 00509 case NORTH_EAST_DOWN: 00510 return sample.y; 00511 00512 case RAW: 00513 default: 00514 return sample.x; 00515 } 00516 } 00517 00518 /** 00519 * Reads the value of the Y axis from the latest update retrieved from the accelerometer. 00520 * 00521 * @return The force measured in the Y axis, in milli-g. 00522 * 00523 * @code 00524 * accelerometer.getY(); 00525 * @endcode 00526 */ 00527 int MicroBitAccelerometer::getY(MicroBitCoordinateSystem system) 00528 { 00529 updateSample(); 00530 00531 switch (system) 00532 { 00533 case SIMPLE_CARTESIAN: 00534 return -sample.y; 00535 00536 case NORTH_EAST_DOWN: 00537 return -sample.x; 00538 00539 case RAW: 00540 default: 00541 return sample.y; 00542 } 00543 } 00544 00545 /** 00546 * Reads the value of the Z axis from the latest update retrieved from the accelerometer. 00547 * 00548 * @return The force measured in the Z axis, in milli-g. 00549 * 00550 * @code 00551 * accelerometer.getZ(); 00552 * @endcode 00553 */ 00554 int MicroBitAccelerometer::getZ(MicroBitCoordinateSystem system) 00555 { 00556 updateSample(); 00557 00558 switch (system) 00559 { 00560 case NORTH_EAST_DOWN: 00561 return -sample.z; 00562 00563 case SIMPLE_CARTESIAN: 00564 case RAW: 00565 default: 00566 return sample.z; 00567 } 00568 } 00569 00570 /** 00571 * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer. 00572 * 00573 * @return The pitch of the device, in degrees. 00574 * 00575 * @code 00576 * accelerometer.getPitch(); 00577 * @endcode 00578 */ 00579 int MicroBitAccelerometer::getPitch() 00580 { 00581 return (int) ((360*getPitchRadians()) / (2*PI)); 00582 } 00583 00584 /** 00585 * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer. 00586 * 00587 * @return The pitch of the device, in radians. 00588 * 00589 * @code 00590 * accelerometer.getPitchRadians(); 00591 * @endcode 00592 */ 00593 float MicroBitAccelerometer::getPitchRadians() 00594 { 00595 if (!(status & MICROBIT_ACCEL_PITCH_ROLL_VALID)) 00596 recalculatePitchRoll(); 00597 00598 return pitch; 00599 } 00600 00601 /** 00602 * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer. 00603 * 00604 * @return The roll of the device, in degrees. 00605 * 00606 * @code 00607 * accelerometer.getRoll(); 00608 * @endcode 00609 */ 00610 int MicroBitAccelerometer::getRoll() 00611 { 00612 return (int) ((360*getRollRadians()) / (2*PI)); 00613 } 00614 00615 /** 00616 * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer. 00617 * 00618 * @return The roll of the device, in radians. 00619 * 00620 * @code 00621 * accelerometer.getRollRadians(); 00622 * @endcode 00623 */ 00624 float MicroBitAccelerometer::getRollRadians() 00625 { 00626 if (!(status & MICROBIT_ACCEL_PITCH_ROLL_VALID)) 00627 recalculatePitchRoll(); 00628 00629 return roll; 00630 } 00631 00632 /** 00633 * Recalculate roll and pitch values for the current sample. 00634 * 00635 * @note We only do this at most once per sample, as the necessary trigonemteric functions are rather 00636 * heavyweight for a CPU without a floating point unit. 00637 */ 00638 void MicroBitAccelerometer::recalculatePitchRoll() 00639 { 00640 float x = (float) getX(NORTH_EAST_DOWN); 00641 float y = (float) getY(NORTH_EAST_DOWN); 00642 float z = (float) getZ(NORTH_EAST_DOWN); 00643 00644 roll = atan2((double)getY(NORTH_EAST_DOWN), (double)getZ(NORTH_EAST_DOWN)); 00645 00646 pitch = atan(-x / (y*sin(roll) + z*cos(roll))); 00647 status |= MICROBIT_ACCEL_PITCH_ROLL_VALID; 00648 } 00649 00650 /** 00651 * Retrieves the last recorded gesture. 00652 * 00653 * @return The last gesture that was detected. 00654 * 00655 * Example: 00656 * @code 00657 * MicroBitDisplay display; 00658 * 00659 * if (accelerometer.getGesture() == SHAKE) 00660 * display.scroll("SHAKE!"); 00661 * @endcode 00662 */ 00663 BasicGesture MicroBitAccelerometer::getGesture() 00664 { 00665 return lastGesture; 00666 } 00667 00668 /** 00669 * A periodic callback invoked by the fiber scheduler idle thread. 00670 * 00671 * Internally calls updateSample(). 00672 */ 00673 void MicroBitAccelerometer::idleTick() 00674 { 00675 updateSample(); 00676 } 00677 00678 /** 00679 * Returns 0 or 1. 1 indicates data is waiting to be read, zero means data is not ready to be read. 00680 * 00681 * We check if any data is ready for reading by checking the interrupt flag on the accelerometer. 00682 */ 00683 int MicroBitAccelerometer::isIdleCallbackNeeded() 00684 { 00685 return !int1; 00686 } 00687 00688 /** 00689 * Destructor for MicroBitAccelerometer, where we deregister from the array of fiber components. 00690 */ 00691 MicroBitAccelerometer::~MicroBitAccelerometer() 00692 { 00693 fiber_remove_idle_component(this); 00694 } 00695 00696 const MMA8653SampleRangeConfig MMA8653SampleRange[MMA8653_SAMPLE_RANGES] = { 00697 {2, 0}, 00698 {4, 1}, 00699 {8, 2} 00700 }; 00701 00702 const MMA8653SampleRateConfig MMA8653SampleRate[MMA8653_SAMPLE_RATES] = { 00703 {1250, 0x00}, 00704 {2500, 0x08}, 00705 {5000, 0x10}, 00706 {10000, 0x18}, 00707 {20000, 0x20}, 00708 {80000, 0x28}, 00709 {160000, 0x30}, 00710 {640000, 0x38} 00711 };
Generated on Tue Jul 12 2022 19:47:35 by 1.7.2