A template for applications where some small amount of data needs to be notified to a phone app over BLE. It is a good starting point for notifications.

Dependencies:   BLE_API mbed nRF51822

Fork of BLE_Button by Bluetooth Low Energy

Revision:
10:7943b5c1117a
Parent:
9:0f6951db24f1
Child:
11:fd1cf9dbf3a4
--- a/main.cpp	Fri Oct 09 13:37:52 2015 +0000
+++ b/main.cpp	Wed Dec 30 09:54:06 2015 +0000
@@ -15,10 +15,9 @@
  */
 
 #include "mbed.h"
-#include "BLE.h"
+#include "ble/BLE.h"
 #include "ButtonService.h"
 
-BLE         ble;
 DigitalOut  led1(LED1);
 InterruptIn button(BUTTON1);
 
@@ -32,7 +31,7 @@
 };
 static uint8_t buttonState = IDLE;
 
-ButtonService *buttonServicePtr;
+static ButtonService *buttonServicePtr;
 
 void buttonPressedCallback(void)
 {
@@ -50,7 +49,7 @@
 
 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
 {
-    ble.gap().startAdvertising();
+    BLE::Instance().gap().startAdvertising();
 }
 
 void periodicCallback(void)
@@ -58,6 +57,48 @@
     led1 = !led1; /* Do blinky on LED1 to indicate system aliveness. */
 }
 
+/**
+ * This function is called when the ble initialization process has failled
+ */
+void onBleInitError(BLE &ble, ble_error_t error)
+{
+    /* Initialization error handling should go here */
+}
+
+/**
+ * Callback triggered when the ble initialization process has finished
+ */
+void bleInitComplete(BLE::InitializationCompleteCallbackContext *params)
+{
+    BLE&        ble   = params->ble;
+    ble_error_t error = params->error;
+
+    if (error != BLE_ERROR_NONE) {
+        /* In case of error, forward the error handling to onBleInitError */
+        onBleInitError(ble, error);
+        return;
+    }
+
+    /* Ensure that it is the default instance of BLE */
+    if(ble.getInstanceID() != BLE::DEFAULT_INSTANCE) {
+        return;
+    }
+
+    ble.gap().onDisconnection(disconnectionCallback);
+
+    /* Setup primary service */
+    buttonServicePtr = new ButtonService(ble, false /* initial value for button pressed */);
+
+    /* setup advertising */
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
+    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
+    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
+    ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
+    ble.gap().startAdvertising();
+
+}
+
 int main(void)
 {
     led1 = 1;
@@ -66,22 +107,15 @@
     button.fall(buttonPressedCallback);
     button.rise(buttonReleasedCallback);
 
-    ble.init();
-    ble.gap().onDisconnection(disconnectionCallback);
-
-    ButtonService buttonService(ble, false /* initial value for button pressed */);
-    buttonServicePtr = &buttonService;
-
-    /* setup advertising */
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
-    ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME));
-    ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
-    ble.gap().setAdvertisingInterval(1000); /* 1000ms. */
-    ble.gap().startAdvertising();
-
+    BLE &ble = BLE::Instance();
+    ble.init(bleInitComplete);
+    
+    /* SpinWait for initialization to complete. This is necessary because the
+     * BLE object is used in the main loop below. */
+    while (ble.hasInitialized()  == false) { /* spin loop */ }
+    
     while (true) {
-        if (buttonState!=IDLE) {
+        if (buttonState != IDLE) {
             buttonServicePtr->updateButtonState(buttonState);
             buttonState = IDLE;
         }