Solution for Bluetooth SIG hands-on training course
Dependencies: BLE_API mbed-dev-bin nRF51822-bluetooth-mdw
Fork of microbit-dal-bluetooth-mdw_starter by
source/drivers/MicroBitAccelerometer.cpp@65:f7ebabf23e15, 2016-07-13 (annotated)
- Committer:
- LancasterUniversity
- Date:
- Wed Jul 13 12:18:45 2016 +0100
- Revision:
- 65:f7ebabf23e15
- Parent:
- 56:1311cac15dda
Synchronized with git rev 00674e34
Author: Joe Finney
microbit: Tuning and furhter debounce of SHAKE gesture
- Added timeout code to prevent over-generation of SHAKE events.
- Tuning of SHAKE detection parameters to align sensitivity with existing
microbit.co.uk algorithm
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
Jonathan Austin |
1:8aa5cdb4ab67 | 1 | /* |
Jonathan Austin |
1:8aa5cdb4ab67 | 2 | The MIT License (MIT) |
Jonathan Austin |
1:8aa5cdb4ab67 | 3 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 4 | Copyright (c) 2016 British Broadcasting Corporation. |
Jonathan Austin |
1:8aa5cdb4ab67 | 5 | This software is provided by Lancaster University by arrangement with the BBC. |
Jonathan Austin |
1:8aa5cdb4ab67 | 6 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 7 | Permission is hereby granted, free of charge, to any person obtaining a |
Jonathan Austin |
1:8aa5cdb4ab67 | 8 | copy of this software and associated documentation files (the "Software"), |
Jonathan Austin |
1:8aa5cdb4ab67 | 9 | to deal in the Software without restriction, including without limitation |
Jonathan Austin |
1:8aa5cdb4ab67 | 10 | the rights to use, copy, modify, merge, publish, distribute, sublicense, |
Jonathan Austin |
1:8aa5cdb4ab67 | 11 | and/or sell copies of the Software, and to permit persons to whom the |
Jonathan Austin |
1:8aa5cdb4ab67 | 12 | Software is furnished to do so, subject to the following conditions: |
Jonathan Austin |
1:8aa5cdb4ab67 | 13 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 14 | The above copyright notice and this permission notice shall be included in |
Jonathan Austin |
1:8aa5cdb4ab67 | 15 | all copies or substantial portions of the Software. |
Jonathan Austin |
1:8aa5cdb4ab67 | 16 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
Jonathan Austin |
1:8aa5cdb4ab67 | 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
Jonathan Austin |
1:8aa5cdb4ab67 | 19 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL |
Jonathan Austin |
1:8aa5cdb4ab67 | 20 | THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
Jonathan Austin |
1:8aa5cdb4ab67 | 21 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
Jonathan Austin |
1:8aa5cdb4ab67 | 22 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER |
Jonathan Austin |
1:8aa5cdb4ab67 | 23 | DEALINGS IN THE SOFTWARE. |
Jonathan Austin |
1:8aa5cdb4ab67 | 24 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 25 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 26 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 27 | * Class definition for MicroBit Accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 28 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 29 | * Represents an implementation of the Freescale MMA8653 3 axis accelerometer |
Jonathan Austin |
1:8aa5cdb4ab67 | 30 | * Also includes basic data caching and on demand activation. |
Jonathan Austin |
1:8aa5cdb4ab67 | 31 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 32 | #include "MicroBitConfig.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 33 | #include "MicroBitAccelerometer.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 34 | #include "ErrorNo.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 35 | #include "MicroBitConfig.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 36 | #include "MicroBitEvent.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 37 | #include "MicroBitCompat.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 38 | #include "MicroBitFiber.h" |
Jonathan Austin |
1:8aa5cdb4ab67 | 39 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 40 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 41 | * Configures the accelerometer for G range and sample rate defined |
Jonathan Austin |
1:8aa5cdb4ab67 | 42 | * in this object. The nearest values are chosen to those defined |
Jonathan Austin |
1:8aa5cdb4ab67 | 43 | * that are supported by the hardware. The instance variables are then |
Jonathan Austin |
1:8aa5cdb4ab67 | 44 | * updated to reflect reality. |
Jonathan Austin |
1:8aa5cdb4ab67 | 45 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 46 | * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the accelerometer could not be configured. |
Jonathan Austin |
1:8aa5cdb4ab67 | 47 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 48 | int MicroBitAccelerometer::configure() |
Jonathan Austin |
1:8aa5cdb4ab67 | 49 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 50 | const MMA8653SampleRangeConfig *actualSampleRange; |
Jonathan Austin |
1:8aa5cdb4ab67 | 51 | const MMA8653SampleRateConfig *actualSampleRate; |
Jonathan Austin |
1:8aa5cdb4ab67 | 52 | int result; |
Jonathan Austin |
1:8aa5cdb4ab67 | 53 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 54 | // First find the nearest sample rate to that specified. |
Jonathan Austin |
1:8aa5cdb4ab67 | 55 | actualSampleRate = &MMA8653SampleRate[MMA8653_SAMPLE_RATES-1]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 56 | for (int i=MMA8653_SAMPLE_RATES-1; i>=0; i--) |
Jonathan Austin |
1:8aa5cdb4ab67 | 57 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 58 | if(MMA8653SampleRate[i].sample_period < this->samplePeriod * 1000) |
Jonathan Austin |
1:8aa5cdb4ab67 | 59 | break; |
Jonathan Austin |
1:8aa5cdb4ab67 | 60 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 61 | actualSampleRate = &MMA8653SampleRate[i]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 62 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 63 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 64 | // Now find the nearest sample range to that specified. |
Jonathan Austin |
1:8aa5cdb4ab67 | 65 | actualSampleRange = &MMA8653SampleRange[MMA8653_SAMPLE_RANGES-1]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 66 | for (int i=MMA8653_SAMPLE_RANGES-1; i>=0; i--) |
Jonathan Austin |
1:8aa5cdb4ab67 | 67 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 68 | if(MMA8653SampleRange[i].sample_range < this->sampleRange) |
Jonathan Austin |
1:8aa5cdb4ab67 | 69 | break; |
Jonathan Austin |
1:8aa5cdb4ab67 | 70 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 71 | actualSampleRange = &MMA8653SampleRange[i]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 72 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 73 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 74 | // OK, we have the correct data. Update our local state. |
Jonathan Austin |
1:8aa5cdb4ab67 | 75 | this->samplePeriod = actualSampleRate->sample_period / 1000; |
Jonathan Austin |
1:8aa5cdb4ab67 | 76 | this->sampleRange = actualSampleRange->sample_range; |
Jonathan Austin |
1:8aa5cdb4ab67 | 77 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 78 | // Now configure the accelerometer accordingly. |
Jonathan Austin |
1:8aa5cdb4ab67 | 79 | // First place the device into standby mode, so it can be configured. |
Jonathan Austin |
1:8aa5cdb4ab67 | 80 | result = writeCommand(MMA8653_CTRL_REG1, 0x00); |
Jonathan Austin |
1:8aa5cdb4ab67 | 81 | if (result != 0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 82 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 83 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 84 | // Enable high precisiosn mode. This consumes a bit more power, but still only 184 uA! |
Jonathan Austin |
1:8aa5cdb4ab67 | 85 | result = writeCommand(MMA8653_CTRL_REG2, 0x10); |
Jonathan Austin |
1:8aa5cdb4ab67 | 86 | if (result != 0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 87 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 88 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 89 | // Enable the INT1 interrupt pin. |
Jonathan Austin |
1:8aa5cdb4ab67 | 90 | result = writeCommand(MMA8653_CTRL_REG4, 0x01); |
Jonathan Austin |
1:8aa5cdb4ab67 | 91 | if (result != 0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 92 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 93 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 94 | // Select the DATA_READY event source to be routed to INT1 |
Jonathan Austin |
1:8aa5cdb4ab67 | 95 | result = writeCommand(MMA8653_CTRL_REG5, 0x01); |
Jonathan Austin |
1:8aa5cdb4ab67 | 96 | if (result != 0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 97 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 98 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 99 | // Configure for the selected g range. |
Jonathan Austin |
1:8aa5cdb4ab67 | 100 | result = writeCommand(MMA8653_XYZ_DATA_CFG, actualSampleRange->xyz_data_cfg); |
Jonathan Austin |
1:8aa5cdb4ab67 | 101 | if (result != 0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 102 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 103 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 104 | // Bring the device back online, with 10bit wide samples at the requested frequency. |
Jonathan Austin |
1:8aa5cdb4ab67 | 105 | result = writeCommand(MMA8653_CTRL_REG1, actualSampleRate->ctrl_reg1 | 0x01); |
Jonathan Austin |
1:8aa5cdb4ab67 | 106 | if (result != 0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 107 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 108 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 109 | return MICROBIT_OK; |
Jonathan Austin |
1:8aa5cdb4ab67 | 110 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 111 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 112 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 113 | * Issues a standard, 2 byte I2C command write to the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 114 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 115 | * Blocks the calling thread until complete. |
Jonathan Austin |
1:8aa5cdb4ab67 | 116 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 117 | * @param reg The address of the register to write to. |
Jonathan Austin |
1:8aa5cdb4ab67 | 118 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 119 | * @param value The value to write. |
Jonathan Austin |
1:8aa5cdb4ab67 | 120 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 121 | * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the the write request failed. |
Jonathan Austin |
1:8aa5cdb4ab67 | 122 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 123 | int MicroBitAccelerometer::writeCommand(uint8_t reg, uint8_t value) |
Jonathan Austin |
1:8aa5cdb4ab67 | 124 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 125 | uint8_t command[2]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 126 | command[0] = reg; |
Jonathan Austin |
1:8aa5cdb4ab67 | 127 | command[1] = value; |
Jonathan Austin |
1:8aa5cdb4ab67 | 128 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 129 | return i2c.write(address, (const char *)command, 2); |
Jonathan Austin |
1:8aa5cdb4ab67 | 130 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 131 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 132 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 133 | * Issues a read command, copying data into the specified buffer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 134 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 135 | * Blocks the calling thread until complete. |
Jonathan Austin |
1:8aa5cdb4ab67 | 136 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 137 | * @param reg The address of the register to access. |
Jonathan Austin |
1:8aa5cdb4ab67 | 138 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 139 | * @param buffer Memory area to read the data into. |
Jonathan Austin |
1:8aa5cdb4ab67 | 140 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 141 | * @param length The number of bytes to read. |
Jonathan Austin |
1:8aa5cdb4ab67 | 142 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 143 | * @return MICROBIT_OK on success, MICROBIT_INVALID_PARAMETER or MICROBIT_I2C_ERROR if the the read request failed. |
Jonathan Austin |
1:8aa5cdb4ab67 | 144 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 145 | int MicroBitAccelerometer::readCommand(uint8_t reg, uint8_t* buffer, int length) |
Jonathan Austin |
1:8aa5cdb4ab67 | 146 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 147 | int result; |
Jonathan Austin |
1:8aa5cdb4ab67 | 148 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 149 | if (buffer == NULL || length <= 0 ) |
Jonathan Austin |
1:8aa5cdb4ab67 | 150 | return MICROBIT_INVALID_PARAMETER; |
Jonathan Austin |
1:8aa5cdb4ab67 | 151 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 152 | result = i2c.write(address, (const char *)®, 1, true); |
Jonathan Austin |
1:8aa5cdb4ab67 | 153 | if (result !=0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 154 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 155 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 156 | result = i2c.read(address, (char *)buffer, length); |
Jonathan Austin |
1:8aa5cdb4ab67 | 157 | if (result !=0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 158 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 159 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 160 | return MICROBIT_OK; |
Jonathan Austin |
1:8aa5cdb4ab67 | 161 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 162 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 163 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 164 | * Constructor. |
Jonathan Austin |
1:8aa5cdb4ab67 | 165 | * Create a software abstraction of an accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 166 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 167 | * @param _i2c an instance of MicroBitI2C used to communicate with the onboard accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 168 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 169 | * @param address the default I2C address of the accelerometer. Defaults to: MMA8653_DEFAULT_ADDR. |
Jonathan Austin |
1:8aa5cdb4ab67 | 170 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 171 | * @param id the unique EventModel id of this component. Defaults to: MICROBIT_ID_ACCELEROMETER |
Jonathan Austin |
1:8aa5cdb4ab67 | 172 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 173 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 174 | * MicroBitI2C i2c = MicroBitI2C(I2C_SDA0, I2C_SCL0); |
Jonathan Austin |
1:8aa5cdb4ab67 | 175 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 176 | * MicroBitAccelerometer accelerometer = MicroBitAccelerometer(i2c); |
Jonathan Austin |
1:8aa5cdb4ab67 | 177 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 178 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 179 | MicroBitAccelerometer::MicroBitAccelerometer(MicroBitI2C& _i2c, uint16_t address, uint16_t id) : sample(), int1(MICROBIT_PIN_ACCEL_DATA_READY), i2c(_i2c) |
Jonathan Austin |
1:8aa5cdb4ab67 | 180 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 181 | // Store our identifiers. |
Jonathan Austin |
1:8aa5cdb4ab67 | 182 | this->id = id; |
Jonathan Austin |
1:8aa5cdb4ab67 | 183 | this->status = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 184 | this->address = address; |
Jonathan Austin |
1:8aa5cdb4ab67 | 185 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 186 | // Update our internal state for 50Hz at +/- 2g (50Hz has a period af 20ms). |
Jonathan Austin |
1:8aa5cdb4ab67 | 187 | this->samplePeriod = 20; |
Jonathan Austin |
1:8aa5cdb4ab67 | 188 | this->sampleRange = 2; |
Jonathan Austin |
1:8aa5cdb4ab67 | 189 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 190 | // Initialise gesture history |
Jonathan Austin |
1:8aa5cdb4ab67 | 191 | this->sigma = 0; |
LancasterUniversity | 38:1a9e8e5e23f2 | 192 | this->impulseSigma = 0; |
LancasterUniversity | 39:112df23f039f | 193 | this->lastGesture = MICROBIT_ACCELEROMETER_EVT_NONE; |
LancasterUniversity | 39:112df23f039f | 194 | this->currentGesture = MICROBIT_ACCELEROMETER_EVT_NONE; |
Jonathan Austin |
1:8aa5cdb4ab67 | 195 | this->shake.x = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 196 | this->shake.y = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 197 | this->shake.z = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 198 | this->shake.count = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 199 | this->shake.timer = 0; |
LancasterUniversity | 38:1a9e8e5e23f2 | 200 | this->shake.impulse_3 = 1; |
LancasterUniversity | 38:1a9e8e5e23f2 | 201 | this->shake.impulse_6 = 1; |
LancasterUniversity | 38:1a9e8e5e23f2 | 202 | this->shake.impulse_8 = 1; |
Jonathan Austin |
1:8aa5cdb4ab67 | 203 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 204 | // Configure and enable the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 205 | if (this->configure() == MICROBIT_OK) |
Jonathan Austin |
1:8aa5cdb4ab67 | 206 | status |= MICROBIT_COMPONENT_RUNNING; |
Jonathan Austin |
1:8aa5cdb4ab67 | 207 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 208 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 209 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 210 | * Attempts to read the 8 bit ID from the accelerometer, this can be used for |
Jonathan Austin |
1:8aa5cdb4ab67 | 211 | * validation purposes. |
Jonathan Austin |
1:8aa5cdb4ab67 | 212 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 213 | * @return the 8 bit ID returned by the accelerometer, or MICROBIT_I2C_ERROR if the request fails. |
Jonathan Austin |
1:8aa5cdb4ab67 | 214 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 215 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 216 | * accelerometer.whoAmI(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 217 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 218 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 219 | int MicroBitAccelerometer::whoAmI() |
Jonathan Austin |
1:8aa5cdb4ab67 | 220 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 221 | uint8_t data; |
Jonathan Austin |
1:8aa5cdb4ab67 | 222 | int result; |
Jonathan Austin |
1:8aa5cdb4ab67 | 223 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 224 | result = readCommand(MMA8653_WHOAMI, &data, 1); |
Jonathan Austin |
1:8aa5cdb4ab67 | 225 | if (result !=0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 226 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 227 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 228 | return (int)data; |
Jonathan Austin |
1:8aa5cdb4ab67 | 229 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 230 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 231 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 232 | * Reads the acceleration data from the accelerometer, and stores it in our buffer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 233 | * This only happens if the accelerometer indicates that it has new data via int1. |
Jonathan Austin |
1:8aa5cdb4ab67 | 234 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 235 | * On first use, this member function will attempt to add this component to the |
Jonathan Austin |
1:8aa5cdb4ab67 | 236 | * list of fiber components in order to constantly update the values stored |
Jonathan Austin |
1:8aa5cdb4ab67 | 237 | * by this object. |
Jonathan Austin |
1:8aa5cdb4ab67 | 238 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 239 | * This technique is called lazy instantiation, and it means that we do not |
Jonathan Austin |
1:8aa5cdb4ab67 | 240 | * obtain the overhead from non-chalantly adding this component to fiber components. |
Jonathan Austin |
1:8aa5cdb4ab67 | 241 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 242 | * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR if the read request fails. |
Jonathan Austin |
1:8aa5cdb4ab67 | 243 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 244 | int MicroBitAccelerometer::updateSample() |
Jonathan Austin |
1:8aa5cdb4ab67 | 245 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 246 | if(!(status & MICROBIT_ACCEL_ADDED_TO_IDLE)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 247 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 248 | fiber_add_idle_component(this); |
Jonathan Austin |
1:8aa5cdb4ab67 | 249 | status |= MICROBIT_ACCEL_ADDED_TO_IDLE; |
Jonathan Austin |
1:8aa5cdb4ab67 | 250 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 251 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 252 | // Poll interrupt line from accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 253 | // n.b. Default is Active LO. Interrupt is cleared in data read. |
Jonathan Austin |
1:8aa5cdb4ab67 | 254 | if(!int1) |
Jonathan Austin |
1:8aa5cdb4ab67 | 255 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 256 | int8_t data[6]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 257 | int result; |
Jonathan Austin |
1:8aa5cdb4ab67 | 258 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 259 | result = readCommand(MMA8653_OUT_X_MSB, (uint8_t *)data, 6); |
Jonathan Austin |
1:8aa5cdb4ab67 | 260 | if (result !=0) |
Jonathan Austin |
1:8aa5cdb4ab67 | 261 | return MICROBIT_I2C_ERROR; |
Jonathan Austin |
1:8aa5cdb4ab67 | 262 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 263 | // read MSB values... |
Jonathan Austin |
1:8aa5cdb4ab67 | 264 | sample.x = data[0]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 265 | sample.y = data[2]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 266 | sample.z = data[4]; |
Jonathan Austin |
1:8aa5cdb4ab67 | 267 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 268 | // Normalize the data in the 0..1024 range. |
Jonathan Austin |
1:8aa5cdb4ab67 | 269 | sample.x *= 8; |
Jonathan Austin |
1:8aa5cdb4ab67 | 270 | sample.y *= 8; |
Jonathan Austin |
1:8aa5cdb4ab67 | 271 | sample.z *= 8; |
Jonathan Austin |
1:8aa5cdb4ab67 | 272 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 273 | #if CONFIG_ENABLED(USE_ACCEL_LSB) |
Jonathan Austin |
1:8aa5cdb4ab67 | 274 | // Add in LSB values. |
Jonathan Austin |
1:8aa5cdb4ab67 | 275 | sample.x += (data[1] / 64); |
Jonathan Austin |
1:8aa5cdb4ab67 | 276 | sample.y += (data[3] / 64); |
Jonathan Austin |
1:8aa5cdb4ab67 | 277 | sample.z += (data[5] / 64); |
Jonathan Austin |
1:8aa5cdb4ab67 | 278 | #endif |
Jonathan Austin |
1:8aa5cdb4ab67 | 279 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 280 | // Scale into millig (approx!) |
Jonathan Austin |
1:8aa5cdb4ab67 | 281 | sample.x *= this->sampleRange; |
Jonathan Austin |
1:8aa5cdb4ab67 | 282 | sample.y *= this->sampleRange; |
Jonathan Austin |
1:8aa5cdb4ab67 | 283 | sample.z *= this->sampleRange; |
Jonathan Austin |
1:8aa5cdb4ab67 | 284 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 285 | // Indicate that pitch and roll data is now stale, and needs to be recalculated if needed. |
Jonathan Austin |
1:8aa5cdb4ab67 | 286 | status &= ~MICROBIT_ACCEL_PITCH_ROLL_VALID; |
Jonathan Austin |
1:8aa5cdb4ab67 | 287 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 288 | // Update gesture tracking |
Jonathan Austin |
1:8aa5cdb4ab67 | 289 | updateGesture(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 290 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 291 | // Indicate that a new sample is available |
Jonathan Austin |
1:8aa5cdb4ab67 | 292 | MicroBitEvent e(id, MICROBIT_ACCELEROMETER_EVT_DATA_UPDATE); |
Jonathan Austin |
1:8aa5cdb4ab67 | 293 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 294 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 295 | return MICROBIT_OK; |
Jonathan Austin |
1:8aa5cdb4ab67 | 296 | }; |
Jonathan Austin |
1:8aa5cdb4ab67 | 297 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 298 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 299 | * A service function. |
Jonathan Austin |
1:8aa5cdb4ab67 | 300 | * It calculates the current scalar acceleration of the device (x^2 + y^2 + z^2). |
Jonathan Austin |
1:8aa5cdb4ab67 | 301 | * It does not, however, square root the result, as this is a relatively high cost operation. |
Jonathan Austin |
1:8aa5cdb4ab67 | 302 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 303 | * This is left to application code should it be needed. |
Jonathan Austin |
1:8aa5cdb4ab67 | 304 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 305 | * @return the sum of the square of the acceleration of the device across all axes. |
Jonathan Austin |
1:8aa5cdb4ab67 | 306 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 307 | int MicroBitAccelerometer::instantaneousAccelerationSquared() |
Jonathan Austin |
1:8aa5cdb4ab67 | 308 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 309 | updateSample(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 310 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 311 | // Use pythagoras theorem to determine the combined force acting on the device. |
Jonathan Austin |
1:8aa5cdb4ab67 | 312 | return (int)sample.x*(int)sample.x + (int)sample.y*(int)sample.y + (int)sample.z*(int)sample.z; |
Jonathan Austin |
1:8aa5cdb4ab67 | 313 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 314 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 315 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 316 | * Service function. |
Jonathan Austin |
1:8aa5cdb4ab67 | 317 | * Determines a 'best guess' posture of the device based on instantaneous data. |
Jonathan Austin |
1:8aa5cdb4ab67 | 318 | * |
LancasterUniversity | 37:b624ae5e94a5 | 319 | * This makes no use of historic data, and forms the input to the filter implemented in updateGesture(). |
Jonathan Austin |
1:8aa5cdb4ab67 | 320 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 321 | * @return A 'best guess' of the current posture of the device, based on instanataneous data. |
Jonathan Austin |
1:8aa5cdb4ab67 | 322 | */ |
LancasterUniversity | 39:112df23f039f | 323 | uint16_t MicroBitAccelerometer::instantaneousPosture() |
Jonathan Austin |
1:8aa5cdb4ab67 | 324 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 325 | bool shakeDetected = false; |
Jonathan Austin |
1:8aa5cdb4ab67 | 326 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 327 | // Test for shake events. |
Jonathan Austin |
1:8aa5cdb4ab67 | 328 | // 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 |
LancasterUniversity | 37:b624ae5e94a5 | 329 | // a strong acceleration to the right, then we can infer a shake. Similarly, we can do this for each axis (left/right, up/down, in/out). |
Jonathan Austin |
1:8aa5cdb4ab67 | 330 | // |
Jonathan Austin |
1:8aa5cdb4ab67 | 331 | // If we see enough zero crossings in succession (MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD), then we decide that the device |
Jonathan Austin |
1:8aa5cdb4ab67 | 332 | // has been shaken. |
Jonathan Austin |
1:8aa5cdb4ab67 | 333 | if ((getX() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.x) || (getX() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.x)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 334 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 335 | shakeDetected = true; |
Jonathan Austin |
1:8aa5cdb4ab67 | 336 | shake.x = !shake.x; |
Jonathan Austin |
1:8aa5cdb4ab67 | 337 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 338 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 339 | if ((getY() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.y) || (getY() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.y)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 340 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 341 | shakeDetected = true; |
Jonathan Austin |
1:8aa5cdb4ab67 | 342 | shake.y = !shake.y; |
Jonathan Austin |
1:8aa5cdb4ab67 | 343 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 344 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 345 | if ((getZ() < -MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && shake.z) || (getZ() > MICROBIT_ACCELEROMETER_SHAKE_TOLERANCE && !shake.z)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 346 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 347 | shakeDetected = true; |
Jonathan Austin |
1:8aa5cdb4ab67 | 348 | shake.z = !shake.z; |
Jonathan Austin |
1:8aa5cdb4ab67 | 349 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 350 | |
LancasterUniversity | 65:f7ebabf23e15 | 351 | // If we detected a zero crossing in this sample period, count this. |
LancasterUniversity | 65:f7ebabf23e15 | 352 | if (shakeDetected && shake.count < MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD) |
LancasterUniversity | 55:6920de8ba10a | 353 | { |
LancasterUniversity | 65:f7ebabf23e15 | 354 | shake.count++; |
LancasterUniversity | 65:f7ebabf23e15 | 355 | |
LancasterUniversity | 65:f7ebabf23e15 | 356 | if (shake.count == 1) |
LancasterUniversity | 65:f7ebabf23e15 | 357 | shake.timer = 0; |
LancasterUniversity | 65:f7ebabf23e15 | 358 | |
LancasterUniversity | 65:f7ebabf23e15 | 359 | if (shake.count == MICROBIT_ACCELEROMETER_SHAKE_COUNT_THRESHOLD) |
Jonathan Austin |
1:8aa5cdb4ab67 | 360 | { |
LancasterUniversity | 65:f7ebabf23e15 | 361 | shake.shaken = 1; |
LancasterUniversity | 65:f7ebabf23e15 | 362 | shake.timer = 0; |
LancasterUniversity | 65:f7ebabf23e15 | 363 | return MICROBIT_ACCELEROMETER_EVT_SHAKE; |
Jonathan Austin |
1:8aa5cdb4ab67 | 364 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 365 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 366 | |
LancasterUniversity | 65:f7ebabf23e15 | 367 | // measure how long we have been detecting a SHAKE event. |
LancasterUniversity | 65:f7ebabf23e15 | 368 | if (shake.count > 0) |
LancasterUniversity | 65:f7ebabf23e15 | 369 | { |
LancasterUniversity | 65:f7ebabf23e15 | 370 | shake.timer++; |
LancasterUniversity | 65:f7ebabf23e15 | 371 | |
LancasterUniversity | 65:f7ebabf23e15 | 372 | // If we've issued a SHAKE event already, and sufficient time has assed, allow another SHAKE event to be issued. |
LancasterUniversity | 65:f7ebabf23e15 | 373 | if (shake.shaken && shake.timer >= MICROBIT_ACCELEROMETER_SHAKE_RTX) |
LancasterUniversity | 65:f7ebabf23e15 | 374 | { |
LancasterUniversity | 65:f7ebabf23e15 | 375 | shake.shaken = 0; |
LancasterUniversity | 65:f7ebabf23e15 | 376 | shake.timer = 0; |
LancasterUniversity | 65:f7ebabf23e15 | 377 | shake.count = 0; |
LancasterUniversity | 65:f7ebabf23e15 | 378 | } |
LancasterUniversity | 65:f7ebabf23e15 | 379 | |
LancasterUniversity | 65:f7ebabf23e15 | 380 | // Decay our count of zero crossings over time. We don't want them to accumulate if the user performs slow moving motions. |
LancasterUniversity | 65:f7ebabf23e15 | 381 | else if (!shake.shaken && shake.timer >= MICROBIT_ACCELEROMETER_SHAKE_DAMPING) |
LancasterUniversity | 65:f7ebabf23e15 | 382 | { |
LancasterUniversity | 65:f7ebabf23e15 | 383 | shake.timer = 0; |
LancasterUniversity | 65:f7ebabf23e15 | 384 | if (shake.count > 0) |
LancasterUniversity | 65:f7ebabf23e15 | 385 | shake.count--; |
LancasterUniversity | 65:f7ebabf23e15 | 386 | } |
LancasterUniversity | 65:f7ebabf23e15 | 387 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 388 | |
LancasterUniversity | 42:e2869e0fa366 | 389 | if (instantaneousAccelerationSquared() < MICROBIT_ACCELEROMETER_FREEFALL_THRESHOLD) |
LancasterUniversity | 42:e2869e0fa366 | 390 | return MICROBIT_ACCELEROMETER_EVT_FREEFALL; |
LancasterUniversity | 42:e2869e0fa366 | 391 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 392 | // Determine our posture. |
Jonathan Austin |
1:8aa5cdb4ab67 | 393 | if (getX() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) |
LancasterUniversity | 39:112df23f039f | 394 | return MICROBIT_ACCELEROMETER_EVT_TILT_LEFT; |
Jonathan Austin |
1:8aa5cdb4ab67 | 395 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 396 | if (getX() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) |
LancasterUniversity | 39:112df23f039f | 397 | return MICROBIT_ACCELEROMETER_EVT_TILT_RIGHT; |
Jonathan Austin |
1:8aa5cdb4ab67 | 398 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 399 | if (getY() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) |
LancasterUniversity | 39:112df23f039f | 400 | return MICROBIT_ACCELEROMETER_EVT_TILT_DOWN; |
Jonathan Austin |
1:8aa5cdb4ab67 | 401 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 402 | if (getY() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) |
LancasterUniversity | 39:112df23f039f | 403 | return MICROBIT_ACCELEROMETER_EVT_TILT_UP; |
Jonathan Austin |
1:8aa5cdb4ab67 | 404 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 405 | if (getZ() < (-1000 + MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) |
LancasterUniversity | 39:112df23f039f | 406 | return MICROBIT_ACCELEROMETER_EVT_FACE_UP; |
Jonathan Austin |
1:8aa5cdb4ab67 | 407 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 408 | if (getZ() > (1000 - MICROBIT_ACCELEROMETER_TILT_TOLERANCE)) |
LancasterUniversity | 39:112df23f039f | 409 | return MICROBIT_ACCELEROMETER_EVT_FACE_DOWN; |
Jonathan Austin |
1:8aa5cdb4ab67 | 410 | |
LancasterUniversity | 39:112df23f039f | 411 | return MICROBIT_ACCELEROMETER_EVT_NONE; |
Jonathan Austin |
1:8aa5cdb4ab67 | 412 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 413 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 414 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 415 | * Updates the basic gesture recognizer. This performs instantaneous pose recognition, and also some low pass filtering to promote |
Jonathan Austin |
1:8aa5cdb4ab67 | 416 | * stability. |
Jonathan Austin |
1:8aa5cdb4ab67 | 417 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 418 | void MicroBitAccelerometer::updateGesture() |
Jonathan Austin |
1:8aa5cdb4ab67 | 419 | { |
LancasterUniversity | 38:1a9e8e5e23f2 | 420 | // Check for High/Low G force events - typically impulses, impacts etc. |
LancasterUniversity | 38:1a9e8e5e23f2 | 421 | // Again, during such spikes, these event take priority of the posture of the device. |
LancasterUniversity | 38:1a9e8e5e23f2 | 422 | // For these events, we don't perform any low pass filtering. |
LancasterUniversity | 38:1a9e8e5e23f2 | 423 | int force = instantaneousAccelerationSquared(); |
LancasterUniversity | 38:1a9e8e5e23f2 | 424 | |
LancasterUniversity | 38:1a9e8e5e23f2 | 425 | if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD) |
LancasterUniversity | 38:1a9e8e5e23f2 | 426 | { |
LancasterUniversity | 38:1a9e8e5e23f2 | 427 | if (force > MICROBIT_ACCELEROMETER_3G_THRESHOLD && !shake.impulse_3) |
LancasterUniversity | 38:1a9e8e5e23f2 | 428 | { |
LancasterUniversity | 39:112df23f039f | 429 | MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_3G); |
LancasterUniversity | 38:1a9e8e5e23f2 | 430 | shake.impulse_3 = 1; |
LancasterUniversity | 38:1a9e8e5e23f2 | 431 | } |
LancasterUniversity | 38:1a9e8e5e23f2 | 432 | if (force > MICROBIT_ACCELEROMETER_6G_THRESHOLD && !shake.impulse_6) |
LancasterUniversity | 38:1a9e8e5e23f2 | 433 | { |
LancasterUniversity | 39:112df23f039f | 434 | MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_6G); |
LancasterUniversity | 38:1a9e8e5e23f2 | 435 | shake.impulse_6 = 1; |
LancasterUniversity | 38:1a9e8e5e23f2 | 436 | } |
LancasterUniversity | 38:1a9e8e5e23f2 | 437 | if (force > MICROBIT_ACCELEROMETER_8G_THRESHOLD && !shake.impulse_8) |
LancasterUniversity | 38:1a9e8e5e23f2 | 438 | { |
LancasterUniversity | 39:112df23f039f | 439 | MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_8G); |
LancasterUniversity | 38:1a9e8e5e23f2 | 440 | shake.impulse_8 = 1; |
LancasterUniversity | 38:1a9e8e5e23f2 | 441 | } |
LancasterUniversity | 38:1a9e8e5e23f2 | 442 | |
LancasterUniversity | 38:1a9e8e5e23f2 | 443 | impulseSigma = 0; |
LancasterUniversity | 38:1a9e8e5e23f2 | 444 | } |
LancasterUniversity | 38:1a9e8e5e23f2 | 445 | |
LancasterUniversity | 38:1a9e8e5e23f2 | 446 | // Reset the impulse event onve the acceleration has subsided. |
LancasterUniversity | 38:1a9e8e5e23f2 | 447 | if (impulseSigma < MICROBIT_ACCELEROMETER_GESTURE_DAMPING) |
LancasterUniversity | 38:1a9e8e5e23f2 | 448 | impulseSigma++; |
LancasterUniversity | 38:1a9e8e5e23f2 | 449 | else |
LancasterUniversity | 42:e2869e0fa366 | 450 | shake.impulse_3 = shake.impulse_6 = shake.impulse_8 = 0; |
LancasterUniversity | 38:1a9e8e5e23f2 | 451 | |
LancasterUniversity | 38:1a9e8e5e23f2 | 452 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 453 | // Determine what it looks like we're doing based on the latest sample... |
LancasterUniversity | 39:112df23f039f | 454 | uint16_t g = instantaneousPosture(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 455 | |
LancasterUniversity | 65:f7ebabf23e15 | 456 | if (g == MICROBIT_ACCELEROMETER_EVT_SHAKE) |
LancasterUniversity | 65:f7ebabf23e15 | 457 | { |
LancasterUniversity | 65:f7ebabf23e15 | 458 | MicroBitEvent e(MICROBIT_ID_GESTURE, MICROBIT_ACCELEROMETER_EVT_SHAKE); |
LancasterUniversity | 65:f7ebabf23e15 | 459 | return; |
LancasterUniversity | 65:f7ebabf23e15 | 460 | } |
LancasterUniversity | 65:f7ebabf23e15 | 461 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 462 | // Perform some low pass filtering to reduce jitter from any detected effects |
Jonathan Austin |
1:8aa5cdb4ab67 | 463 | if (g == currentGesture) |
Jonathan Austin |
1:8aa5cdb4ab67 | 464 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 465 | if (sigma < MICROBIT_ACCELEROMETER_GESTURE_DAMPING) |
Jonathan Austin |
1:8aa5cdb4ab67 | 466 | sigma++; |
Jonathan Austin |
1:8aa5cdb4ab67 | 467 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 468 | else |
Jonathan Austin |
1:8aa5cdb4ab67 | 469 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 470 | currentGesture = g; |
Jonathan Austin |
1:8aa5cdb4ab67 | 471 | sigma = 0; |
Jonathan Austin |
1:8aa5cdb4ab67 | 472 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 473 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 474 | // If we've reached threshold, update our record and raise the relevant event... |
Jonathan Austin |
1:8aa5cdb4ab67 | 475 | if (currentGesture != lastGesture && sigma >= MICROBIT_ACCELEROMETER_GESTURE_DAMPING) |
Jonathan Austin |
1:8aa5cdb4ab67 | 476 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 477 | lastGesture = currentGesture; |
Jonathan Austin |
1:8aa5cdb4ab67 | 478 | MicroBitEvent e(MICROBIT_ID_GESTURE, lastGesture); |
Jonathan Austin |
1:8aa5cdb4ab67 | 479 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 480 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 481 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 482 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 483 | * Attempts to set the sample rate of the accelerometer to the specified value (in ms). |
Jonathan Austin |
1:8aa5cdb4ab67 | 484 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 485 | * @param period the requested time between samples, in milliseconds. |
Jonathan Austin |
1:8aa5cdb4ab67 | 486 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 487 | * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails. |
Jonathan Austin |
1:8aa5cdb4ab67 | 488 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 489 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 490 | * // sample rate is now 20 ms. |
Jonathan Austin |
1:8aa5cdb4ab67 | 491 | * accelerometer.setPeriod(20); |
Jonathan Austin |
1:8aa5cdb4ab67 | 492 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 493 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 494 | * @note The requested rate may not be possible on the hardware. In this case, the |
Jonathan Austin |
1:8aa5cdb4ab67 | 495 | * nearest lower rate is chosen. |
Jonathan Austin |
1:8aa5cdb4ab67 | 496 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 497 | int MicroBitAccelerometer::setPeriod(int period) |
Jonathan Austin |
1:8aa5cdb4ab67 | 498 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 499 | this->samplePeriod = period; |
Jonathan Austin |
1:8aa5cdb4ab67 | 500 | return this->configure(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 501 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 502 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 503 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 504 | * Reads the currently configured sample rate of the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 505 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 506 | * @return The time between samples, in milliseconds. |
Jonathan Austin |
1:8aa5cdb4ab67 | 507 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 508 | int MicroBitAccelerometer::getPeriod() |
Jonathan Austin |
1:8aa5cdb4ab67 | 509 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 510 | return (int)samplePeriod; |
Jonathan Austin |
1:8aa5cdb4ab67 | 511 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 512 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 513 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 514 | * Attempts to set the sample range of the accelerometer to the specified value (in g). |
Jonathan Austin |
1:8aa5cdb4ab67 | 515 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 516 | * @param range The requested sample range of samples, in g. |
Jonathan Austin |
1:8aa5cdb4ab67 | 517 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 518 | * @return MICROBIT_OK on success, MICROBIT_I2C_ERROR is the request fails. |
Jonathan Austin |
1:8aa5cdb4ab67 | 519 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 520 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 521 | * // the sample range of the accelerometer is now 8G. |
Jonathan Austin |
1:8aa5cdb4ab67 | 522 | * accelerometer.setRange(8); |
Jonathan Austin |
1:8aa5cdb4ab67 | 523 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 524 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 525 | * @note The requested range may not be possible on the hardware. In this case, the |
Jonathan Austin |
1:8aa5cdb4ab67 | 526 | * nearest lower range is chosen. |
Jonathan Austin |
1:8aa5cdb4ab67 | 527 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 528 | int MicroBitAccelerometer::setRange(int range) |
Jonathan Austin |
1:8aa5cdb4ab67 | 529 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 530 | this->sampleRange = range; |
Jonathan Austin |
1:8aa5cdb4ab67 | 531 | return this->configure(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 532 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 533 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 534 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 535 | * Reads the currently configured sample range of the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 536 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 537 | * @return The sample range, in g. |
Jonathan Austin |
1:8aa5cdb4ab67 | 538 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 539 | int MicroBitAccelerometer::getRange() |
Jonathan Austin |
1:8aa5cdb4ab67 | 540 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 541 | return (int)sampleRange; |
Jonathan Austin |
1:8aa5cdb4ab67 | 542 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 543 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 544 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 545 | * Reads the value of the X axis from the latest update retrieved from the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 546 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 547 | * @param system The coordinate system to use. By default, a simple cartesian system is provided. |
Jonathan Austin |
1:8aa5cdb4ab67 | 548 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 549 | * @return The force measured in the X axis, in milli-g. |
Jonathan Austin |
1:8aa5cdb4ab67 | 550 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 551 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 552 | * accelerometer.getX(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 553 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 554 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 555 | int MicroBitAccelerometer::getX(MicroBitCoordinateSystem system) |
Jonathan Austin |
1:8aa5cdb4ab67 | 556 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 557 | updateSample(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 558 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 559 | switch (system) |
Jonathan Austin |
1:8aa5cdb4ab67 | 560 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 561 | case SIMPLE_CARTESIAN: |
Jonathan Austin |
1:8aa5cdb4ab67 | 562 | return -sample.x; |
Jonathan Austin |
1:8aa5cdb4ab67 | 563 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 564 | case NORTH_EAST_DOWN: |
Jonathan Austin |
1:8aa5cdb4ab67 | 565 | return sample.y; |
Jonathan Austin |
1:8aa5cdb4ab67 | 566 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 567 | case RAW: |
Jonathan Austin |
1:8aa5cdb4ab67 | 568 | default: |
Jonathan Austin |
1:8aa5cdb4ab67 | 569 | return sample.x; |
Jonathan Austin |
1:8aa5cdb4ab67 | 570 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 571 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 572 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 573 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 574 | * Reads the value of the Y axis from the latest update retrieved from the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 575 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 576 | * @return The force measured in the Y axis, in milli-g. |
Jonathan Austin |
1:8aa5cdb4ab67 | 577 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 578 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 579 | * accelerometer.getY(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 580 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 581 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 582 | int MicroBitAccelerometer::getY(MicroBitCoordinateSystem system) |
Jonathan Austin |
1:8aa5cdb4ab67 | 583 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 584 | updateSample(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 585 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 586 | switch (system) |
Jonathan Austin |
1:8aa5cdb4ab67 | 587 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 588 | case SIMPLE_CARTESIAN: |
Jonathan Austin |
1:8aa5cdb4ab67 | 589 | return -sample.y; |
Jonathan Austin |
1:8aa5cdb4ab67 | 590 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 591 | case NORTH_EAST_DOWN: |
Jonathan Austin |
1:8aa5cdb4ab67 | 592 | return -sample.x; |
Jonathan Austin |
1:8aa5cdb4ab67 | 593 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 594 | case RAW: |
Jonathan Austin |
1:8aa5cdb4ab67 | 595 | default: |
Jonathan Austin |
1:8aa5cdb4ab67 | 596 | return sample.y; |
Jonathan Austin |
1:8aa5cdb4ab67 | 597 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 598 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 599 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 600 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 601 | * Reads the value of the Z axis from the latest update retrieved from the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 602 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 603 | * @return The force measured in the Z axis, in milli-g. |
Jonathan Austin |
1:8aa5cdb4ab67 | 604 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 605 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 606 | * accelerometer.getZ(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 607 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 608 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 609 | int MicroBitAccelerometer::getZ(MicroBitCoordinateSystem system) |
Jonathan Austin |
1:8aa5cdb4ab67 | 610 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 611 | updateSample(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 612 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 613 | switch (system) |
Jonathan Austin |
1:8aa5cdb4ab67 | 614 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 615 | case NORTH_EAST_DOWN: |
Jonathan Austin |
1:8aa5cdb4ab67 | 616 | return -sample.z; |
Jonathan Austin |
1:8aa5cdb4ab67 | 617 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 618 | case SIMPLE_CARTESIAN: |
Jonathan Austin |
1:8aa5cdb4ab67 | 619 | case RAW: |
Jonathan Austin |
1:8aa5cdb4ab67 | 620 | default: |
Jonathan Austin |
1:8aa5cdb4ab67 | 621 | return sample.z; |
Jonathan Austin |
1:8aa5cdb4ab67 | 622 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 623 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 624 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 625 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 626 | * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 627 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 628 | * @return The pitch of the device, in degrees. |
Jonathan Austin |
1:8aa5cdb4ab67 | 629 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 630 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 631 | * accelerometer.getPitch(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 632 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 633 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 634 | int MicroBitAccelerometer::getPitch() |
Jonathan Austin |
1:8aa5cdb4ab67 | 635 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 636 | return (int) ((360*getPitchRadians()) / (2*PI)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 637 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 638 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 639 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 640 | * Provides a rotation compensated pitch of the device, based on the latest update retrieved from the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 641 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 642 | * @return The pitch of the device, in radians. |
Jonathan Austin |
1:8aa5cdb4ab67 | 643 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 644 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 645 | * accelerometer.getPitchRadians(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 646 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 647 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 648 | float MicroBitAccelerometer::getPitchRadians() |
Jonathan Austin |
1:8aa5cdb4ab67 | 649 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 650 | if (!(status & MICROBIT_ACCEL_PITCH_ROLL_VALID)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 651 | recalculatePitchRoll(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 652 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 653 | return pitch; |
Jonathan Austin |
1:8aa5cdb4ab67 | 654 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 655 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 656 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 657 | * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 658 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 659 | * @return The roll of the device, in degrees. |
Jonathan Austin |
1:8aa5cdb4ab67 | 660 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 661 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 662 | * accelerometer.getRoll(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 663 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 664 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 665 | int MicroBitAccelerometer::getRoll() |
Jonathan Austin |
1:8aa5cdb4ab67 | 666 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 667 | return (int) ((360*getRollRadians()) / (2*PI)); |
Jonathan Austin |
1:8aa5cdb4ab67 | 668 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 669 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 670 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 671 | * Provides a rotation compensated roll of the device, based on the latest update retrieved from the accelerometer. |
Jonathan Austin |
1:8aa5cdb4ab67 | 672 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 673 | * @return The roll of the device, in radians. |
Jonathan Austin |
1:8aa5cdb4ab67 | 674 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 675 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 676 | * accelerometer.getRollRadians(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 677 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 678 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 679 | float MicroBitAccelerometer::getRollRadians() |
Jonathan Austin |
1:8aa5cdb4ab67 | 680 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 681 | if (!(status & MICROBIT_ACCEL_PITCH_ROLL_VALID)) |
Jonathan Austin |
1:8aa5cdb4ab67 | 682 | recalculatePitchRoll(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 683 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 684 | return roll; |
Jonathan Austin |
1:8aa5cdb4ab67 | 685 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 686 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 687 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 688 | * Recalculate roll and pitch values for the current sample. |
Jonathan Austin |
1:8aa5cdb4ab67 | 689 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 690 | * @note We only do this at most once per sample, as the necessary trigonemteric functions are rather |
Jonathan Austin |
1:8aa5cdb4ab67 | 691 | * heavyweight for a CPU without a floating point unit. |
Jonathan Austin |
1:8aa5cdb4ab67 | 692 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 693 | void MicroBitAccelerometer::recalculatePitchRoll() |
Jonathan Austin |
1:8aa5cdb4ab67 | 694 | { |
LancasterUniversity | 43:0374ea4d2167 | 695 | double x = (double) getX(NORTH_EAST_DOWN); |
LancasterUniversity | 43:0374ea4d2167 | 696 | double y = (double) getY(NORTH_EAST_DOWN); |
LancasterUniversity | 43:0374ea4d2167 | 697 | double z = (double) getZ(NORTH_EAST_DOWN); |
Jonathan Austin |
1:8aa5cdb4ab67 | 698 | |
LancasterUniversity | 43:0374ea4d2167 | 699 | roll = atan2(y, z); |
LancasterUniversity | 43:0374ea4d2167 | 700 | pitch = atan(-x / (y*sin(roll) + z*cos(roll))); |
LancasterUniversity | 6:2e1c2e0d8c7a | 701 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 702 | status |= MICROBIT_ACCEL_PITCH_ROLL_VALID; |
Jonathan Austin |
1:8aa5cdb4ab67 | 703 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 704 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 705 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 706 | * Retrieves the last recorded gesture. |
Jonathan Austin |
1:8aa5cdb4ab67 | 707 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 708 | * @return The last gesture that was detected. |
Jonathan Austin |
1:8aa5cdb4ab67 | 709 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 710 | * Example: |
Jonathan Austin |
1:8aa5cdb4ab67 | 711 | * @code |
Jonathan Austin |
1:8aa5cdb4ab67 | 712 | * MicroBitDisplay display; |
Jonathan Austin |
1:8aa5cdb4ab67 | 713 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 714 | * if (accelerometer.getGesture() == SHAKE) |
Jonathan Austin |
1:8aa5cdb4ab67 | 715 | * display.scroll("SHAKE!"); |
Jonathan Austin |
1:8aa5cdb4ab67 | 716 | * @endcode |
Jonathan Austin |
1:8aa5cdb4ab67 | 717 | */ |
LancasterUniversity | 39:112df23f039f | 718 | uint16_t MicroBitAccelerometer::getGesture() |
Jonathan Austin |
1:8aa5cdb4ab67 | 719 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 720 | return lastGesture; |
Jonathan Austin |
1:8aa5cdb4ab67 | 721 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 722 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 723 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 724 | * A periodic callback invoked by the fiber scheduler idle thread. |
Jonathan Austin |
1:8aa5cdb4ab67 | 725 | * |
Jonathan Austin |
1:8aa5cdb4ab67 | 726 | * Internally calls updateSample(). |
Jonathan Austin |
1:8aa5cdb4ab67 | 727 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 728 | void MicroBitAccelerometer::idleTick() |
Jonathan Austin |
1:8aa5cdb4ab67 | 729 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 730 | updateSample(); |
Jonathan Austin |
1:8aa5cdb4ab67 | 731 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 732 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 733 | /** |
Jonathan Austin |
1:8aa5cdb4ab67 | 734 | * Destructor for MicroBitAccelerometer, where we deregister from the array of fiber components. |
Jonathan Austin |
1:8aa5cdb4ab67 | 735 | */ |
Jonathan Austin |
1:8aa5cdb4ab67 | 736 | MicroBitAccelerometer::~MicroBitAccelerometer() |
Jonathan Austin |
1:8aa5cdb4ab67 | 737 | { |
Jonathan Austin |
1:8aa5cdb4ab67 | 738 | fiber_remove_idle_component(this); |
Jonathan Austin |
1:8aa5cdb4ab67 | 739 | } |
Jonathan Austin |
1:8aa5cdb4ab67 | 740 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 741 | const MMA8653SampleRangeConfig MMA8653SampleRange[MMA8653_SAMPLE_RANGES] = { |
Jonathan Austin |
1:8aa5cdb4ab67 | 742 | {2, 0}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 743 | {4, 1}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 744 | {8, 2} |
Jonathan Austin |
1:8aa5cdb4ab67 | 745 | }; |
Jonathan Austin |
1:8aa5cdb4ab67 | 746 | |
Jonathan Austin |
1:8aa5cdb4ab67 | 747 | const MMA8653SampleRateConfig MMA8653SampleRate[MMA8653_SAMPLE_RATES] = { |
Jonathan Austin |
1:8aa5cdb4ab67 | 748 | {1250, 0x00}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 749 | {2500, 0x08}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 750 | {5000, 0x10}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 751 | {10000, 0x18}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 752 | {20000, 0x20}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 753 | {80000, 0x28}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 754 | {160000, 0x30}, |
Jonathan Austin |
1:8aa5cdb4ab67 | 755 | {640000, 0x38} |
LancasterUniversity | 6:2e1c2e0d8c7a | 756 | }; |