Smart Button

Dependencies:   BLE_API mbed nRF51822

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 #include "mbed.h"
00002 #include "BLE.h"
00003 
00004 class ButtonService {
00005 public:
00006     const static uint16_t BUTTON_SERVICE_UUID              = 0xA000;
00007     const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001;
00008  
00009     ButtonService(BLEDevice &_ble, bool buttonPressedInitial) :
00010         ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY)
00011     {
00012         GattCharacteristic *charTable[] = {&buttonState};
00013         GattService         buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
00014         ble.gattServer().addService(buttonService);
00015     }
00016  
00017     void updateButtonState(bool newState)
00018     {
00019         ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool));
00020     }
00021  
00022 private:
00023     BLEDevice &ble;
00024     ReadOnlyGattCharacteristic<bool> buttonState;
00025 };
00026 
00027 class LEDService {
00028 public:
00029     const static uint16_t LED_SERVICE_UUID              = 0xB000;
00030     const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xB001;
00031  
00032     LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic = false) :
00033         ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic)
00034     {
00035         GattCharacteristic *charTable[] = {&ledState};
00036         GattService         ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
00037         ble.gattServer().addService(ledService);
00038     }
00039  
00040     GattAttribute::Handle_t getValueHandle() const
00041     {
00042         return ledState.getValueHandle();
00043     }
00044  
00045 private:
00046     BLEDevice &ble;
00047     ReadWriteGattCharacteristic<bool> ledState;
00048 };
00049 
00050 class BuzzerService {
00051 public:
00052     const static uint16_t BUZZ_SERVICE_UUID              = 0xC000;
00053     const static uint16_t BUZZ_STATE_CHARACTERISTIC_UUID = 0xC001;
00054  
00055     BuzzerService(BLEDevice &_ble, uint16_t initialValue = 0) :
00056         ble(_ble), buzzState(BUZZ_STATE_CHARACTERISTIC_UUID, &initialValue)
00057     {
00058         GattCharacteristic *charTable[] = {&buzzState};
00059         GattService         buzzService(BUZZ_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *));
00060         ble.gattServer().addService(buzzService);
00061     }
00062  
00063     GattAttribute::Handle_t getValueHandle() const
00064     {
00065         return buzzState.getValueHandle();
00066     }
00067  
00068 private:
00069     BLEDevice &ble;
00070     ReadWriteGattCharacteristic<uint16_t> buzzState;
00071 };
00072 
00073 DigitalOut  led1(p14);
00074 DigitalOut  led2(p15);
00075 InterruptIn button(p16);
00076 PwmOut*     buzzer = NULL;
00077 
00078 void setBuzzer(uint16_t value) {
00079     if (value) {
00080         if (!buzzer) {
00081             buzzer = new PwmOut(p30);
00082         }
00083         buzzer->period(1.0/value);
00084         buzzer->write(0.5);
00085     } else {
00086         if (buzzer) {
00087             buzzer->write(0);
00088             delete buzzer;
00089             buzzer = NULL;
00090         }
00091     }
00092 }
00093 
00094 static const uint8_t device_name[] = "Nut2";
00095 static const uint16_t uuid16_list[] = {
00096     ButtonService::BUTTON_SERVICE_UUID,
00097     LEDService::LED_SERVICE_UUID
00098 };
00099 
00100 BLEDevice      ble;
00101 ButtonService *svcButton;
00102 LEDService    *svcLed1;
00103 LEDService    *svcLed2;
00104 BuzzerService *svcBuzzer;
00105  
00106 void buttonPressedCallback(void)
00107 {
00108     svcButton->updateButtonState(true);
00109 }
00110  
00111 void buttonReleasedCallback(void)
00112 {
00113     svcButton->updateButtonState(false);
00114 }
00115 
00116 void disconnectionCallback(const Gap::DisconnectionCallbackParams_t* reason)
00117 {
00118     ble.startAdvertising();
00119     led1 = 1;
00120     led2 = 1;
00121     setBuzzer(0);
00122 }
00123 
00124 void onDataWrittenCallback(const GattWriteCallbackParams *params)
00125 {
00126     if ((params->handle == svcLed1->getValueHandle()) && (params->len == 1)) {
00127         led1 = !*(params->data);
00128     } else if ((params->handle == svcLed2->getValueHandle()) && (params->len == 1)) {
00129         led2 = !*(params->data);
00130     } else if ((params->handle == svcBuzzer->getValueHandle()) && (params->len == 2)) {
00131         setBuzzer(*(uint16_t*)(params->data));
00132     }
00133 }
00134  
00135 int main(void)
00136 {
00137     led1 = 1;
00138     led2 = 1;
00139     setBuzzer(0);
00140     //Ticker ticker;
00141     //ticker.attach([] { led1 = !led1; }, 1.0);
00142     button.fall(buttonPressedCallback);
00143     button.rise(buttonReleasedCallback);
00144  
00145     ble.init();
00146     ble.onDisconnection(disconnectionCallback);
00147     ble.gattServer().onDataWritten(onDataWrittenCallback);
00148  
00149     svcButton = new ButtonService(ble, false);
00150     svcLed1 = new LEDService(ble);
00151     svcLed2 = new LEDService(ble);
00152     svcBuzzer = new BuzzerService(ble);
00153  
00154     // setup advertising
00155     ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
00156     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list));
00157     ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, device_name, sizeof(device_name));
00158 
00159     ble.gap().setDeviceName(device_name);
00160     ble.gap().setTxPower(4);
00161     ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
00162     ble.gap().setAdvertisingInterval(Gap::MSEC_TO_GAP_DURATION_UNITS(1000));
00163     ble.gap().setAdvertisingTimeout(0);
00164     ble.startAdvertising();
00165  
00166     while (true) {
00167         ble.waitForEvent();
00168     }
00169 }