Nordic nRF51 basic device information, battery & temperature services example.

Dependencies:   BLE_API mbed nRF51822

You can use for example in Nexus4 BLE Device Monitor application to look each Service characteristics.

main.cpp

Committer:
MetaMika
Date:
2015-06-08
Revision:
2:8f2c349db7dd
Parent:
1:ddb24c21ea52

File content as of revision 2:8f2c349db7dd:

/* mbed Microcontroller Library
 * Copyright (c) 2006-2013 ARM Limited
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * Author: Mika Karaila, Metso Automation Inc.
 *
 * This Bluetooth LE example contains all basic device characteristics.
 * Measurement services are simulated for battery & temperature.
 *
 */

#include "mbed.h"
#include "BLEDevice.h"

BLEDevice  ble;
DigitalOut led1(LED1);

#define NEED_CONSOLE_OUTPUT 0 /* Set this if you need debug messages on the console;
                               * it will have an impact on code-size and power consumption. */

#if NEED_CONSOLE_OUTPUT
Serial  pc(USBTX, USBRX);
#define DEBUG(...) { pc.printf(__VA_ARGS__); }
#else
#define DEBUG(...) /* nothing */
#endif /* #if NEED_CONSOLE_OUTPUT */

// DEVICE_NAME_UUID = '2A00'; // Nordic fixed this to nRF5, can be written

// Temperature 0-100 C, simulated
static uint8_t      temperature = 32;
GattCharacteristic  tempMeas(GattCharacteristic::UUID_TEMPERATURE_MEASUREMENT_CHAR, (uint8_t *)temperature, sizeof(temperature), sizeof(temperature),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *temperatureChars[] = {&tempMeas };
// TODO add custom service instead of Heart rate
GattService         temperatureService(GattService::UUID_HEART_RATE_SERVICE, temperatureChars, sizeof(temperatureChars) / sizeof(GattCharacteristic *));

// SYSTEM
static char         systemId = 'A';
GattCharacteristic  systemID(GattCharacteristic::UUID_SYSTEM_ID_CHAR, (uint8_t *)systemId, sizeof(systemId), sizeof(systemId),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *systemChars[] = {&systemID };
GattService         systemService(GattService::UUID_DEVICE_INFORMATION_SERVICE, systemChars, sizeof(systemChars) / sizeof(GattCharacteristic *));

// MODEL
static char         model[31] = "Test sensor";
GattCharacteristic  modelID(GattCharacteristic::UUID_MODEL_NUMBER_STRING_CHAR, (uint8_t *)model, sizeof(model), sizeof(model),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *modelChars[] = {&modelID };
GattService         modelService(GattService::UUID_DEVICE_INFORMATION_SERVICE, modelChars, sizeof(modelChars) / sizeof(GattCharacteristic *));

// Firmware
static char         fwversion[31] = "Firmware: 0216";
GattCharacteristic  fwChars(GattCharacteristic::UUID_FIRMWARE_REVISION_STRING_CHAR, (uint8_t *)fwversion, sizeof(fwversion), sizeof(fwversion),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *firmwareChars[] = {&fwChars };
GattService         firmwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, firmwareChars, sizeof(firmwareChars) / sizeof(GattCharacteristic *));

// Software
static char         swversion[31] = "Sensor build (0001)";
GattCharacteristic  swChars(GattCharacteristic::UUID_SOFTWARE_REVISION_STRING_CHAR, (uint8_t *)swversion, sizeof(swversion), sizeof(swversion),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *softwareChars[] = {&swChars };
GattService         softwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, softwareChars, sizeof(softwareChars) / sizeof(GattCharacteristic *));
// Hardware
static char         hwversion[31] = "Sensor hw proto 0";
GattCharacteristic  hwChars(GattCharacteristic::UUID_HARDWARE_REVISION_STRING_CHAR, (uint8_t *)hwversion, sizeof(hwversion), sizeof(hwversion),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *hardwareChars[] = {&hwChars };
GattService         hardwareService(GattService::UUID_DEVICE_INFORMATION_SERVICE, hardwareChars, sizeof(hardwareChars) / sizeof(GattCharacteristic *));
// Manufacturer
static char         vendor[31] = "Test Company Inc.";
GattCharacteristic  vendorChars(GattCharacteristic::UUID_MANUFACTURER_NAME_STRING_CHAR, (uint8_t *)vendor, sizeof(vendor), sizeof(vendor),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *manufacturerChars[] = {&vendorChars };
GattService         manufacturerService(GattService::UUID_DEVICE_INFORMATION_SERVICE, manufacturerChars, sizeof(manufacturerChars) / sizeof(GattCharacteristic *));
// Serial number
static char         serial[31] = "1234567890";
GattCharacteristic  serialChars(GattCharacteristic::UUID_SERIAL_NUMBER_STRING_CHAR, (uint8_t *)serial, sizeof(serial), sizeof(serial),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ);
GattCharacteristic *serialNumberChars[] = {&serialChars };
GattService         serialNumberService(GattService::UUID_DEVICE_INFORMATION_SERVICE, serialNumberChars, sizeof(serialNumberChars) / sizeof(GattCharacteristic *));

static uint8_t      batteryLevel = 100;
GattCharacteristic  batteryPercentage(GattCharacteristic::UUID_BATTERY_LEVEL_CHAR, (uint8_t *)batteryLevel, sizeof(batteryLevel), sizeof(batteryLevel),
                           GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
GattCharacteristic *batteryChars[] = {&batteryPercentage };
GattService         batteryService(GattService::UUID_BATTERY_SERVICE, batteryChars, sizeof(batteryChars) / sizeof(GattCharacteristic *));

void disconnectionCallback(Gap::Handle_t handle, Gap::DisconnectionReason_t reason)
{
    printf("Disconnected handle %u!\n\r", handle);
    printf("Restarting the advertising process\n\r");
    ble.startAdvertising();
}

/**
 * Triggered periodically by the 'ticker' interrupt; updates hrmCounter.
 */
void periodicCallback(void)
{
    led1 = !led1; /* Do blinky on LED1 while we're waiting for BLE events */

    if (ble.getGapState().connected) {
        /* Update the battery measurement */
        batteryLevel--;
        if (batteryLevel == 1) {
            batteryLevel = 100;
        }
        ble.updateCharacteristicValue(batteryPercentage.getValueAttribute().getHandle(), &batteryLevel, sizeof(batteryLevel));
        
        /* Update the temperature measurement */
        temperature++;
        if (temperature == 50) {
            temperature = 10;
        }
        ble.updateCharacteristicValue(tempMeas.getValueAttribute().getHandle(), &temperature, sizeof(temperature));
    }
}

int main(void)
{
    led1 = 1;
    Ticker ticker;
    ticker.attach(periodicCallback, 1);

    DEBUG("Initialising the nRF51822\n\r");
    ble.init();
    ble.onDisconnection(disconnectionCallback);

    /* setup advertising */
    ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::LE_GENERAL_DISCOVERABLE);
    ble.accumulateAdvertisingPayload(GapAdvertisingData::GENERIC_THERMOMETER);

    ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
    ble.setAdvertisingInterval(160); /* 1000ms; in multiples of 0.625ms. */
    ble.startAdvertising();

    ble.addService(batteryService);
    ble.addService(firmwareService);
    ble.addService(softwareService);
    ble.addService(hardwareService);
    ble.addService(modelService);
    ble.addService(temperatureService);

    while (true) {
        ble.waitForEvent();
    }
}