Smart Button
Dependencies: BLE_API mbed nRF51822
main.cpp@1:795c0e3fbd4e, 2016-10-16 (annotated)
- Committer:
- vshymanskyy
- Date:
- Sun Oct 16 14:19:47 2016 +0000
- Revision:
- 1:795c0e3fbd4e
- Parent:
- 0:d7ba2329a303
remove comment
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
vshymanskyy | 0:d7ba2329a303 | 1 | #include "mbed.h" |
vshymanskyy | 0:d7ba2329a303 | 2 | #include "BLE.h" |
vshymanskyy | 0:d7ba2329a303 | 3 | |
vshymanskyy | 0:d7ba2329a303 | 4 | class ButtonService { |
vshymanskyy | 0:d7ba2329a303 | 5 | public: |
vshymanskyy | 0:d7ba2329a303 | 6 | const static uint16_t BUTTON_SERVICE_UUID = 0xA000; |
vshymanskyy | 0:d7ba2329a303 | 7 | const static uint16_t BUTTON_STATE_CHARACTERISTIC_UUID = 0xA001; |
vshymanskyy | 0:d7ba2329a303 | 8 | |
vshymanskyy | 0:d7ba2329a303 | 9 | ButtonService(BLEDevice &_ble, bool buttonPressedInitial) : |
vshymanskyy | 0:d7ba2329a303 | 10 | ble(_ble), buttonState(BUTTON_STATE_CHARACTERISTIC_UUID, &buttonPressedInitial, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY) |
vshymanskyy | 0:d7ba2329a303 | 11 | { |
vshymanskyy | 0:d7ba2329a303 | 12 | GattCharacteristic *charTable[] = {&buttonState}; |
vshymanskyy | 0:d7ba2329a303 | 13 | GattService buttonService(ButtonService::BUTTON_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); |
vshymanskyy | 0:d7ba2329a303 | 14 | ble.gattServer().addService(buttonService); |
vshymanskyy | 0:d7ba2329a303 | 15 | } |
vshymanskyy | 0:d7ba2329a303 | 16 | |
vshymanskyy | 0:d7ba2329a303 | 17 | void updateButtonState(bool newState) |
vshymanskyy | 0:d7ba2329a303 | 18 | { |
vshymanskyy | 0:d7ba2329a303 | 19 | ble.gattServer().write(buttonState.getValueHandle(), (uint8_t *)&newState, sizeof(bool)); |
vshymanskyy | 0:d7ba2329a303 | 20 | } |
vshymanskyy | 0:d7ba2329a303 | 21 | |
vshymanskyy | 0:d7ba2329a303 | 22 | private: |
vshymanskyy | 0:d7ba2329a303 | 23 | BLEDevice &ble; |
vshymanskyy | 0:d7ba2329a303 | 24 | ReadOnlyGattCharacteristic<bool> buttonState; |
vshymanskyy | 0:d7ba2329a303 | 25 | }; |
vshymanskyy | 0:d7ba2329a303 | 26 | |
vshymanskyy | 0:d7ba2329a303 | 27 | class LEDService { |
vshymanskyy | 0:d7ba2329a303 | 28 | public: |
vshymanskyy | 0:d7ba2329a303 | 29 | const static uint16_t LED_SERVICE_UUID = 0xB000; |
vshymanskyy | 0:d7ba2329a303 | 30 | const static uint16_t LED_STATE_CHARACTERISTIC_UUID = 0xB001; |
vshymanskyy | 0:d7ba2329a303 | 31 | |
vshymanskyy | 0:d7ba2329a303 | 32 | LEDService(BLEDevice &_ble, bool initialValueForLEDCharacteristic = false) : |
vshymanskyy | 0:d7ba2329a303 | 33 | ble(_ble), ledState(LED_STATE_CHARACTERISTIC_UUID, &initialValueForLEDCharacteristic) |
vshymanskyy | 0:d7ba2329a303 | 34 | { |
vshymanskyy | 0:d7ba2329a303 | 35 | GattCharacteristic *charTable[] = {&ledState}; |
vshymanskyy | 0:d7ba2329a303 | 36 | GattService ledService(LED_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); |
vshymanskyy | 0:d7ba2329a303 | 37 | ble.gattServer().addService(ledService); |
vshymanskyy | 0:d7ba2329a303 | 38 | } |
vshymanskyy | 0:d7ba2329a303 | 39 | |
vshymanskyy | 0:d7ba2329a303 | 40 | GattAttribute::Handle_t getValueHandle() const |
vshymanskyy | 0:d7ba2329a303 | 41 | { |
vshymanskyy | 0:d7ba2329a303 | 42 | return ledState.getValueHandle(); |
vshymanskyy | 0:d7ba2329a303 | 43 | } |
vshymanskyy | 0:d7ba2329a303 | 44 | |
vshymanskyy | 0:d7ba2329a303 | 45 | private: |
vshymanskyy | 0:d7ba2329a303 | 46 | BLEDevice &ble; |
vshymanskyy | 0:d7ba2329a303 | 47 | ReadWriteGattCharacteristic<bool> ledState; |
vshymanskyy | 0:d7ba2329a303 | 48 | }; |
vshymanskyy | 0:d7ba2329a303 | 49 | |
vshymanskyy | 0:d7ba2329a303 | 50 | class BuzzerService { |
vshymanskyy | 0:d7ba2329a303 | 51 | public: |
vshymanskyy | 0:d7ba2329a303 | 52 | const static uint16_t BUZZ_SERVICE_UUID = 0xC000; |
vshymanskyy | 0:d7ba2329a303 | 53 | const static uint16_t BUZZ_STATE_CHARACTERISTIC_UUID = 0xC001; |
vshymanskyy | 0:d7ba2329a303 | 54 | |
vshymanskyy | 0:d7ba2329a303 | 55 | BuzzerService(BLEDevice &_ble, uint16_t initialValue = 0) : |
vshymanskyy | 0:d7ba2329a303 | 56 | ble(_ble), buzzState(BUZZ_STATE_CHARACTERISTIC_UUID, &initialValue) |
vshymanskyy | 0:d7ba2329a303 | 57 | { |
vshymanskyy | 0:d7ba2329a303 | 58 | GattCharacteristic *charTable[] = {&buzzState}; |
vshymanskyy | 0:d7ba2329a303 | 59 | GattService buzzService(BUZZ_SERVICE_UUID, charTable, sizeof(charTable) / sizeof(GattCharacteristic *)); |
vshymanskyy | 0:d7ba2329a303 | 60 | ble.gattServer().addService(buzzService); |
vshymanskyy | 0:d7ba2329a303 | 61 | } |
vshymanskyy | 0:d7ba2329a303 | 62 | |
vshymanskyy | 0:d7ba2329a303 | 63 | GattAttribute::Handle_t getValueHandle() const |
vshymanskyy | 0:d7ba2329a303 | 64 | { |
vshymanskyy | 0:d7ba2329a303 | 65 | return buzzState.getValueHandle(); |
vshymanskyy | 0:d7ba2329a303 | 66 | } |
vshymanskyy | 0:d7ba2329a303 | 67 | |
vshymanskyy | 0:d7ba2329a303 | 68 | private: |
vshymanskyy | 0:d7ba2329a303 | 69 | BLEDevice &ble; |
vshymanskyy | 0:d7ba2329a303 | 70 | ReadWriteGattCharacteristic<uint16_t> buzzState; |
vshymanskyy | 0:d7ba2329a303 | 71 | }; |
vshymanskyy | 0:d7ba2329a303 | 72 | |
vshymanskyy | 0:d7ba2329a303 | 73 | DigitalOut led1(p14); |
vshymanskyy | 0:d7ba2329a303 | 74 | DigitalOut led2(p15); |
vshymanskyy | 0:d7ba2329a303 | 75 | InterruptIn button(p16); |
vshymanskyy | 0:d7ba2329a303 | 76 | PwmOut* buzzer = NULL; |
vshymanskyy | 0:d7ba2329a303 | 77 | |
vshymanskyy | 0:d7ba2329a303 | 78 | void setBuzzer(uint16_t value) { |
vshymanskyy | 0:d7ba2329a303 | 79 | if (value) { |
vshymanskyy | 0:d7ba2329a303 | 80 | if (!buzzer) { |
vshymanskyy | 0:d7ba2329a303 | 81 | buzzer = new PwmOut(p30); |
vshymanskyy | 0:d7ba2329a303 | 82 | } |
vshymanskyy | 0:d7ba2329a303 | 83 | buzzer->period(1.0/value); |
vshymanskyy | 0:d7ba2329a303 | 84 | buzzer->write(0.5); |
vshymanskyy | 0:d7ba2329a303 | 85 | } else { |
vshymanskyy | 0:d7ba2329a303 | 86 | if (buzzer) { |
vshymanskyy | 0:d7ba2329a303 | 87 | buzzer->write(0); |
vshymanskyy | 0:d7ba2329a303 | 88 | delete buzzer; |
vshymanskyy | 0:d7ba2329a303 | 89 | buzzer = NULL; |
vshymanskyy | 0:d7ba2329a303 | 90 | } |
vshymanskyy | 0:d7ba2329a303 | 91 | } |
vshymanskyy | 0:d7ba2329a303 | 92 | } |
vshymanskyy | 0:d7ba2329a303 | 93 | |
vshymanskyy | 0:d7ba2329a303 | 94 | static const uint8_t device_name[] = "Nut2"; |
vshymanskyy | 0:d7ba2329a303 | 95 | static const uint16_t uuid16_list[] = { |
vshymanskyy | 0:d7ba2329a303 | 96 | ButtonService::BUTTON_SERVICE_UUID, |
vshymanskyy | 0:d7ba2329a303 | 97 | LEDService::LED_SERVICE_UUID |
vshymanskyy | 0:d7ba2329a303 | 98 | }; |
vshymanskyy | 0:d7ba2329a303 | 99 | |
vshymanskyy | 0:d7ba2329a303 | 100 | BLEDevice ble; |
vshymanskyy | 0:d7ba2329a303 | 101 | ButtonService *svcButton; |
vshymanskyy | 0:d7ba2329a303 | 102 | LEDService *svcLed1; |
vshymanskyy | 0:d7ba2329a303 | 103 | LEDService *svcLed2; |
vshymanskyy | 0:d7ba2329a303 | 104 | BuzzerService *svcBuzzer; |
vshymanskyy | 0:d7ba2329a303 | 105 | |
vshymanskyy | 0:d7ba2329a303 | 106 | void buttonPressedCallback(void) |
vshymanskyy | 0:d7ba2329a303 | 107 | { |
vshymanskyy | 0:d7ba2329a303 | 108 | svcButton->updateButtonState(true); |
vshymanskyy | 0:d7ba2329a303 | 109 | } |
vshymanskyy | 0:d7ba2329a303 | 110 | |
vshymanskyy | 0:d7ba2329a303 | 111 | void buttonReleasedCallback(void) |
vshymanskyy | 0:d7ba2329a303 | 112 | { |
vshymanskyy | 0:d7ba2329a303 | 113 | svcButton->updateButtonState(false); |
vshymanskyy | 0:d7ba2329a303 | 114 | } |
vshymanskyy | 0:d7ba2329a303 | 115 | |
vshymanskyy | 0:d7ba2329a303 | 116 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t* reason) |
vshymanskyy | 0:d7ba2329a303 | 117 | { |
vshymanskyy | 0:d7ba2329a303 | 118 | ble.startAdvertising(); |
vshymanskyy | 0:d7ba2329a303 | 119 | led1 = 1; |
vshymanskyy | 0:d7ba2329a303 | 120 | led2 = 1; |
vshymanskyy | 0:d7ba2329a303 | 121 | setBuzzer(0); |
vshymanskyy | 0:d7ba2329a303 | 122 | } |
vshymanskyy | 0:d7ba2329a303 | 123 | |
vshymanskyy | 0:d7ba2329a303 | 124 | void onDataWrittenCallback(const GattWriteCallbackParams *params) |
vshymanskyy | 0:d7ba2329a303 | 125 | { |
vshymanskyy | 0:d7ba2329a303 | 126 | if ((params->handle == svcLed1->getValueHandle()) && (params->len == 1)) { |
vshymanskyy | 0:d7ba2329a303 | 127 | led1 = !*(params->data); |
vshymanskyy | 0:d7ba2329a303 | 128 | } else if ((params->handle == svcLed2->getValueHandle()) && (params->len == 1)) { |
vshymanskyy | 0:d7ba2329a303 | 129 | led2 = !*(params->data); |
vshymanskyy | 0:d7ba2329a303 | 130 | } else if ((params->handle == svcBuzzer->getValueHandle()) && (params->len == 2)) { |
vshymanskyy | 0:d7ba2329a303 | 131 | setBuzzer(*(uint16_t*)(params->data)); |
vshymanskyy | 0:d7ba2329a303 | 132 | } |
vshymanskyy | 0:d7ba2329a303 | 133 | } |
vshymanskyy | 0:d7ba2329a303 | 134 | |
vshymanskyy | 0:d7ba2329a303 | 135 | int main(void) |
vshymanskyy | 0:d7ba2329a303 | 136 | { |
vshymanskyy | 0:d7ba2329a303 | 137 | led1 = 1; |
vshymanskyy | 0:d7ba2329a303 | 138 | led2 = 1; |
vshymanskyy | 0:d7ba2329a303 | 139 | setBuzzer(0); |
vshymanskyy | 0:d7ba2329a303 | 140 | //Ticker ticker; |
vshymanskyy | 0:d7ba2329a303 | 141 | //ticker.attach([] { led1 = !led1; }, 1.0); |
vshymanskyy | 0:d7ba2329a303 | 142 | button.fall(buttonPressedCallback); |
vshymanskyy | 0:d7ba2329a303 | 143 | button.rise(buttonReleasedCallback); |
vshymanskyy | 0:d7ba2329a303 | 144 | |
vshymanskyy | 0:d7ba2329a303 | 145 | ble.init(); |
vshymanskyy | 0:d7ba2329a303 | 146 | ble.onDisconnection(disconnectionCallback); |
vshymanskyy | 0:d7ba2329a303 | 147 | ble.gattServer().onDataWritten(onDataWrittenCallback); |
vshymanskyy | 0:d7ba2329a303 | 148 | |
vshymanskyy | 0:d7ba2329a303 | 149 | svcButton = new ButtonService(ble, false); |
vshymanskyy | 0:d7ba2329a303 | 150 | svcLed1 = new LEDService(ble); |
vshymanskyy | 0:d7ba2329a303 | 151 | svcLed2 = new LEDService(ble); |
vshymanskyy | 0:d7ba2329a303 | 152 | svcBuzzer = new BuzzerService(ble); |
vshymanskyy | 0:d7ba2329a303 | 153 | |
vshymanskyy | 0:d7ba2329a303 | 154 | // setup advertising |
vshymanskyy | 0:d7ba2329a303 | 155 | ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
vshymanskyy | 0:d7ba2329a303 | 156 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); |
vshymanskyy | 0:d7ba2329a303 | 157 | ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, device_name, sizeof(device_name)); |
vshymanskyy | 0:d7ba2329a303 | 158 | |
vshymanskyy | 0:d7ba2329a303 | 159 | ble.gap().setDeviceName(device_name); |
vshymanskyy | 0:d7ba2329a303 | 160 | ble.gap().setTxPower(4); |
vshymanskyy | 0:d7ba2329a303 | 161 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
vshymanskyy | 0:d7ba2329a303 | 162 | ble.gap().setAdvertisingInterval(Gap::MSEC_TO_GAP_DURATION_UNITS(1000)); |
vshymanskyy | 0:d7ba2329a303 | 163 | ble.gap().setAdvertisingTimeout(0); |
vshymanskyy | 0:d7ba2329a303 | 164 | ble.startAdvertising(); |
vshymanskyy | 0:d7ba2329a303 | 165 | |
vshymanskyy | 0:d7ba2329a303 | 166 | while (true) { |
vshymanskyy | 0:d7ba2329a303 | 167 | ble.waitForEvent(); |
vshymanskyy | 0:d7ba2329a303 | 168 | } |
vshymanskyy | 0:d7ba2329a303 | 169 | } |