
BLE GATT-service implementation for high quantity sensor data from a MPU6050-accelerator/gyroscope
Dependencies: BLE_API mbed nRF51822 MPU6050_lib
MPU6050Service.h
- Committer:
- fruediger
- Date:
- 2015-07-13
- Revision:
- 7:af3e2b9c137a
- Parent:
- 6:c1db7e82d76a
- Child:
- 9:6a28d9c0e486
File content as of revision 7:af3e2b9c137a:
#pragma once #ifndef __MPU6050_SERVICE_H__ #define __MPU6050_SERVICE_H__ #include "BLE.h" typedef struct { uint16_t a1, a2, a3; uint16_t temp; uint16_t g1, g2, g3; } mpu6050SensorReading_t; typedef struct { mpu6050SensorReading_t data; uint32_t clock_us; // ~ 1h 11min 34s 967ms 296us // (so we have to resynchronize our clock approx. every hour) } mpu6050SensorData_t; typedef enum { ACCEL_RANGE_2G = 0x00, // 0b__00 ACCEL_RANGE_4G = 0x01, // 0b__01 ACCEL_RANGE_8G = 0x02, // 0b__10 ACCEL_RANGE_16G = 0x03, // 0b__11 GYRO_RANGE_250 = 0x00, // 0b00__ GYRO_RANGE_500 = 0x04, // 0b01__ GYRO_RANGE_1000 = 0x08, // 0b10__ GYRO_RANGE_2000 = 0x0C // 0b11__ } mpu6050MeasuringRange_t; inline mpu6050MeasuringRange_t operator|(mpu6050MeasuringRange_t a, mpu6050MeasuringRange_t b) { return static_cast<mpu6050MeasuringRange_t>(static_cast<int>(a) | static_cast<int>(b)); } class MPU6050Service { public: enum { UUID_MP6050_SERVICE = 0xA123, UUID_MPU6050_SENSOR_DATA_CHAR = 0xA124, UUID_MPU6050_MEASURING_RANGE_CHAR = 0xA125, UUID_MPU6050_MASTER_CLOCK_CHAR = 0xA126 }; MPU6050Service ( BLE &ble, const mpu6050SensorData_t *initialData = NULL, const mpu6050MeasuringRange_t measuringRange = ACCEL_RANGE_2G | GYRO_RANGE_250, const uint32_t masterClock_us = 0 ) : gattServer(ble.gattServer()), sensorDataCharacteristic ( UUID_MPU6050_SENSOR_DATA_CHAR, (mpu6050SensorData_t*)initialData, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY // improving latency by repurposing notifications and "writing" the client // (i.e. indicating the client but not wait for a response) ), measuringRangeCharacteristic ( UUID_MPU6050_MEASURING_RANGE_CHAR, (mpu6050MeasuringRange_t*)&measuringRange, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE // also improving latency ), masterClockCharacteristic ( UUID_MPU6050_MASTER_CLOCK_CHAR, (uint32_t*)&masterClock_us, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE // look above again ) { static bool serviceAdded = false; if (serviceAdded) return; GattCharacteristic *charTable[] = { &sensorDataCharacteristic, &measuringRangeCharacteristic, &masterClockCharacteristic }; GattService mpu6050Service(UUID_MP6050_SERVICE, charTable, sizeof(charTable) / sizeof(GattCharacteristic*)); gattServer.addService(mpu6050Service); gattServer.onDataSent(this, &MPU6050Service::dataSentCallback); gattServer.onDataWritten(this, &MPU6050Service::dataWrittenCallback); serviceAdded = true; } void start() { // sending data once will invoke the dataSent(...) callback later on // which will be looped by the event driven behavior of the BLE API (because it will send data again on it's own) updateSensorDataCharacteristic(); } private: GattServer &gattServer; ReadOnlyGattCharacteristic<mpu6050SensorData_t> sensorDataCharacteristic; WriteOnlyGattCharacteristic<mpu6050MeasuringRange_t> measuringRangeCharacteristic; WriteOnlyGattCharacteristic<uint32_t> masterClockCharacteristic; union { struct { uint8_t accel_x_h, accel_x_l; uint8_t accel_y_h, accel_y_l; uint8_t accel_z_h, accel_z_l; uint8_t temp_h, temp_l; uint8_t gyro_x_h, gyro_x_l; uint8_t gyro_y_h, gyro_y_l; uint8_t gyro_z_h, gyro_z_l; } registers; mpu6050SensorReading_t data; } converter; void dataSentCallback(unsigned count) { // we came here, if we just sent data, // so lets keep the BLE stack busy by sending data again updateSensorDataCharacteristic(); } void dataWrittenCallback(const GattWriteCallbackParams *context) { // some writable characteristics were updated by the client } void updateSensorDataCharacteristic() { mpu6050SensorData_t data; // flood the transmission buffer of the BLE stack until it's full do { // TODO: poll and accumulate data // ... data.data = converter.data; data.clock_us = 0; // write data in characteristic and repeat } while (gattServer.write(sensorDataCharacteristic.getValueHandle(), reinterpret_cast<uint8_t*>(&data), sizeof(mpu6050SensorData_t)) == BLE_ERROR_NONE); // error case or buffer is full (or break out of loop); // this also means the last data update will be lost, if not sent again // (we are ignoring this fact and just keep on going, because we're NOT interested in the QUALITY of data, but in the QUANTITY } }; #endif