Smart Button
Dependencies: BLE_API mbed nRF51822
main.cpp
- Committer:
- vshymanskyy
- Date:
- 2016-10-16
- Revision:
- 0:d7ba2329a303
- Child:
- 1:795c0e3fbd4e
File content as of revision 0:d7ba2329a303:
/* #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(); } }