Smart Button

Dependencies:   BLE_API mbed nRF51822

main.cpp

Committer:
vshymanskyy
Date:
2016-10-16
Revision:
1:795c0e3fbd4e
Parent:
0:d7ba2329a303

File content as of revision 1:795c0e3fbd4e:

#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();
    }
}