
BLE GATT-service implementation for high quantity sensor data from a MPU6050-accelerator/gyroscope
Dependencies: BLE_API mbed nRF51822 MPU6050_lib
MPU6050Service.h@13:496c0f5e8a61, 2015-09-22 (annotated)
- Committer:
- fruediger
- Date:
- Tue Sep 22 10:50:59 2015 +0000
- Revision:
- 13:496c0f5e8a61
- Parent:
- 12:dc46aa2edccd
last commit before making this a public repository
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
fruediger | 3:d72d9195dc26 | 1 | #pragma once |
fruediger | 3:d72d9195dc26 | 2 | #ifndef __MPU6050_SERVICE_H__ |
fruediger | 3:d72d9195dc26 | 3 | #define __MPU6050_SERVICE_H__ |
fruediger | 3:d72d9195dc26 | 4 | |
fruediger | 3:d72d9195dc26 | 5 | #include "BLE.h" |
fruediger | 9:6a28d9c0e486 | 6 | #include "MPU6050.h" |
fruediger | 3:d72d9195dc26 | 7 | |
fruediger | 3:d72d9195dc26 | 8 | class MPU6050Service |
fruediger | 3:d72d9195dc26 | 9 | { |
fruediger | 3:d72d9195dc26 | 10 | public: |
fruediger | 3:d72d9195dc26 | 11 | enum |
fruediger | 3:d72d9195dc26 | 12 | { |
fruediger | 9:6a28d9c0e486 | 13 | UUID_MPU6050_SERVICE = 0xA123, |
fruediger | 3:d72d9195dc26 | 14 | |
fruediger | 3:d72d9195dc26 | 15 | UUID_MPU6050_SENSOR_DATA_CHAR = 0xA124, |
fruediger | 10:b305e261e7d1 | 16 | UUID_MPU6050_MOTION_INDICATOR_CHAR = 0xA125, |
fruediger | 10:b305e261e7d1 | 17 | UUID_MPU6050_MEASURING_RANGE_CHAR = 0xA126, |
fruediger | 10:b305e261e7d1 | 18 | UUID_MPU6050_MASTER_CLOCK_CHAR = 0xA127 |
fruediger | 3:d72d9195dc26 | 19 | }; |
fruediger | 3:d72d9195dc26 | 20 | |
fruediger | 9:6a28d9c0e486 | 21 | enum MeasuringRange |
fruediger | 9:6a28d9c0e486 | 22 | { |
fruediger | 9:6a28d9c0e486 | 23 | ACCEL_RANGE_2G = 0x00, // 0b__00 |
fruediger | 9:6a28d9c0e486 | 24 | ACCEL_RANGE_4G = 0x01, // 0b__01 |
fruediger | 9:6a28d9c0e486 | 25 | ACCEL_RANGE_8G = 0x02, // 0b__10 |
fruediger | 9:6a28d9c0e486 | 26 | ACCEL_RANGE_16G = 0x03, // 0b__11 |
fruediger | 9:6a28d9c0e486 | 27 | |
fruediger | 10:b305e261e7d1 | 28 | ACCEL_RANGE_MASK = 0x03, // 0b__11 |
fruediger | 10:b305e261e7d1 | 29 | |
fruediger | 9:6a28d9c0e486 | 30 | GYRO_RANGE_250 = 0x00, // 0b00__ |
fruediger | 9:6a28d9c0e486 | 31 | GYRO_RANGE_500 = 0x04, // 0b01__ |
fruediger | 9:6a28d9c0e486 | 32 | GYRO_RANGE_1000 = 0x08, // 0b10__ |
fruediger | 10:b305e261e7d1 | 33 | GYRO_RANGE_2000 = 0x0C, // 0b11__ |
fruediger | 10:b305e261e7d1 | 34 | |
fruediger | 10:b305e261e7d1 | 35 | GYRO_RANGE_MASK = 0x0C // 0b11__ |
fruediger | 9:6a28d9c0e486 | 36 | }; |
fruediger | 9:6a28d9c0e486 | 37 | friend inline MeasuringRange operator|(MeasuringRange a, MeasuringRange b) { return static_cast<MeasuringRange>(static_cast<int>(a) | static_cast<int>(b)); } |
fruediger | 10:b305e261e7d1 | 38 | friend inline MeasuringRange operator&(MeasuringRange a, MeasuringRange b) { return static_cast<MeasuringRange>(static_cast<int>(a) & static_cast<int>(b)); } |
fruediger | 9:6a28d9c0e486 | 39 | |
fruediger | 10:b305e261e7d1 | 40 | enum MotionIndicator |
fruediger | 9:6a28d9c0e486 | 41 | { |
fruediger | 10:b305e261e7d1 | 42 | MOTION_IND_NEGATIVE_X = MPU6050::MOT_NEGATIVE_X, |
fruediger | 10:b305e261e7d1 | 43 | MOTION_IND_POSITIVE_X = MPU6050::MOT_POSITIVE_X, |
fruediger | 10:b305e261e7d1 | 44 | |
fruediger | 10:b305e261e7d1 | 45 | MOTION_IND_NEGATIVE_Y = MPU6050::MOT_NEGATIVE_Y, |
fruediger | 10:b305e261e7d1 | 46 | MOTION_IND_POSITIVE_Y = MPU6050::MOT_POSITIVE_Y, |
fruediger | 10:b305e261e7d1 | 47 | |
fruediger | 10:b305e261e7d1 | 48 | MOTION_IND_NEGATIVE_Z = MPU6050::MOT_NEGATIVE_Z, |
fruediger | 10:b305e261e7d1 | 49 | MOTION_IND_POSITIVE_Z = MPU6050::MOT_POSITIVE_Z, |
fruediger | 9:6a28d9c0e486 | 50 | |
fruediger | 10:b305e261e7d1 | 51 | MOTION_IND_FREEFALL = 0x02, // 0b00000010 |
fruediger | 10:b305e261e7d1 | 52 | MOTION_IND_ZERO_MOTION = MPU6050::MOT_ZERO |
fruediger | 10:b305e261e7d1 | 53 | }; |
fruediger | 10:b305e261e7d1 | 54 | friend inline MotionIndicator operator|(MotionIndicator a, MotionIndicator b) { return static_cast<MotionIndicator>(static_cast<int>(a) | static_cast<int>(b)); } |
fruediger | 10:b305e261e7d1 | 55 | friend inline MotionIndicator operator&(MotionIndicator a, MotionIndicator b) { return static_cast<MotionIndicator>(static_cast<int>(a) & static_cast<int>(b)); } |
fruediger | 10:b305e261e7d1 | 56 | |
fruediger | 10:b305e261e7d1 | 57 | typedef __packed struct |
fruediger | 10:b305e261e7d1 | 58 | { |
fruediger | 10:b305e261e7d1 | 59 | int16_t accelX, accelY, accelZ; |
fruediger | 10:b305e261e7d1 | 60 | |
fruediger | 10:b305e261e7d1 | 61 | int16_t temperature; |
fruediger | 9:6a28d9c0e486 | 62 | |
fruediger | 10:b305e261e7d1 | 63 | int16_t gyroX, gyroY, gyroZ; |
fruediger | 9:6a28d9c0e486 | 64 | |
fruediger | 10:b305e261e7d1 | 65 | uint32_t clock_us; |
fruediger | 9:6a28d9c0e486 | 66 | } SensorData; |
fruediger | 9:6a28d9c0e486 | 67 | |
fruediger | 10:b305e261e7d1 | 68 | typedef __packed struct |
fruediger | 10:b305e261e7d1 | 69 | { |
fruediger | 10:b305e261e7d1 | 70 | MotionIndicator indicator; |
fruediger | 10:b305e261e7d1 | 71 | |
fruediger | 10:b305e261e7d1 | 72 | uint32_t clock_us; |
fruediger | 10:b305e261e7d1 | 73 | |
fruediger | 10:b305e261e7d1 | 74 | } MotionIndication; |
fruediger | 10:b305e261e7d1 | 75 | |
fruediger | 3:d72d9195dc26 | 76 | MPU6050Service |
fruediger | 3:d72d9195dc26 | 77 | ( |
fruediger | 9:6a28d9c0e486 | 78 | BLE &ble, |
fruediger | 9:6a28d9c0e486 | 79 | MPU6050 &mpu6050, |
fruediger | 12:dc46aa2edccd | 80 | InterruptIn *interruptIn = NULL, |
fruediger | 9:6a28d9c0e486 | 81 | const SensorData *initialData = NULL, |
fruediger | 9:6a28d9c0e486 | 82 | const MeasuringRange measuringRange = ACCEL_RANGE_2G | GYRO_RANGE_250, |
fruediger | 9:6a28d9c0e486 | 83 | const uint32_t masterClock_us = 0 |
fruediger | 3:d72d9195dc26 | 84 | ) : |
fruediger | 3:d72d9195dc26 | 85 | gattServer(ble.gattServer()), |
fruediger | 9:6a28d9c0e486 | 86 | mpu(mpu6050), |
fruediger | 12:dc46aa2edccd | 87 | intIn(interruptIn), |
fruediger | 10:b305e261e7d1 | 88 | timer(), |
fruediger | 9:6a28d9c0e486 | 89 | |
fruediger | 9:6a28d9c0e486 | 90 | _isRunning(false), |
fruediger | 9:6a28d9c0e486 | 91 | updateSensorDataCharacteristicTrigger(false), |
fruediger | 12:dc46aa2edccd | 92 | updateMotionIndicatorCharacteristicTrigger(false), |
fruediger | 12:dc46aa2edccd | 93 | updateMeasuringRangeTrigger(false), |
fruediger | 9:6a28d9c0e486 | 94 | |
fruediger | 10:b305e261e7d1 | 95 | timerOffset_us(masterClock_us), |
fruediger | 9:6a28d9c0e486 | 96 | |
fruediger | 3:d72d9195dc26 | 97 | sensorDataCharacteristic |
fruediger | 3:d72d9195dc26 | 98 | ( |
fruediger | 3:d72d9195dc26 | 99 | UUID_MPU6050_SENSOR_DATA_CHAR, |
fruediger | 9:6a28d9c0e486 | 100 | (SensorData*)initialData, |
fruediger | 3:d72d9195dc26 | 101 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY // improving latency by repurposing notifications and "writing" the client |
fruediger | 3:d72d9195dc26 | 102 | // (i.e. indicating the client but not wait for a response) |
fruediger | 3:d72d9195dc26 | 103 | ), |
fruediger | 10:b305e261e7d1 | 104 | motionIndicatorCharaceristic |
fruediger | 10:b305e261e7d1 | 105 | ( |
fruediger | 10:b305e261e7d1 | 106 | UUID_MPU6050_MOTION_INDICATOR_CHAR, |
fruediger | 10:b305e261e7d1 | 107 | NULL, |
fruediger | 10:b305e261e7d1 | 108 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY |
fruediger | 10:b305e261e7d1 | 109 | ), |
fruediger | 3:d72d9195dc26 | 110 | measuringRangeCharacteristic |
fruediger | 3:d72d9195dc26 | 111 | ( |
fruediger | 3:d72d9195dc26 | 112 | UUID_MPU6050_MEASURING_RANGE_CHAR, |
fruediger | 9:6a28d9c0e486 | 113 | (MeasuringRange*)&measuringRange, |
fruediger | 3:d72d9195dc26 | 114 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE // also improving latency |
fruediger | 3:d72d9195dc26 | 115 | ), |
fruediger | 3:d72d9195dc26 | 116 | masterClockCharacteristic |
fruediger | 3:d72d9195dc26 | 117 | ( |
fruediger | 3:d72d9195dc26 | 118 | UUID_MPU6050_MASTER_CLOCK_CHAR, |
fruediger | 4:a97e6917f731 | 119 | (uint32_t*)&masterClock_us, |
fruediger | 3:d72d9195dc26 | 120 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE // look above again |
fruediger | 3:d72d9195dc26 | 121 | ) |
fruediger | 3:d72d9195dc26 | 122 | { |
fruediger | 7:af3e2b9c137a | 123 | static bool serviceAdded = false; |
fruediger | 3:d72d9195dc26 | 124 | if (serviceAdded) |
fruediger | 3:d72d9195dc26 | 125 | return; |
fruediger | 3:d72d9195dc26 | 126 | |
fruediger | 3:d72d9195dc26 | 127 | GattCharacteristic *charTable[] = |
fruediger | 3:d72d9195dc26 | 128 | { |
fruediger | 3:d72d9195dc26 | 129 | &sensorDataCharacteristic, |
fruediger | 10:b305e261e7d1 | 130 | &motionIndicatorCharaceristic, |
fruediger | 3:d72d9195dc26 | 131 | &measuringRangeCharacteristic, |
fruediger | 3:d72d9195dc26 | 132 | &masterClockCharacteristic |
fruediger | 3:d72d9195dc26 | 133 | }; |
fruediger | 3:d72d9195dc26 | 134 | |
fruediger | 9:6a28d9c0e486 | 135 | GattService mpu6050Service(UUID_MPU6050_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic*)); |
fruediger | 3:d72d9195dc26 | 136 | |
fruediger | 3:d72d9195dc26 | 137 | gattServer.addService(mpu6050Service); |
fruediger | 3:d72d9195dc26 | 138 | gattServer.onDataSent(this, &MPU6050Service::dataSentCallback); |
fruediger | 3:d72d9195dc26 | 139 | gattServer.onDataWritten(this, &MPU6050Service::dataWrittenCallback); |
fruediger | 3:d72d9195dc26 | 140 | |
fruediger | 12:dc46aa2edccd | 141 | if (intIn != NULL) |
fruediger | 12:dc46aa2edccd | 142 | intIn->rise(this, &MPU6050Service::interruptRiseCallback); |
fruediger | 10:b305e261e7d1 | 143 | |
fruediger | 3:d72d9195dc26 | 144 | serviceAdded = true; |
fruediger | 3:d72d9195dc26 | 145 | } |
fruediger | 3:d72d9195dc26 | 146 | |
fruediger | 9:6a28d9c0e486 | 147 | bool isRunning() |
fruediger | 3:d72d9195dc26 | 148 | { |
fruediger | 9:6a28d9c0e486 | 149 | return _isRunning; |
fruediger | 9:6a28d9c0e486 | 150 | } |
fruediger | 9:6a28d9c0e486 | 151 | |
fruediger | 9:6a28d9c0e486 | 152 | bool start() |
fruediger | 9:6a28d9c0e486 | 153 | { |
fruediger | 9:6a28d9c0e486 | 154 | if (!deviceReset()) |
fruediger | 9:6a28d9c0e486 | 155 | { |
fruediger | 9:6a28d9c0e486 | 156 | _isRunning = false; |
fruediger | 9:6a28d9c0e486 | 157 | return false; |
fruediger | 9:6a28d9c0e486 | 158 | } |
fruediger | 10:b305e261e7d1 | 159 | |
fruediger | 10:b305e261e7d1 | 160 | timer.stop(); |
fruediger | 10:b305e261e7d1 | 161 | timer.reset(); |
fruediger | 10:b305e261e7d1 | 162 | timer.start(); |
fruediger | 9:6a28d9c0e486 | 163 | |
fruediger | 9:6a28d9c0e486 | 164 | _isRunning = true; |
fruediger | 9:6a28d9c0e486 | 165 | |
fruediger | 3:d72d9195dc26 | 166 | // sending data once will invoke the dataSent(...) callback later on |
fruediger | 9:6a28d9c0e486 | 167 | // which will be looped by the event driven behavior of the BLE API (because it will send data again on it's own and so on) |
fruediger | 9:6a28d9c0e486 | 168 | updateSensorDataCharacteristicTrigger = true; |
fruediger | 9:6a28d9c0e486 | 169 | |
fruediger | 9:6a28d9c0e486 | 170 | return true; |
fruediger | 9:6a28d9c0e486 | 171 | } |
fruediger | 9:6a28d9c0e486 | 172 | |
fruediger | 9:6a28d9c0e486 | 173 | void stop() |
fruediger | 10:b305e261e7d1 | 174 | { |
fruediger | 9:6a28d9c0e486 | 175 | _isRunning = false; |
fruediger | 9:6a28d9c0e486 | 176 | } |
fruediger | 9:6a28d9c0e486 | 177 | |
fruediger | 9:6a28d9c0e486 | 178 | void handleService() |
fruediger | 9:6a28d9c0e486 | 179 | { |
fruediger | 10:b305e261e7d1 | 180 | if (_isRunning) |
fruediger | 10:b305e261e7d1 | 181 | { |
fruediger | 10:b305e261e7d1 | 182 | if (updateMeasuringRangeTrigger) |
fruediger | 10:b305e261e7d1 | 183 | updateMeasuringRange(); |
fruediger | 10:b305e261e7d1 | 184 | if (updateSensorDataCharacteristicTrigger) |
fruediger | 10:b305e261e7d1 | 185 | updateSensorDataCharacteristic(); |
fruediger | 10:b305e261e7d1 | 186 | if (updateMotionIndicatorCharacteristicTrigger) |
fruediger | 10:b305e261e7d1 | 187 | updateMotionIndicatorCharacteristic(); |
fruediger | 10:b305e261e7d1 | 188 | } |
fruediger | 3:d72d9195dc26 | 189 | } |
fruediger | 3:d72d9195dc26 | 190 | |
fruediger | 10:b305e261e7d1 | 191 | private: |
fruediger | 12:dc46aa2edccd | 192 | static const int MAX_SENSOR_POLLS_PER_UPDATE = 10; |
fruediger | 9:6a28d9c0e486 | 193 | |
fruediger | 3:d72d9195dc26 | 194 | GattServer &gattServer; |
fruediger | 9:6a28d9c0e486 | 195 | MPU6050 &mpu; |
fruediger | 12:dc46aa2edccd | 196 | InterruptIn *intIn; |
fruediger | 10:b305e261e7d1 | 197 | Timer timer; |
fruediger | 5:ea4d280a0a2f | 198 | |
fruediger | 9:6a28d9c0e486 | 199 | volatile bool _isRunning; |
fruediger | 9:6a28d9c0e486 | 200 | bool updateSensorDataCharacteristicTrigger; |
fruediger | 10:b305e261e7d1 | 201 | bool updateMotionIndicatorCharacteristicTrigger; |
fruediger | 10:b305e261e7d1 | 202 | bool updateMeasuringRangeTrigger; |
fruediger | 9:6a28d9c0e486 | 203 | |
fruediger | 10:b305e261e7d1 | 204 | uint32_t timerOffset_us; |
fruediger | 3:d72d9195dc26 | 205 | |
fruediger | 10:b305e261e7d1 | 206 | ReadOnlyGattCharacteristic<SensorData> sensorDataCharacteristic; |
fruediger | 10:b305e261e7d1 | 207 | ReadOnlyGattCharacteristic<MotionIndicator> motionIndicatorCharaceristic; |
fruediger | 10:b305e261e7d1 | 208 | WriteOnlyGattCharacteristic<MeasuringRange> measuringRangeCharacteristic; |
fruediger | 10:b305e261e7d1 | 209 | WriteOnlyGattCharacteristic<uint32_t> masterClockCharacteristic; |
fruediger | 3:d72d9195dc26 | 210 | |
fruediger | 3:d72d9195dc26 | 211 | void dataSentCallback(unsigned count) |
fruediger | 3:d72d9195dc26 | 212 | { |
fruediger | 3:d72d9195dc26 | 213 | // we came here, if we just sent data, |
fruediger | 3:d72d9195dc26 | 214 | // so lets keep the BLE stack busy by sending data again |
fruediger | 9:6a28d9c0e486 | 215 | updateSensorDataCharacteristicTrigger = true; |
fruediger | 3:d72d9195dc26 | 216 | } |
fruediger | 3:d72d9195dc26 | 217 | |
fruediger | 3:d72d9195dc26 | 218 | void dataWrittenCallback(const GattWriteCallbackParams *context) |
fruediger | 3:d72d9195dc26 | 219 | { |
fruediger | 10:b305e261e7d1 | 220 | // update master clock immediately |
fruediger | 10:b305e261e7d1 | 221 | if (context->handle == masterClockCharacteristic.getValueAttribute().getHandle()) |
fruediger | 10:b305e261e7d1 | 222 | { |
fruediger | 10:b305e261e7d1 | 223 | timer.stop(); |
fruediger | 10:b305e261e7d1 | 224 | timer.reset(); |
fruediger | 10:b305e261e7d1 | 225 | |
fruediger | 10:b305e261e7d1 | 226 | timerOffset_us = *((uint32_t*)context->data); |
fruediger | 10:b305e261e7d1 | 227 | |
fruediger | 10:b305e261e7d1 | 228 | timer.start(); |
fruediger | 10:b305e261e7d1 | 229 | } |
fruediger | 10:b305e261e7d1 | 230 | // delay measuring range update |
fruediger | 10:b305e261e7d1 | 231 | else if (context->handle == measuringRangeCharacteristic.getValueAttribute().getHandle()) |
fruediger | 10:b305e261e7d1 | 232 | { |
fruediger | 10:b305e261e7d1 | 233 | updateMeasuringRangeTrigger = true; |
fruediger | 10:b305e261e7d1 | 234 | } |
fruediger | 3:d72d9195dc26 | 235 | } |
fruediger | 3:d72d9195dc26 | 236 | |
fruediger | 10:b305e261e7d1 | 237 | void interruptRiseCallback() |
fruediger | 9:6a28d9c0e486 | 238 | { |
fruediger | 10:b305e261e7d1 | 239 | updateMotionIndicatorCharacteristicTrigger = true; |
fruediger | 9:6a28d9c0e486 | 240 | } |
fruediger | 9:6a28d9c0e486 | 241 | |
fruediger | 3:d72d9195dc26 | 242 | void updateSensorDataCharacteristic() |
fruediger | 10:b305e261e7d1 | 243 | { |
fruediger | 10:b305e261e7d1 | 244 | updateSensorDataCharacteristicTrigger = false; |
fruediger | 10:b305e261e7d1 | 245 | |
fruediger | 10:b305e261e7d1 | 246 | int n = 0; |
fruediger | 10:b305e261e7d1 | 247 | SensorData data; |
fruediger | 10:b305e261e7d1 | 248 | |
fruediger | 10:b305e261e7d1 | 249 | for (; n < MAX_SENSOR_POLLS_PER_UPDATE; n++) |
fruediger | 10:b305e261e7d1 | 250 | if (mpu.getMotionAndTemperature |
fruediger | 10:b305e261e7d1 | 251 | ( |
fruediger | 10:b305e261e7d1 | 252 | (int16_t*)&(data.accelX), (int16_t*)&(data.accelY), (int16_t*)&(data.accelZ), |
fruediger | 10:b305e261e7d1 | 253 | (int16_t*)&(data.temperature), |
fruediger | 10:b305e261e7d1 | 254 | (int16_t*)&(data.gyroX), (int16_t*)&(data.gyroY), (int16_t*)&(data.gyroZ), |
fruediger | 10:b305e261e7d1 | 255 | 0.0 |
fruediger | 10:b305e261e7d1 | 256 | )) |
fruediger | 10:b305e261e7d1 | 257 | { |
fruediger | 10:b305e261e7d1 | 258 | data.clock_us = timer.read_us() + timerOffset_us; |
fruediger | 10:b305e261e7d1 | 259 | |
fruediger | 10:b305e261e7d1 | 260 | if (gattServer.write(sensorDataCharacteristic.getValueHandle(), (uint8_t*)&data, sizeof(SensorData)) != BLE_ERROR_NONE) |
fruediger | 9:6a28d9c0e486 | 261 | break; |
fruediger | 10:b305e261e7d1 | 262 | } |
fruediger | 10:b305e261e7d1 | 263 | |
fruediger | 10:b305e261e7d1 | 264 | if (n == 0) |
fruediger | 10:b305e261e7d1 | 265 | updateSensorDataCharacteristicTrigger = true; |
fruediger | 10:b305e261e7d1 | 266 | } |
fruediger | 10:b305e261e7d1 | 267 | |
fruediger | 10:b305e261e7d1 | 268 | void updateMotionIndicatorCharacteristic() |
fruediger | 10:b305e261e7d1 | 269 | { |
fruediger | 10:b305e261e7d1 | 270 | updateMotionIndicatorCharacteristicTrigger = false; |
fruediger | 3:d72d9195dc26 | 271 | |
fruediger | 10:b305e261e7d1 | 272 | MPU6050::Interrupt intSet = static_cast<MPU6050::Interrupt>(0); |
fruediger | 10:b305e261e7d1 | 273 | MPU6050::Motion motSet = static_cast<MPU6050::Motion>(0); |
fruediger | 10:b305e261e7d1 | 274 | MotionIndicator mot; |
fruediger | 10:b305e261e7d1 | 275 | |
fruediger | 10:b305e261e7d1 | 276 | mpu.getInterruptStatuses(&intSet); |
fruediger | 10:b305e261e7d1 | 277 | mpu.getMotionStatus(&motSet); |
fruediger | 10:b305e261e7d1 | 278 | |
fruediger | 10:b305e261e7d1 | 279 | mot = *((MotionIndicator*)&motSet); |
fruediger | 10:b305e261e7d1 | 280 | |
fruediger | 10:b305e261e7d1 | 281 | if ((intSet & MPU6050::INT_FREEFALL) != 0) |
fruediger | 10:b305e261e7d1 | 282 | mot = mot | MOTION_IND_FREEFALL; |
fruediger | 10:b305e261e7d1 | 283 | else |
fruediger | 10:b305e261e7d1 | 284 | mot = mot & static_cast<MotionIndicator>(~0x02); |
fruediger | 10:b305e261e7d1 | 285 | |
fruediger | 10:b305e261e7d1 | 286 | gattServer.write(motionIndicatorCharaceristic.getValueHandle(), (uint8_t*)&mot, sizeof(MotionIndicator)); |
fruediger | 3:d72d9195dc26 | 287 | } |
fruediger | 9:6a28d9c0e486 | 288 | |
fruediger | 10:b305e261e7d1 | 289 | void updateMeasuringRange() |
fruediger | 10:b305e261e7d1 | 290 | { |
fruediger | 10:b305e261e7d1 | 291 | static const uint16_t sizeOfMeasuringRange = sizeof(MeasuringRange); |
fruediger | 10:b305e261e7d1 | 292 | |
fruediger | 10:b305e261e7d1 | 293 | updateMeasuringRangeTrigger = false; |
fruediger | 10:b305e261e7d1 | 294 | |
fruediger | 10:b305e261e7d1 | 295 | union |
fruediger | 10:b305e261e7d1 | 296 | { |
fruediger | 10:b305e261e7d1 | 297 | MeasuringRange range; |
fruediger | 10:b305e261e7d1 | 298 | uint8_t bytes[sizeOfMeasuringRange]; |
fruediger | 10:b305e261e7d1 | 299 | } conv; |
fruediger | 10:b305e261e7d1 | 300 | |
fruediger | 10:b305e261e7d1 | 301 | if (gattServer.read(measuringRangeCharacteristic.getValueHandle(), conv.bytes, (uint16_t*)&sizeOfMeasuringRange) == BLE_ERROR_NONE) |
fruediger | 10:b305e261e7d1 | 302 | { |
fruediger | 10:b305e261e7d1 | 303 | switch (conv.range & ACCEL_RANGE_MASK) |
fruediger | 10:b305e261e7d1 | 304 | { |
fruediger | 10:b305e261e7d1 | 305 | case ACCEL_RANGE_2G: |
fruediger | 10:b305e261e7d1 | 306 | mpu.setAccelRange(MPU6050::ACCEL_RANGE_2G); |
fruediger | 10:b305e261e7d1 | 307 | break; |
fruediger | 10:b305e261e7d1 | 308 | case ACCEL_RANGE_4G: |
fruediger | 10:b305e261e7d1 | 309 | mpu.setAccelRange(MPU6050::ACCEL_RANGE_4G); |
fruediger | 10:b305e261e7d1 | 310 | break; |
fruediger | 10:b305e261e7d1 | 311 | case ACCEL_RANGE_8G: |
fruediger | 10:b305e261e7d1 | 312 | mpu.setAccelRange(MPU6050::ACCEL_RANGE_8G); |
fruediger | 10:b305e261e7d1 | 313 | break; |
fruediger | 10:b305e261e7d1 | 314 | case ACCEL_RANGE_16G: |
fruediger | 10:b305e261e7d1 | 315 | mpu.setAccelRange(MPU6050::ACCEL_RANGE_16G); |
fruediger | 10:b305e261e7d1 | 316 | break; |
fruediger | 10:b305e261e7d1 | 317 | } |
fruediger | 10:b305e261e7d1 | 318 | |
fruediger | 10:b305e261e7d1 | 319 | switch (conv.range & GYRO_RANGE_MASK) |
fruediger | 10:b305e261e7d1 | 320 | { |
fruediger | 10:b305e261e7d1 | 321 | case GYRO_RANGE_250: |
fruediger | 10:b305e261e7d1 | 322 | mpu.setGyroRange(MPU6050::GYRO_RANGE_250); |
fruediger | 10:b305e261e7d1 | 323 | break; |
fruediger | 10:b305e261e7d1 | 324 | case GYRO_RANGE_500: |
fruediger | 10:b305e261e7d1 | 325 | mpu.setGyroRange(MPU6050::GYRO_RANGE_500); |
fruediger | 10:b305e261e7d1 | 326 | break; |
fruediger | 10:b305e261e7d1 | 327 | case GYRO_RANGE_1000: |
fruediger | 10:b305e261e7d1 | 328 | mpu.setGyroRange(MPU6050::GYRO_RANGE_1000); |
fruediger | 10:b305e261e7d1 | 329 | break; |
fruediger | 10:b305e261e7d1 | 330 | case GYRO_RANGE_2000: |
fruediger | 10:b305e261e7d1 | 331 | mpu.setGyroRange(MPU6050::GYRO_RANGE_2000); |
fruediger | 10:b305e261e7d1 | 332 | break; |
fruediger | 10:b305e261e7d1 | 333 | } |
fruediger | 10:b305e261e7d1 | 334 | } |
fruediger | 10:b305e261e7d1 | 335 | } |
fruediger | 10:b305e261e7d1 | 336 | |
fruediger | 10:b305e261e7d1 | 337 | inline bool deviceReset() |
fruediger | 9:6a28d9c0e486 | 338 | { |
fruediger | 9:6a28d9c0e486 | 339 | uint8_t id; |
fruediger | 9:6a28d9c0e486 | 340 | |
fruediger | 9:6a28d9c0e486 | 341 | return |
fruediger | 9:6a28d9c0e486 | 342 | mpu.getDeviceId(&id) && |
fruediger | 9:6a28d9c0e486 | 343 | (id == MPU6050::MPU6050_ID) && |
fruediger | 9:6a28d9c0e486 | 344 | mpu.reset() && |
fruediger | 10:b305e261e7d1 | 345 | mpu.setClockSource(MPU6050::CLOCK_SRC_INTERNAL_8MHZ) && |
fruediger | 10:b305e261e7d1 | 346 | mpu.setInterruptsEnabled(MPU6050::INT_FREEFALL | MPU6050::INT_MOTION | MPU6050::INT_ZERO_MOTION) && |
fruediger | 10:b305e261e7d1 | 347 | mpu.setSleepEnabled(false); |
fruediger | 9:6a28d9c0e486 | 348 | } |
fruediger | 3:d72d9195dc26 | 349 | }; |
fruediger | 3:d72d9195dc26 | 350 | |
fruediger | 3:d72d9195dc26 | 351 | #endif |