Test of 100 Hz

Dependencies:   mbed BLE_API nRF51822 eMPL_MPU6050

Files at this revision

API Documentation at this revision

Comitter:
avk01
Date:
Wed Sep 25 15:05:11 2019 +0000
Parent:
3:24e365bd1b97
Commit message:
100 Hz with BLE

Changed in this revision

BLE_API.lib Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
nRF51822.lib Show annotated file Show diff for this revision Revisions of this file
--- a/BLE_API.lib	Thu Nov 05 06:58:30 2015 +0000
+++ b/BLE_API.lib	Wed Sep 25 15:05:11 2019 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#a097e1be76f4
+http://mbed.org/teams/Bluetooth-Low-Energy/code/BLE_API/#65474dc93927
--- a/main.cpp	Thu Nov 05 06:58:30 2015 +0000
+++ b/main.cpp	Wed Sep 25 15:05:11 2019 +0000
@@ -7,11 +7,13 @@
 #include "nrf51_bitfields.h"
 
 #include "BLE.h"
-#include "DFUService.h"
 #include "UARTService.h"
 
-
-#define LOG(...)    { pc.printf(__VA_ARGS__); }
+//#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
@@ -28,25 +30,28 @@
 #define UART_RTS    p10
 
 /* Starting sampling rate. */
-#define DEFAULT_MPU_HZ  (100)
+#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);
-AnalogIn    battery(BATTERY_PIN);
+
+#ifdef SERIAL_DEBUG
 Serial pc(UART_TX, UART_RX);
+#endif
 
 InterruptIn motion_probe(p14);
 
 int read_none_count = 0;
-
-BLEDevice  ble;
-UARTService *uartServicePtr;
-
+static const char *devName = "SKQP-B01";
+UARTService *uartService = 0;
 volatile bool bleIsConnected = false;
-volatile uint8_t tick_event = 0;
+volatile bool updatesEnabled = false;
 volatile uint8_t motion_event = 0;
 static signed char board_orientation[9] = {
     1, 0, 0,
@@ -54,37 +59,121 @@
     0, 0, 1
 };
 
+void check_i2c_bus(void);
+unsigned short inv_orientation_matrix_to_scalar(const signed char *mtx);
 
-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)
 {
-    LOG("Connected!\n");
+#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)
 {
-    LOG("Disconnected!\n");
-    LOG("Restarting the advertising process\n");
-    ble.startAdvertising();
+#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)
 {
-    static uint32_t count = 0;
-    
-    LOG("%d\r\n", count++);
+    if( bleIsConnected ) {
+        LedSwitchOFF(green);
+        if( updatesEnabled ) {
+            LedSwitchOFF(red);
+            blue = !blue;
+            return;
+
+        }
+        LedSwitchOFF(blue);
+        red = !red;
+        return;
+    }
+    LedSwitchOFF(blue);
+    LedSwitchOFF(red);
     green = !green;
 }
 
-void detect(void)
+void ButtonReset(void)
 {
-    LOG("Button pressed\n");  
-    blue = !blue;
+    NVIC_SystemReset();
 }
 
 void motion_interrupt_handle(void)
@@ -92,160 +181,108 @@
     motion_event = 1;
 }
 
-void tap_cb(unsigned char direction, unsigned char count)
-{
-    LOG("Tap motion detected\n");
-}
-
-void android_orient_cb(unsigned char orientation)
-{
-    LOG("Oriention changed\n");
-}
-
-
 int main(void)
 {
     blue  = 1;
     green = 1;
     red   = 1;
-
+#ifdef SERIAL_DEBUG
     pc.baud(115200);
-    
     wait(1);
-    
-    LOG("---- Seeed Tiny BLE ----\n");
-    
+    LOG("---- Seeed Tiny BLE ----");
+#endif
     mbed_i2c_clear(MPU6050_SDA, MPU6050_SCL);
     mbed_i2c_init(MPU6050_SDA, MPU6050_SCL);
-    
-
     if (mpu_init(0)) {
-        LOG("failed to initialize mpu6050\r\n");
+#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(DEFAULT_MPU_HZ);
-    
+    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 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);
-    
+    mpu_get_accel_fsr(&accel_fsr); */
     dmp_load_motion_driver_firmware();
-    dmp_set_orientation(
-        inv_orientation_matrix_to_scalar(board_orientation));
-    dmp_register_tap_cb(tap_cb);
-    dmp_register_android_orient_cb(android_orient_cb);
-    
-    uint16_t dmp_features = DMP_FEATURE_6X_LP_QUAT | DMP_FEATURE_TAP |
-                       DMP_FEATURE_ANDROID_ORIENT | DMP_FEATURE_SEND_RAW_ACCEL | DMP_FEATURE_SEND_CAL_GYRO |
-                       DMP_FEATURE_GYRO_CAL;
-    dmp_enable_feature(dmp_features);
+    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_GESTURE);
-    dmp_set_tap_thresh(TAP_XYZ, 50);
-    
-    
+    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, 3);
-
-    button.fall(detect);
-
-    LOG("Initialising the nRF51822\n");
-    ble.init();
-    ble.gap().onDisconnection(disconnectionCallback);
-    ble.gap().onConnection(connectionCallback);
-
-
-    /* setup advertising */
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
-    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
-                                     (const uint8_t *)"smurfs", sizeof("smurfs"));
-    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
-                                     (const uint8_t *)UARTServiceUUID_reversed, sizeof(UARTServiceUUID_reversed));
-    DFUService dfu(ble);                                 
-    UARTService uartService(ble);
-    uartServicePtr = &uartService;
-    //uartService.retargetStdout();
-
-    ble.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */
-    ble.gap().startAdvertising();
-    
+    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) {
-        if (motion_event) {
-            
-            unsigned long sensor_timestamp;
-            short gyro[3], accel[3], sensors;
-            long quat[4];
-            unsigned char more = 1;
-            
-            while (more) {
-                /* This function gets new data from the FIFO when the DMP is in
-                 * use. The FIFO can contain any combination of gyro, accel,
-                 * quaternion, and gesture data. The sensors parameter tells the
-                 * caller which data fields were actually populated with new data.
-                 * For example, if sensors == (INV_XYZ_GYRO | INV_WXYZ_QUAT), then
-                 * the FIFO isn't being filled with accel data.
-                 * The driver parses the gesture data to determine if a gesture
-                 * event has occurred; on an event, the application will be notified
-                 * via a callback (assuming that a callback function was properly
-                 * registered). The more parameter is non-zero if there are
-                 * leftover packets in the FIFO.
-                 */
-                dmp_read_fifo(gyro, accel, quat, &sensor_timestamp, &sensors,
-                              &more);
-                
-                
-                /* Gyro and accel data are written to the FIFO by the DMP in chip
-                 * frame and hardware units. This behavior is convenient because it
-                 * keeps the gyro and accel outputs of dmp_read_fifo and
-                 * mpu_read_fifo consistent.
-                 */
-                if (sensors & INV_XYZ_GYRO) {
-                    // LOG("GYRO: %d, %d, %d\n", gyro[0], gyro[1], gyro[2]);
-                }
-                if (sensors & INV_XYZ_ACCEL) {
-                    //LOG("ACC: %d, %d, %d\n", accel[0], accel[1], accel[2]);
-                }
-                
-                /* Unlike gyro and accel, quaternions are written to the FIFO in
-                 * the body frame, q30. The orientation is set by the scalar passed
-                 * to dmp_set_orientation during initialization.
-                 */
-                if (sensors & INV_WXYZ_QUAT) {
-                    // LOG("QUAT: %ld, %ld, %ld, %ld\n", quat[0], quat[1], quat[2], quat[3]);
-                }
-                
-                if (sensors) {
-                    read_none_count = 0;
-                } else {
-                    read_none_count++;
-                    if (read_none_count > 3) {
-                        read_none_count = 0;
-                        
-                        LOG("I2C may be stuck @ %d\r\n", sensor_timestamp);
-                        mbed_i2c_clear(MPU6050_SDA, MPU6050_SCL);
-                    }
+        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
                 }
             }
-            
-            motion_event = 0;
-        } else {
-            ble.waitForEvent();
+            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;
     }
 }
 
@@ -277,8 +314,6 @@
 unsigned short inv_orientation_matrix_to_scalar(
     const signed char *mtx)
 {
-    unsigned short scalar;
-
     /*
        XYZ  010_001_000 Identity Matrix
        XZY  001_010_000
@@ -287,12 +322,9 @@
        ZXY  001_000_010
        ZYX  000_001_010
      */
-
-    scalar = inv_row_2_scale(mtx);
+    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;
 }
 
--- a/mbed.bld	Thu Nov 05 06:58:30 2015 +0000
+++ b/mbed.bld	Wed Sep 25 15:05:11 2019 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/users/mbed_official/code/mbed/builds/9296ab0bfc11
\ No newline at end of file
+https://os.mbed.com/users/mbed_official/code/mbed/builds/65be27845400
\ No newline at end of file
--- a/nRF51822.lib	Thu Nov 05 06:58:30 2015 +0000
+++ b/nRF51822.lib	Wed Sep 25 15:05:11 2019 +0000
@@ -1,1 +1,1 @@
-http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#bf85bf7e73d5
+http://mbed.org/teams/Nordic-Semiconductor/code/nRF51822/#c90ae1400bf2