Test of 100 Hz
Dependencies: mbed BLE_API nRF51822 eMPL_MPU6050
main.cpp
- Committer:
- avk01
- Date:
- 2019-09-25
- Revision:
- 4:dedfd6797c10
- Parent:
- 3:24e365bd1b97
File content as of revision 4:dedfd6797c10:
#include "mbed.h" #include "mbed_i2c.h" #include "inv_mpu.h" #include "inv_mpu_dmp_motion_driver.h" #include "nrf51.h" #include "nrf51_bitfields.h" #include "BLE.h" #include "UARTService.h" //#define CALIBRATE #define SERIAL_DEBUG #ifdef SERIAL_DEBUG #define LOG(...) { pc.printf(__VA_ARGS__); pc.printf("\r\n"); } #endif #define LED_GREEN p21 #define LED_RED p22 #define LED_BLUE p23 #define BUTTON_PIN p17 #define BATTERY_PIN p1 #define MPU6050_SDA p12 #define MPU6050_SCL p13 #define UART_TX p9 #define UART_RX p11 #define UART_CTS p8 #define UART_RTS p10 /* Starting sampling rate. */ #define DEFAULT_MPU_HZ (100) #define DEFAULT_GYRO_FST (2000) // 250, 500, 1000, 2000 #define DEFAULT_ACCEL_FST (8) // 2, 4, 8, 16 DigitalOut blue(LED_BLUE); DigitalOut green(LED_GREEN); DigitalOut red(LED_RED); InterruptIn button(BUTTON_PIN); #ifdef SERIAL_DEBUG Serial pc(UART_TX, UART_RX); #endif InterruptIn motion_probe(p14); int read_none_count = 0; static const char *devName = "SKQP-B01"; UARTService *uartService = 0; volatile bool bleIsConnected = false; volatile bool updatesEnabled = false; volatile uint8_t motion_event = 0; static signed char board_orientation[9] = { 1, 0, 0, 0, 1, 0, 0, 0, 1 }; void check_i2c_bus(void); unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx); void LedSwitchON(DigitalOut & led) { if( led != 0 ) led = 0; } void LedSwitchOFF(DigitalOut & led) { if( led != 1 ) led = 1; } void connectionCallback(const Gap::ConnectionCallbackParams_t *params) { #ifdef SERIAL_DEBUG LOG("Connected!"); #endif BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); Gap::ConnectionParams_t connectionParams; ble.gap().getPreferredConnectionParams(&connectionParams); connectionParams.minConnectionInterval = 6; connectionParams.maxConnectionInterval = 10; if (ble.gap().updateConnectionParams(params->handle, &connectionParams) == BLE_ERROR_NONE) { #ifdef SERIAL_DEBUG LOG("ConnectionParams Update Accepted!"); #endif } bleIsConnected = true; blue = 0; } void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *cbParams) { #ifdef SERIAL_DEBUG LOG("Disconnected: %d!",cbParams->reason); LOG("Restarting the advertising process"); #endif BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); ble.gap().startAdvertising(); bleIsConnected = false; updatesEnabled = false; blue = 1; } void onUpdatesEnabledCallback(GattAttribute::Handle_t handle) { if ((uartService != NULL) && (handle == uartService->getRXCharacteristicHandle())) { updatesEnabled = true; // LOG("onUpdatesEnabledCallback"); } } void onUpdatesDisabledCallback(GattAttribute::Handle_t handle) { if ((uartService != NULL) && (handle == uartService->getRXCharacteristicHandle())) { updatesEnabled = false; // LOG("onUpdatesDisabledCallback"); } } void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) { BLE &ble = params->ble; ble_error_t error = params->error; if (error != BLE_ERROR_NONE) { return; } uint8_t pass[6] = {'1', '2', '3', '4', '5', '6'}; ble.securityManager().init(true,true,SecurityManager::IO_CAPS_DISPLAY_ONLY,pass); ble.gap().onDisconnection(disconnectionCallback); ble.gap().onConnection(connectionCallback); ble.gattServer().onUpdatesEnabled(onUpdatesEnabledCallback); ble.gattServer().onUpdatesDisabled(onUpdatesDisabledCallback); // uartService = new UARTService(ble); /* setup advertising */ ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); ble.gap().setDeviceName((const uint8_t*)devName); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,(const uint8_t *)devName, sizeof(devName)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME,(const uint8_t *)devName, sizeof(devName)); ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,(const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed)); ble.gap().setAdvertisingInterval(8); /* 5ms; in multiples of 0.625ms. */ ble.gap().startAdvertising(); #ifdef SERIAL_DEBUG // LOG("bleInitComplete %s!",ble.getVersion()); #endif } void tick(void) { if( bleIsConnected ) { LedSwitchOFF(green); if( updatesEnabled ) { LedSwitchOFF(red); blue = !blue; return; } LedSwitchOFF(blue); red = !red; return; } LedSwitchOFF(blue); LedSwitchOFF(red); green = !green; } void ButtonReset(void) { NVIC_SystemReset(); } void motion_interrupt_handle(void) { motion_event = 1; } int main(void) { blue = 1; green = 1; red = 1; #ifdef SERIAL_DEBUG pc.baud(115200); wait(1); LOG("---- Seeed Tiny BLE ----"); #endif mbed_i2c_clear(MPU6050_SDA, MPU6050_SCL); mbed_i2c_init(MPU6050_SDA, MPU6050_SCL); if (mpu_init(0)) { #ifdef SERIAL_DEBUG LOG("failed to initialize mpu6050"); #endif } /* Get/set hardware configuration. Start gyro. */ /* Wake up all sensors. */ mpu_set_sensors(INV_XYZ_GYRO | INV_XYZ_ACCEL); /* Push both gyro and accel data into the FIFO. */ mpu_configure_fifo(INV_XYZ_GYRO | INV_XYZ_ACCEL); mpu_set_sample_rate(4*DEFAULT_MPU_HZ); mpu_set_gyro_fsr(DEFAULT_GYRO_FST); mpu_set_accel_fsr(DEFAULT_ACCEL_FST); /* Read back configuration in case it was set improperly. */ /* unsigned char accel_fsr; unsigned short gyro_rate, gyro_fsr; mpu_get_sample_rate(&gyro_rate); mpu_get_gyro_fsr(&gyro_fsr); mpu_get_accel_fsr(&accel_fsr); */ dmp_load_motion_driver_firmware(); dmp_set_orientation(inv_orientation_matrix_to_scalar(board_orientation)); dmp_enable_feature(DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO | DMP_FEATURE_GYRO_CAL | DMP_FEATURE_LP_QUAT); dmp_set_fifo_rate(DEFAULT_MPU_HZ); mpu_set_dmp_state(1); dmp_set_interrupt_mode(DMP_INT_CONTINUOUS); motion_probe.fall(motion_interrupt_handle); button.fall(ButtonReset); // unsigned long sensor_timestamp = 0; short gyro[3], accel[3], sensors; long quat[4]; #ifdef CALIBRATE LedSwitchON(red); while (sensor_timestamp < 20000) { unsigned char more = 1; dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more); } LedSwitchOFF(red); #endif Ticker ticker; ticker.attach(tick, 1); // #ifdef SERIAL_DEBUG LOG("Initialising the nRF51822"); #endif BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); ble.init(bleInitComplete); while(ble.hasInitialized() == false); // wait for init // unsigned char dataBuffer[20]; memset(dataBuffer,0,sizeof(dataBuffer)); dataBuffer[16] = 'E'; dataBuffer[17] = 'N'; dataBuffer[18] = 'D'; dataBuffer[19] = 0; while (true) { ble.waitForEvent(); if ( !motion_event || !updatesEnabled ) continue; unsigned char more = 1; while (more) { ble.waitForEvent(); if( dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,&more) == 0 ) { if ((sensors & INV_XYZ_GYRO) && (sensors & INV_XYZ_ACCEL)) { memcpy(dataBuffer,&sensor_timestamp,4); memcpy(dataBuffer+4,accel,6); memcpy(dataBuffer+10,gyro,6); uartService->write(dataBuffer,20); #ifdef SERIAL_DEBUG // LOG("%d: %d, %d, %d, %d, %d, %d", sensor_timestamp, accel[0], accel[1], accel[2], gyro[0], gyro[1], gyro[2]); #endif } } if (sensors) { read_none_count = 0; continue; } read_none_count++; if (read_none_count > 2) { read_none_count = 0; #ifdef SERIAL_DEBUG LOG("I2C may be stuck @ %d", sensor_timestamp); #endif ble.waitForEvent(); mbed_i2c_clear(MPU6050_SDA, MPU6050_SCL); ble.waitForEvent(); break; } } motion_event = 0; } } /* These next two functions converts the orientation matrix (see * gyro_orientation) to a scalar representation for use by the DMP. * NOTE: These functions are borrowed from Invensense's MPL. */ static inline unsigned short inv_row_2_scale(const signed char *row) { unsigned short b; if (row[0] > 0) b = 0; else if (row[0] < 0) b = 4; else if (row[1] > 0) b = 1; else if (row[1] < 0) b = 5; else if (row[2] > 0) b = 2; else if (row[2] < 0) b = 6; else b = 7; // error return b; } unsigned short inv_orientation_matrix_to_scalar( const signed char *mtx) { /* XYZ 010_001_000 Identity Matrix XZY 001_010_000 YXZ 010_000_001 YZX 000_010_001 ZXY 001_000_010 ZYX 000_001_010 */ unsigned short scalar = inv_row_2_scale(mtx); scalar |= inv_row_2_scale(mtx + 3) << 3; scalar |= inv_row_2_scale(mtx + 6) << 6; return scalar; }