Simple BLE device with LED and Button service, running on IDB04A1 shield.

Dependencies:   BLE_API X_NUCLEO_IDB0XA1 mbed

Fork of BLE_LED_Button by Jan Jongboom

Files at this revision

API Documentation at this revision

Comitter:
janjongboom
Date:
Fri Apr 29 11:44:02 2016 +0000
Parent:
10:af76616e4d75
Child:
12:7eebfdfdd892
Commit message:
BLE Workshop, LED and Button service

Changed in this revision

ButtonService.h 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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ButtonService.h	Fri Apr 29 11:44:02 2016 +0000
@@ -0,0 +1,43 @@
+/* mbed Microcontroller Library
+ * Copyright (c) 2006-2013 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+ 
+#ifndef __BLE_BUTTON_SERVICE_H__
+#define __BLE_BUTTON_SERVICE_H__
+ 
+class ButtonService {
+public:
+    const static uint16_t BUTTON_SERVICE_UUID              = 0xA010;
+    const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA011;
+ 
+    ButtonService(BLE &_ble, bool buttonPressedInitial) :
+        ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
+    {
+        GattCharacteristic *charTable[] = {&buttonState};
+        GattService         buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
+        ble.gattServer().addService(buttonService);
+    }
+ 
+    void updateButtonState(bool newState) {
+        ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool));
+    }
+ 
+private:
+    BLE                              &ble;
+    ReadOnlyGattCharacteristic<bool>  buttonState;
+};
+ 
+#endif /* #ifndef __BLE_BUTTON_SERVICE_H__ */
+ 
\ No newline at end of file
--- a/main.cpp	Tue Jan 12 10:34:34 2016 +0000
+++ b/main.cpp	Fri Apr 29 11:44:02 2016 +0000
@@ -17,25 +17,44 @@
 #include "mbed.h"
 #include "ble/BLE.h"
 #include "LEDService.h"
+#include "ButtonService.h"
 
-DigitalOut alivenessLED(LED1, 0);
-DigitalOut actuatedLED(LED2, 0);
+#define LED_ON          0
+#define LED_OFF         1
 
-const static char     DEVICE_NAME[] = "LED";
-static const uint16_t uuid16_list[] = {LEDService::LED_SERVICE_UUID};
+DigitalOut alivenessLED(LED1, LED_OFF); // green
+DigitalOut actuatedLED(LED2, LED_OFF);  // red
+InterruptIn button(BUTTON1);
+
+const static char     DEVICE_NAME[] = "MY_BLE_DEVICE";
+static const uint16_t uuid16_list[] = { 
+    LEDService::LED_SERVICE_UUID, 
+    ButtonService::BUTTON_SERVICE_UUID
+};
 
 LEDService *ledServicePtr;
+ButtonService *buttonServicePtr;
 
 Ticker ticker;
 
+void periodicCallback(void)
+{
+    alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
+}
+
 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *params)
 {
     BLE::Instance().gap().startAdvertising();
+    
+    ticker.attach(periodicCallback, 1);
 }
 
-void periodicCallback(void)
+void connectionCallback(const Gap::ConnectionCallbackParams_t * params)
 {
-    alivenessLED = !alivenessLED; /* Do blinky on LED1 to indicate system aliveness. */
+    // stop blinking when we connect
+    ticker.detach();
+    // also put the led off
+    alivenessLED = LED_OFF;
 }
 
 /**
@@ -45,8 +64,12 @@
  *     Information about the characterisitc being updated.
  */
 void onDataWrittenCallback(const GattWriteCallbackParams *params) {
+    // handle corresponds to the characteristic being written
+    // then we can read data to get a buffer of the actual data
     if ((params->handle == ledServicePtr->getValueHandle()) && (params->len == 1)) {
-        actuatedLED = *(params->data);
+        // When writing 1 -> turn LED on, 0 -> turn LED off
+        char val = params->data[0];
+        actuatedLED = val == 1 ? LED_ON : LED_OFF;
     }
 }
 
@@ -55,7 +78,8 @@
  */
 void onBleInitError(BLE &ble, ble_error_t error)
 {
-    /* Initialization error handling should go here */
+    // blink fast when we encountered an error
+    ticker.attach(periodicCallback, 0.2);
 }
 
 /**
@@ -78,12 +102,14 @@
     }
  
     ble.gap().onDisconnection(disconnectionCallback);
+    ble.gap().onConnection(connectionCallback);
     ble.gattServer().onDataWritten(onDataWrittenCallback);
 
-    bool initialValueForLEDCharacteristic = false;
-    ledServicePtr = new LEDService(ble, initialValueForLEDCharacteristic);
+    // Begin - If you add a new service, add it here!
+    ledServicePtr = new LEDService(ble, false /* inital value */);
+    buttonServicePtr = new ButtonService(ble, false /* initial value */);
+    // End - If you add a new service, add it here!
 
-    /* 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));
@@ -92,10 +118,23 @@
     ble.gap().startAdvertising();
 }
 
+void button_down() {
+    if (!buttonServicePtr) return;
+    buttonServicePtr->updateButtonState(true);
+}
+void button_up() {
+    if (!buttonServicePtr) return;
+    buttonServicePtr->updateButtonState(false);
+}
+
 int main(void)
 {
-    ticker.attach(periodicCallback, 1); /* Blink LED every second */
-
+    // Blink the green LED!
+    ticker.attach(periodicCallback, 1);
+    
+    button.fall(&button_down);
+    button.rise(&button_up);
+    
     BLE &ble = BLE::Instance();
     ble.init(bleInitComplete);