clone

Dependencies:   BLE_API Blynk mbed nRF51822

Fork of Blynk_RBL_BLE_Nano by Volodymyr Shymanskyy

main.cpp

Committer:
vshymanskyy
Date:
2015-08-31
Revision:
0:cf8e8a71c9c3
Child:
1:6b5c74442c7a

File content as of revision 0:cf8e8a71c9c3:

#include "mbed.h"
#include "ble/BLE.h"

#define TXRX_BUF_LEN                     20

Timer millis_timer;

static
void delay(unsigned long ms)
{
    wait_ms(ms);
}

static
unsigned long millis(void)
{
    return millis_timer.read_ms();
}

BLE  ble;

Serial pc(USBTX, USBRX);

#define BLYNK_DEBUG
#define BLYNK_PRINT pc
#include <Blynk/BlynkSimpleUserDefined.h>
#include <Blynk/utility/BlynkFifo.h>


// The Nordic UART Service
static const uint8_t uart_base_uuid[]     = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_tx_uuid[]       = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_rx_uuid[]       = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
static const uint8_t uart_dev_name[]      = "Blynk";

uint8_t txPayload[TXRX_BUF_LEN] = {0,};
uint8_t rxPayload[TXRX_BUF_LEN] = {0,};

GattCharacteristic  txCharacteristic (uart_tx_uuid, txPayload, 1,
                    TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE |
                    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE);
                                      
GattCharacteristic  rxCharacteristic (uart_rx_uuid, rxPayload, 1, TXRX_BUF_LEN,
                    GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
                                      
GattCharacteristic *uartChars[] = {&txCharacteristic, &rxCharacteristic};

GattService         uartService(uart_base_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));



void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
    pc.printf("Disconnected \r\n");
    pc.printf("Restart advertising \r\n");
    ble.startAdvertising();
}

BlynkFifo<uint8_t, 128> rx_fifo;

void WrittenHandler(const GattWriteCallbackParams *Handler)
{
    if (Handler->handle == txCharacteristic.getValueAttribute().getHandle()) 
    {
        uint8_t buf[TXRX_BUF_LEN];
        uint16_t bytesRead;
        ble.readCharacteristicValue(txCharacteristic.getValueAttribute().getHandle(), buf, &bytesRead);
        pc.printf("Got data\r\n");
        rx_fifo.write(buf, bytesRead);
    }
}

// You should get Auth Token in the Blynk App.
// Go to the Project Settings (nut icon).
char auth[] = "e3918e9a5fbd4739a8c973bcfc4e12b8";

// This function is used by Blynk to receive data
size_t BlynkStreamRead(void* buf, size_t len)
{
    uint32_t start = millis();
    while ((rx_fifo.getOccupied() < len) && (millis() - start < 1500)) {
        ble.waitForEvent();
    }
    return rx_fifo.read((uint8_t*)buf, len);
}

// This function is used by Blynk to send data
size_t BlynkStreamWrite(const void* buf, size_t len)
{
    int i = 0;
    uint8_t* buff = (uint8_t*)buf;
    while (i < len) {
        ble.updateCharacteristicValue(rxCharacteristic.getValueAttribute().getHandle(), buff+i, BlynkMin(size_t(TXRX_BUF_LEN), len-i));
        i += TXRX_BUF_LEN;
    }
    return len;
}

//DigitalOut led(LED1);

BLYNK_READ(V1) {
    //led = !led;
    Blynk.virtualWrite(V1, millis()/1000);
}

Timeout flipper;

//DigitalOut led2(LED2);
 
void flip() {
    //led2 = !led2;
    flipper.attach(&flip, 2.0);
}

void setup()
{
    flipper.attach(&flip, 2.0);
    
    pc.baud(9600);
    millis_timer.start();
    Blynk.begin(auth);

    ble.init();
    ble.onDisconnection(disconnectionCallback);
    ble.onDataWritten(WrittenHandler);  
        
    // setup advertising 
    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
                                    uart_dev_name, sizeof(uart_dev_name) - 1);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
                                    uart_base_uuid_rev, sizeof(uart_base_uuid));
    
    ble.setAdvertisingInterval(Gap::MSEC_TO_GAP_DURATION_UNITS(1000));
    
    ble.addService(uartService);
    
    ble.startAdvertising(); 
    pc.printf("Advertising Start \r\n");
}

void loop()
{
    ble.waitForEvent();
    // Okay, handle Blynk protocol
    int hasIncomingData = rx_fifo.getOccupied();
    //BLYNK_LOG("Readable: %d", hasIncomingData);
    // Tell Blynk if it has incoming data
    // (this allows to skip unneeded BlynkStreamRead calls)
    if (!Blynk.run(hasIncomingData)) {
      // Error happened. No action for serial.
    }
}

int main() {
    setup();
    while(1) {
        loop();
    }
}