MPU6050センサ Wallbot_BLE用 サンプル
Dependencies: BLE_API mbed nRF51822
Diff: main.cpp
- Revision:
- 0:2fa085b36ad8
- Child:
- 2:bbf9db7db756
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Mon Jan 05 09:58:42 2015 +0000 @@ -0,0 +1,250 @@ +#include "mbed.h" +#include "BLEDevice.h" +#include "MPU6050.h" + +/* +#define DBG 1 +#define NEED_CONSOLE_OUTPUT 1 // Set this if you need debug messages on the console; + // it will have an impact on code-size and power consumption. + +#if NEED_CONSOLE_OUTPUT +Serial pc(USBTX, USBRX); +#define DEBUG(...) { pc.printf(__VA_ARGS__); } +#else +#define DEBUG(...) // nothing // +#endif // #if NEED_CONSOLE_OUTPUT // +*/ + +BLEDevice ble; + +MPU6050 mpu(I2C_SDA0, I2C_SCL0); + +static const char DEVICENAME[] = "BLE-Nano"; +static volatile bool triggerSensorPolling = false; + +//9FDF3283-9049-CF8D-5C4D-98E7E2002731 +const uint8_t MPU6050_adv_service_uuid[] = { + 0x9F,0xDF,0x32,0x83, + 0x90,0x49, + 0xCF,0x8D, + 0x5C,0x4D, + 0x98,0xE7,0xE2,0x00,0x27,0x31 +}; + +const uint8_t MPU6050_service_uuid[] = { + 0x31,0x27,0x00,0xE2,0xE7,0x98,0x4D,0x5C,0x8D,0xCF,0x49,0x90,0x83,0x32,0xDF,0x9F +}; + +const uint8_t MPU6050_Accel_Characteristic_uuid[] = { + 0xFF,0xA2,0x8C,0xDE,0x65,0x25, + 0x44,0x89, + 0x80,0x1C, + 0x1C,0x06,0x0C,0xAC,0x97,0x67 +}; + +const uint8_t MPU6050_Gyro_Characteristic_uuid[] = { + 0x65, 0x60, 0xBE, 0x95,0xD9, 0x31, + 0x4F, 0x64, + 0x95, 0x75, + 0xC6, 0xDD, 0xB5, 0xAE, 0x7F, 0xA5 +}; + +uint8_t accelPayload[sizeof(float)*3] = {0,0,0}; +uint8_t gyroPayload[sizeof(float)*3] = {0,0,0}; +uint8_t tempPayload[sizeof(float)*1] = {0}; +uint8_t batt = 100; /* Battery level */ +uint8_t read_batt = 0; /* Variable to hold battery level reads */ + +GattCharacteristic accelChar (MPU6050_Accel_Characteristic_uuid, + accelPayload, (sizeof(float) * 3), (sizeof(float) * 3), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); + +GattCharacteristic gyroChar (MPU6050_Gyro_Characteristic_uuid, + gyroPayload, (sizeof(float) * 3), (sizeof(float) * 3), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); + +GattCharacteristic *ControllerChars[] = { &accelChar, &gyroChar, }; +GattService MPU6050Service(MPU6050_service_uuid, ControllerChars, sizeof(ControllerChars) / sizeof(GattCharacteristic *)); + + +GattCharacteristic tempChar (GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, + tempPayload, (sizeof(float) * 1), (sizeof(float) * 1), + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); + +GattCharacteristic *htmChars[] = { &tempChar, }; +GattService htmService(GattService::UUID_HEALTH_THERMOMETER_SERVICE, htmChars, + sizeof(htmChars) / sizeof(GattCharacteristic *)); + +/* Battery Level Service */ + +GattCharacteristic battLevel ( GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, + (uint8_t *)batt, 1, 1, + GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); + +GattCharacteristic *battChars[] = {&battLevel, }; +GattService battService(GattService::UUID_BATTERY_SERVICE, battChars, + sizeof(battChars) / sizeof(GattCharacteristic *)); + +uint16_t uuid16_list[] = {GattService::UUID_HEALTH_THERMOMETER_SERVICE, + GattService::UUID_BATTERY_SERVICE}; + + +void updateValue(); + +void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason) // Mod +{ + + //DEBUG("Disconnected handle %u, reason %u\n", handle, reason); + //DEBUG("Restarting the advertising process\n\r"); + + ble.startAdvertising(); +} + +void onConnectionCallback(Gap::Handle_t handle, Gap::addr_type_t peerAddrType, const Gap::address_t peerAddr, const Gap::ConnectionParams_t *params) //Mod +{ + + //DEBUG("connected. Got handle %u\r\n", handle); + + /*******************************************************************************/ + /* CentralがMacOS X の時 connection intervalを設定する場合は */ + /* nRF51822 -> projectconfig.h -> GAP -> */ + /* CFG_GAP_CONNECTION_MIN_INTERVAL_MS / CFG_GAP_CONNECTION_MAX_INTERVAL_MSを */ + /* 直接編集すること */ + /******************************************************************************/ + + #define MIN_CONN_INTERVAL 1000 /**< Minimum connection interval (250 ms) */ + #define MAX_CONN_INTERVAL 1000 /**< Maximum connection interval (350 ms). */ + #define CONN_SUP_TIMEOUT 6000 /**< Connection supervisory timeout (6 seconds). */ + #define SLAVE_LATENCY 4 + + Gap::ConnectionParams_t gap_conn_params; + gap_conn_params.minConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(MIN_CONN_INTERVAL); + gap_conn_params.maxConnectionInterval = Gap::MSEC_TO_GAP_DURATION_UNITS(MAX_CONN_INTERVAL); + gap_conn_params.connectionSupervisionTimeout = Gap::MSEC_TO_GAP_DURATION_UNITS(CONN_SUP_TIMEOUT); + gap_conn_params.slaveLatency = SLAVE_LATENCY; + ble.updateConnectionParams(handle, &gap_conn_params); + //if (ble.updateConnectionParams(handle, &gap_conn_params) != BLE_ERROR_NONE) { + // DEBUG("failed to update connection paramter\r\n"); + //} + + updateValue(); +} + +void timeoutCallback(void) +{ + //DEBUG("TimeOut\n\r"); + //DEBUG("Restarting the advertising process\n\r"); + + ble.startAdvertising(); +} + +void periodicCallback(void) +{ + //oneSecondLed = !oneSecondLed; /* Do blinky on LED1 while we're waiting for BLE events */ + + /* Note that the periodicCallback() executes in interrupt context, so it is safer to do + * heavy-weight sensor polling from the main thread. */ + triggerSensorPolling = true; +} + +/**************************************************************************/ +/*! + @brief Program entry point +*/ +/**************************************************************************/ +int main(void) +{ + + //#if DBG + // pc.printf("Start\n\r"); + //#endif + + if( mpu.testConnection() ){ + //pc.printf("mpu test:OK\n\r"); + }else{ + //pc.printf("mpu test:NG\n\r"); + } + + Ticker ticker; + ticker.attach(periodicCallback, 1); //1sec + + ble.init(); + ble.onDisconnection(disconnectionCallback); + ble.onConnection(onConnectionCallback); + ble.onTimeout(timeoutCallback); + + /* setup device name */ + ble.setDeviceName((const uint8_t *)DEVICENAME); + + /* setup advertising */ + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); + ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (const uint8_t *)DEVICENAME, sizeof(DEVICENAME)); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS, + (const uint8_t *)MPU6050_adv_service_uuid, sizeof(MPU6050_adv_service_uuid)); + + ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ + ble.startAdvertising(); + + ble.addService(MPU6050Service); + ble.addService(htmService); + ble.addService(battService); + + while(true) { + if (triggerSensorPolling && ble.getGapState().connected) { + triggerSensorPolling = false; + updateValue(); + } else { + ble.waitForEvent(); + } + } +} + +void updateValue(void){ + + float acData[3]; + float gyData[3]; + float tempData = 0.0; + + //加速度を取得。なんか、関数が逆みたいなので、getGyroが加速度だそうです。 + //mpu.getAccelero(acData); + mpu.getGyro(acData); + + memcpy(accelPayload+sizeof(float)*0, &acData[0], sizeof(acData[0])); + memcpy(accelPayload+sizeof(float)*1, &acData[1], sizeof(acData[1])); + memcpy(accelPayload+sizeof(float)*2, &acData[2], sizeof(acData[2])); + + //ジャイロを取得。なんか、関数が逆みたいなので、getAcceleroがジャイロだそうです。 + //mpu.getGyro(gyData); + mpu.getAccelero(gyData); + + memcpy(gyroPayload+sizeof(float)*0, &gyData[0], sizeof(gyData[0])); + memcpy(gyroPayload+sizeof(float)*1, &gyData[1], sizeof(gyData[1])); + memcpy(gyroPayload+sizeof(float)*2, &gyData[2], sizeof(gyData[2])); + + //温度を取得 + tempData = mpu.getTemp(); + + memcpy(tempPayload+sizeof(float)*0, &tempData, sizeof(tempData)); + /* + pc.printf("Accel: %.3lf,%.3lf,%.3lf\r\n", + *(float*)&accelPayload[sizeof(float)*0], + *(float*)&accelPayload[sizeof(float)*1], + *(float*)&accelPayload[sizeof(float)*2]); + + pc.printf("Gyro: %.3lf,%.3lf,%.3lf\r\n", + *(float*)&gyroPayload[sizeof(float)*0], + *(float*)&gyroPayload[sizeof(float)*1], + *(float*)&gyroPayload[sizeof(float)*2]); + + pc.printf("Temp: %.3lf\r\n", *(float*)&tempPayload[sizeof(float)*0]); + pc.printf("Battery: %d\r\n", batt); + */ + + ble.updateCharacteristicValue(accelChar.getValueAttribute().getHandle(), accelPayload, sizeof(accelPayload)); //Mod + ble.updateCharacteristicValue(gyroChar.getValueAttribute().getHandle(), gyroPayload, sizeof(gyroPayload)); //Mod + ble.updateCharacteristicValue(tempChar.getValueAttribute().getHandle(), tempPayload, sizeof(tempPayload)); //Mod + ble.updateCharacteristicValue(battLevel.getValueAttribute().getHandle(), &batt, sizeof(batt)); //Mod +}