Smart Button
Dependencies: BLE_API mbed nRF51822
Diff: main.cpp
- Revision:
- 0:d7ba2329a303
- Child:
- 1:795c0e3fbd4e
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Sun Oct 16 14:18:27 2016 +0000 @@ -0,0 +1,271 @@ +/* + +#define BUTTON_SERVICE_UUID 0xA000 +#define BUTTON_STATE_CHAR_UUID 0xA001 + +#define LED_SERVICE_UUID 0xB000 +#define LED_STATE_CHAR_UUID 0xB001 +#define LED_STATUS_CHAR_UUID 0xB002 + +const static char DEVICE_NAME[] = "Button"; +static const uint16_t uuid16_list[] = {BUTTON_SERVICE_UUID, LED_SERVICE_UUID}; + +bool buttonPressed = false; + +ReadOnlyGattCharacteristic<bool> buttonState(BUTTON_STATE_CHAR_UUID, &buttonPressed, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); + +//static uint8_t readValue[10] = {0}; +//ReadOnlyArrayGattCharacteristic<uint8_t, sizeof(readValue)> readChar(LED_STATUS_CHAR_UUID, readValue); + +static uint8_t writeValue[10] = {0}; +WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(LED_STATE_CHAR_UUID, writeValue); + + + + +void writeCharCallback(const GattWriteCallbackParams* params) +{ + // check to see what characteristic was written, by handle + if(params->handle == writeChar.getValueHandle()) { + // toggle LED if only 1 byte is written + if(params->len == 1) { + led2 = params->data[0] ? false : true; + } + // update the readChar with the value of writeChar + //ble.updateCharacteristicValue(readChar.getValueHandle(),params->data,params->len); + } +} + + + +void buttonPressedCallback(void) +{ + buttonPressed = true; + ble.updateCharacteristicValue(buttonState.getValueHandle(), (uint8_t *)&buttonPressed, sizeof(bool)); + //led2 = false; +} + +void buttonReleasedCallback(void) +{ + buttonPressed = false; + ble.updateCharacteristicValue(buttonState.getValueHandle(), (uint8_t *)&buttonPressed, sizeof(bool)); + //led2 = true; +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t* reason) +{ + ble.startAdvertising(); + led1 = 1; + led2 = 1; +} + +void periodicCallback(void) +{ + led1 = !led1; // Do blinky on LED1 to indicate system aliveness. +} + +int main(void) +{ + led1 = 1; + led2 = 1; + Ticker ticker; + ticker.attach(periodicCallback, 1); + button.fall(buttonPressedCallback); + button.rise(buttonReleasedCallback); + + ble.init(); + ble.onDisconnection(disconnectionCallback); + ble.onDataWritten(writeCharCallback); + + GattCharacteristic *btnChars[] = {&buttonState}; + GattService buttonService(BUTTON_SERVICE_UUID, btnChars, sizeof(btnChars) / sizeof(GattCharacteristic *)); + ble.addService(buttonService); + + // Set up custom service + GattCharacteristic *ledChars[] = { &writeChar}; //&readChar, + GattService ledService(LED_SERVICE_UUID, ledChars, sizeof(ledChars) / sizeof(GattCharacteristic *)); + ble.addService(ledService); + + // setup advertising + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); + ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.setAdvertisingInterval(Gap::MSEC_TO_GAP_DURATION_UNITS(1000)); // 1000ms. + ble.startAdvertising(); + + while (true) { + ble.waitForEvent(); + } +} +*/ + +#include "mbed.h" +#include "BLE.h" + +class ButtonService { +public: + const static uint16_t BUTTON_SERVICE_UUID = 0xA000; + const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001; + + ButtonService(BLEDevice &_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: + BLEDevice &ble; + ReadOnlyGattCharacteristic<bool> buttonState; +}; + +class LEDService { +public: + const static uint16_t LED_SERVICE_UUID = 0xB000; + const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xB001; + + LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic = false) : + ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic) + { + GattCharacteristic *charTable[] = {&ledState}; + GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.gattServer().addService(ledService); + } + + GattAttribute::Handle_t getValueHandle() const + { + return ledState.getValueHandle(); + } + +private: + BLEDevice &ble; + ReadWriteGattCharacteristic<bool> ledState; +}; + +class BuzzerService { +public: + const static uint16_t BUZZ_SERVICE_UUID = 0xC000; + const static uint16_t BUZZ_STATE_CHARACTERISTIC_UUID = 0xC001; + + BuzzerService(BLEDevice &_ble, uint16_t initialValue = 0) : + ble(_ble), buzzState(BUZZ_STATE_CHARACTERISTIC_UUID, &initialValue) + { + GattCharacteristic *charTable[] = {&buzzState}; + GattService buzzService(BUZZ_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); + ble.gattServer().addService(buzzService); + } + + GattAttribute::Handle_t getValueHandle() const + { + return buzzState.getValueHandle(); + } + +private: + BLEDevice &ble; + ReadWriteGattCharacteristic<uint16_t> buzzState; +}; + +DigitalOut led1(p14); +DigitalOut led2(p15); +InterruptIn button(p16); +PwmOut* buzzer = NULL; + +void setBuzzer(uint16_t value) { + if (value) { + if (!buzzer) { + buzzer = new PwmOut(p30); + } + buzzer->period(1.0/value); + buzzer->write(0.5); + } else { + if (buzzer) { + buzzer->write(0); + delete buzzer; + buzzer = NULL; + } + } +} + +static const uint8_t device_name[] = "Nut2"; +static const uint16_t uuid16_list[] = { + ButtonService::BUTTON_SERVICE_UUID, + LEDService::LED_SERVICE_UUID +}; + +BLEDevice ble; +ButtonService *svcButton; +LEDService *svcLed1; +LEDService *svcLed2; +BuzzerService *svcBuzzer; + +void buttonPressedCallback(void) +{ + svcButton->updateButtonState(true); +} + +void buttonReleasedCallback(void) +{ + svcButton->updateButtonState(false); +} + +void disconnectionCallback(const Gap::DisconnectionCallbackParams_t* reason) +{ + ble.startAdvertising(); + led1 = 1; + led2 = 1; + setBuzzer(0); +} + +void onDataWrittenCallback(const GattWriteCallbackParams *params) +{ + if ((params->handle == svcLed1->getValueHandle()) && (params->len == 1)) { + led1 = !*(params->data); + } else if ((params->handle == svcLed2->getValueHandle()) && (params->len == 1)) { + led2 = !*(params->data); + } else if ((params->handle == svcBuzzer->getValueHandle()) && (params->len == 2)) { + setBuzzer(*(uint16_t*)(params->data)); + } +} + +int main(void) +{ + led1 = 1; + led2 = 1; + setBuzzer(0); + //Ticker ticker; + //ticker.attach([] { led1 = !led1; }, 1.0); + button.fall(buttonPressedCallback); + button.rise(buttonReleasedCallback); + + ble.init(); + ble.onDisconnection(disconnectionCallback); + ble.gattServer().onDataWritten(onDataWrittenCallback); + + svcButton = new ButtonService(ble, false); + svcLed1 = new LEDService(ble); + svcLed2 = new LEDService(ble); + svcBuzzer = new BuzzerService(ble); + + // setup advertising + ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); + ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, device_name, sizeof(device_name)); + + ble.gap().setDeviceName(device_name); + ble.gap().setTxPower(4); + ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); + ble.gap().setAdvertisingInterval(Gap::MSEC_TO_GAP_DURATION_UNITS(1000)); + ble.gap().setAdvertisingTimeout(0); + ble.startAdvertising(); + + while (true) { + ble.waitForEvent(); + } +} \ No newline at end of file