Josh Stroud
/
nrf51-evoTest
Example with mbed, ble, and evothings app
Fork of HelloWorld by
main.cpp@2:3015a85eb00a, 2016-03-15 (annotated)
- Committer:
- jstroud
- Date:
- Tue Mar 15 03:17:05 2016 +0000
- Revision:
- 2:3015a85eb00a
- Parent:
- 0:fb6bbc10ffa0
First commit, works, for Jacob
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
jstroud | 2:3015a85eb00a | 1 | /* |
jstroud | 2:3015a85eb00a | 2 | * nRF51-DK BLEDevice service/characteristic (read/write) using mbed.org |
jstroud | 2:3015a85eb00a | 3 | */ |
jstroud | 2:3015a85eb00a | 4 | |
jstroud | 2:3015a85eb00a | 5 | // uncomment if not interested in a console log |
jstroud | 2:3015a85eb00a | 6 | #define CONSOLE_LOG |
jstroud | 2:3015a85eb00a | 7 | |
simon | 0:fb6bbc10ffa0 | 8 | #include "mbed.h" |
jstroud | 2:3015a85eb00a | 9 | #include "BLE.h" |
jstroud | 2:3015a85eb00a | 10 | |
jstroud | 2:3015a85eb00a | 11 | //------------------------------------------------------------------------- |
jstroud | 2:3015a85eb00a | 12 | |
jstroud | 2:3015a85eb00a | 13 | #ifdef CONSOLE_LOG |
jstroud | 2:3015a85eb00a | 14 | #define INFO(x, ...) printf(x, ##__VA_ARGS__); |
jstroud | 2:3015a85eb00a | 15 | #define INFO_NL(x, ...) printf(x "\r\n", ##__VA_ARGS__); |
jstroud | 2:3015a85eb00a | 16 | #else |
jstroud | 2:3015a85eb00a | 17 | #define INFO(x, ...) |
jstroud | 2:3015a85eb00a | 18 | #define INFO_NL(x, ...) |
jstroud | 2:3015a85eb00a | 19 | #endif |
simon | 0:fb6bbc10ffa0 | 20 | |
jstroud | 2:3015a85eb00a | 21 | // a little routine to print a 128-bit UUID nicely |
jstroud | 2:3015a85eb00a | 22 | void INFO_UUID(const char *prefix, UUID uuid) |
jstroud | 2:3015a85eb00a | 23 | { |
jstroud | 2:3015a85eb00a | 24 | uint8_t *p = (uint8_t *)uuid.getBaseUUID(); |
jstroud | 2:3015a85eb00a | 25 | INFO("%s: ", prefix); |
jstroud | 2:3015a85eb00a | 26 | for (int i=0; i<16; i++) |
jstroud | 2:3015a85eb00a | 27 | { |
jstroud | 2:3015a85eb00a | 28 | INFO("%02x", p[i]); |
jstroud | 2:3015a85eb00a | 29 | if ((i == 3) || (i == 5) || (i == 7) || (i == 9)) INFO("-"); |
jstroud | 2:3015a85eb00a | 30 | } |
jstroud | 2:3015a85eb00a | 31 | INFO_NL(""); |
jstroud | 2:3015a85eb00a | 32 | } |
jstroud | 2:3015a85eb00a | 33 | |
jstroud | 2:3015a85eb00a | 34 | //------------------------------------------------------------------------- |
jstroud | 2:3015a85eb00a | 35 | |
jstroud | 2:3015a85eb00a | 36 | // name of the device |
jstroud | 2:3015a85eb00a | 37 | const static char DEVICE_NAME[] = "nRF51-DK"; |
jstroud | 2:3015a85eb00a | 38 | |
jstroud | 2:3015a85eb00a | 39 | // GATT service and characteristic UUIDs |
jstroud | 2:3015a85eb00a | 40 | const UUID nRF51_GATT_SERVICE = UUID((uint8_t *)"nRF51-DK "); |
jstroud | 2:3015a85eb00a | 41 | const UUID nRF51_GATT_CHAR_BUTTON = UUID((uint8_t *)"nRF51-DK button "); |
jstroud | 2:3015a85eb00a | 42 | const UUID nRF51_GATT_CHAR_LED = UUID((uint8_t *)"nRF51-DK led "); |
simon | 0:fb6bbc10ffa0 | 43 | |
jstroud | 2:3015a85eb00a | 44 | #define CHARACTERISTIC_BUTTON 0 |
jstroud | 2:3015a85eb00a | 45 | #define CHARACTERISTIC_LED 1 |
jstroud | 2:3015a85eb00a | 46 | #define CHARACTERISTIC_COUNT 2 |
jstroud | 2:3015a85eb00a | 47 | |
jstroud | 2:3015a85eb00a | 48 | // our bluetooth smart objects |
jstroud | 2:3015a85eb00a | 49 | BLEDevice ble; |
jstroud | 2:3015a85eb00a | 50 | GattService *gatt_service; |
jstroud | 2:3015a85eb00a | 51 | GattCharacteristic *gatt_characteristics[CHARACTERISTIC_COUNT]; |
jstroud | 2:3015a85eb00a | 52 | uint8_t gatt_char_value[CHARACTERISTIC_COUNT]; |
jstroud | 2:3015a85eb00a | 53 | |
jstroud | 2:3015a85eb00a | 54 | #ifdef CONSOLE_LOG |
jstroud | 2:3015a85eb00a | 55 | Serial pc(USBTX,USBRX); |
jstroud | 2:3015a85eb00a | 56 | #endif |
jstroud | 2:3015a85eb00a | 57 | |
jstroud | 2:3015a85eb00a | 58 | //------------------------------------------------------------------------- |
jstroud | 2:3015a85eb00a | 59 | // button handling |
jstroud | 2:3015a85eb00a | 60 | //------------------------------------------------------------------------- |
jstroud | 2:3015a85eb00a | 61 | |
jstroud | 2:3015a85eb00a | 62 | // define our digital in values we will be using for the characteristic |
jstroud | 2:3015a85eb00a | 63 | DigitalIn button1(P0_17); |
jstroud | 2:3015a85eb00a | 64 | DigitalIn button2(P0_18); |
jstroud | 2:3015a85eb00a | 65 | DigitalIn button3(P0_19); |
jstroud | 2:3015a85eb00a | 66 | DigitalIn button4(P0_20); |
jstroud | 2:3015a85eb00a | 67 | |
jstroud | 2:3015a85eb00a | 68 | uint8_t button_new_value = 0; |
jstroud | 2:3015a85eb00a | 69 | uint8_t button_old_value = button_new_value; |
jstroud | 2:3015a85eb00a | 70 | |
jstroud | 2:3015a85eb00a | 71 | void monitorButtons() |
jstroud | 2:3015a85eb00a | 72 | { |
jstroud | 2:3015a85eb00a | 73 | // read in the buttons, mapped into nibble (0000 = all off, 1111 = all on) |
jstroud | 2:3015a85eb00a | 74 | button_new_value = 0; |
jstroud | 2:3015a85eb00a | 75 | button_new_value |= (button1.read() != 1); button_new_value <<= 1; |
jstroud | 2:3015a85eb00a | 76 | button_new_value |= (button2.read() != 1); button_new_value <<= 1; |
jstroud | 2:3015a85eb00a | 77 | button_new_value |= (button3.read() != 1); button_new_value <<= 1; |
jstroud | 2:3015a85eb00a | 78 | button_new_value |= (button4.read() != 1); |
jstroud | 2:3015a85eb00a | 79 | |
jstroud | 2:3015a85eb00a | 80 | // set the updated value of the characteristic if data has changed |
jstroud | 2:3015a85eb00a | 81 | if (button_new_value != button_old_value) |
jstroud | 2:3015a85eb00a | 82 | { |
jstroud | 2:3015a85eb00a | 83 | ble.updateCharacteristicValue( |
jstroud | 2:3015a85eb00a | 84 | gatt_characteristics[CHARACTERISTIC_BUTTON] -> getValueHandle(), |
jstroud | 2:3015a85eb00a | 85 | &button_new_value, sizeof(button_new_value)); |
jstroud | 2:3015a85eb00a | 86 | button_old_value = button_new_value; |
jstroud | 2:3015a85eb00a | 87 | |
jstroud | 2:3015a85eb00a | 88 | INFO_NL(" button state: [0x%02x]", button_new_value); |
simon | 0:fb6bbc10ffa0 | 89 | } |
simon | 0:fb6bbc10ffa0 | 90 | } |
jstroud | 2:3015a85eb00a | 91 | |
jstroud | 2:3015a85eb00a | 92 | //------------------------------------------------------------------------- |
jstroud | 2:3015a85eb00a | 93 | // LED handling |
jstroud | 2:3015a85eb00a | 94 | //------------------------------------------------------------------------- |
jstroud | 2:3015a85eb00a | 95 | |
jstroud | 2:3015a85eb00a | 96 | DigitalOut led1(P0_21); |
jstroud | 2:3015a85eb00a | 97 | DigitalOut led2(P0_22); |
jstroud | 2:3015a85eb00a | 98 | DigitalOut led3(P0_23); |
jstroud | 2:3015a85eb00a | 99 | DigitalOut led4(P0_24); |
jstroud | 2:3015a85eb00a | 100 | |
jstroud | 2:3015a85eb00a | 101 | uint8_t led_value = 0; |
jstroud | 2:3015a85eb00a | 102 | |
jstroud | 2:3015a85eb00a | 103 | void onLedDataWritten(const uint8_t* value, uint8_t length) |
jstroud | 2:3015a85eb00a | 104 | { |
jstroud | 2:3015a85eb00a | 105 | // we only care about a single byte |
jstroud | 2:3015a85eb00a | 106 | led_value = value[0]; |
jstroud | 2:3015a85eb00a | 107 | |
jstroud | 2:3015a85eb00a | 108 | // depending on the value coming through; set/unset LED's |
jstroud | 2:3015a85eb00a | 109 | if ((led_value & 0x01) != 0) led1.write(0); else led1.write(1); |
jstroud | 2:3015a85eb00a | 110 | if ((led_value & 0x02) != 0) led2.write(0); else led2.write(1); |
jstroud | 2:3015a85eb00a | 111 | if ((led_value & 0x04) != 0) led3.write(0); else led3.write(1); |
jstroud | 2:3015a85eb00a | 112 | if ((led_value & 0x08) != 0) led4.write(0); else led4.write(1); |
jstroud | 2:3015a85eb00a | 113 | |
jstroud | 2:3015a85eb00a | 114 | INFO_NL(" led state: [0x%02x]", led_value); |
jstroud | 2:3015a85eb00a | 115 | } |
jstroud | 2:3015a85eb00a | 116 | |
jstroud | 2:3015a85eb00a | 117 | //------------------------------------------------------------------------- |
jstroud | 2:3015a85eb00a | 118 | |
jstroud | 2:3015a85eb00a | 119 | void onConnection(const Gap::ConnectionCallbackParams_t *params) |
jstroud | 2:3015a85eb00a | 120 | { |
jstroud | 2:3015a85eb00a | 121 | INFO_NL(">> connected"); |
jstroud | 2:3015a85eb00a | 122 | |
jstroud | 2:3015a85eb00a | 123 | // set the initial values of the characteristics (for every session) |
jstroud | 2:3015a85eb00a | 124 | led_value = 0; |
jstroud | 2:3015a85eb00a | 125 | onLedDataWritten(&led_value, 1); // force LED's to be in off state |
jstroud | 2:3015a85eb00a | 126 | } |
jstroud | 2:3015a85eb00a | 127 | |
jstroud | 2:3015a85eb00a | 128 | void onDataWritten(const GattWriteCallbackParams *context) |
jstroud | 2:3015a85eb00a | 129 | { |
jstroud | 2:3015a85eb00a | 130 | // was the characteristic being written to nRF51_GATT_CHAR_LED? |
jstroud | 2:3015a85eb00a | 131 | if (context -> handle == |
jstroud | 2:3015a85eb00a | 132 | gatt_characteristics[CHARACTERISTIC_LED] -> getValueHandle()) |
jstroud | 2:3015a85eb00a | 133 | { |
jstroud | 2:3015a85eb00a | 134 | onLedDataWritten(context -> data, context -> len); |
jstroud | 2:3015a85eb00a | 135 | } |
jstroud | 2:3015a85eb00a | 136 | } |
jstroud | 2:3015a85eb00a | 137 | |
jstroud | 2:3015a85eb00a | 138 | void onDisconnection(Gap::Handle_t handle, |
jstroud | 2:3015a85eb00a | 139 | Gap::DisconnectionReason_t disconnectReason) |
jstroud | 2:3015a85eb00a | 140 | { |
jstroud | 2:3015a85eb00a | 141 | INFO_NL(">> disconnected"); |
jstroud | 2:3015a85eb00a | 142 | ble.startAdvertising(); |
jstroud | 2:3015a85eb00a | 143 | INFO_NL(">> device advertising"); |
jstroud | 2:3015a85eb00a | 144 | } |
jstroud | 2:3015a85eb00a | 145 | |
jstroud | 2:3015a85eb00a | 146 | int main() |
jstroud | 2:3015a85eb00a | 147 | { |
jstroud | 2:3015a85eb00a | 148 | #ifdef CONSOLE_LOG |
jstroud | 2:3015a85eb00a | 149 | // wait a second before trying to write something to console |
jstroud | 2:3015a85eb00a | 150 | wait(1); |
jstroud | 2:3015a85eb00a | 151 | #endif |
jstroud | 2:3015a85eb00a | 152 | INFO_NL(">> nRF51-DK start"); |
jstroud | 2:3015a85eb00a | 153 | |
jstroud | 2:3015a85eb00a | 154 | // create our button characteristic (read, notify) |
jstroud | 2:3015a85eb00a | 155 | gatt_characteristics[CHARACTERISTIC_BUTTON] = |
jstroud | 2:3015a85eb00a | 156 | new GattCharacteristic( |
jstroud | 2:3015a85eb00a | 157 | nRF51_GATT_CHAR_BUTTON, |
jstroud | 2:3015a85eb00a | 158 | &gatt_char_value[CHARACTERISTIC_BUTTON], 1, 1, |
jstroud | 2:3015a85eb00a | 159 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | |
jstroud | 2:3015a85eb00a | 160 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY); |
jstroud | 2:3015a85eb00a | 161 | |
jstroud | 2:3015a85eb00a | 162 | // create our LED characteristic (read, write) |
jstroud | 2:3015a85eb00a | 163 | gatt_characteristics[CHARACTERISTIC_LED] = |
jstroud | 2:3015a85eb00a | 164 | new GattCharacteristic( |
jstroud | 2:3015a85eb00a | 165 | nRF51_GATT_CHAR_LED, |
jstroud | 2:3015a85eb00a | 166 | &gatt_char_value[CHARACTERISTIC_LED], 1, 1, |
jstroud | 2:3015a85eb00a | 167 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ | |
jstroud | 2:3015a85eb00a | 168 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | |
jstroud | 2:3015a85eb00a | 169 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE); |
jstroud | 2:3015a85eb00a | 170 | |
jstroud | 2:3015a85eb00a | 171 | // create our service, with both characteristics |
jstroud | 2:3015a85eb00a | 172 | gatt_service = |
jstroud | 2:3015a85eb00a | 173 | new GattService(nRF51_GATT_SERVICE, |
jstroud | 2:3015a85eb00a | 174 | gatt_characteristics, CHARACTERISTIC_COUNT); |
jstroud | 2:3015a85eb00a | 175 | |
jstroud | 2:3015a85eb00a | 176 | // initialize our ble device |
jstroud | 2:3015a85eb00a | 177 | ble.init(); |
jstroud | 2:3015a85eb00a | 178 | ble.setDeviceName((uint8_t *)DEVICE_NAME); |
jstroud | 2:3015a85eb00a | 179 | INFO_NL(">> initialized device '%s'", DEVICE_NAME); |
jstroud | 2:3015a85eb00a | 180 | |
jstroud | 2:3015a85eb00a | 181 | // configure our advertising type, payload and interval |
jstroud | 2:3015a85eb00a | 182 | ble.accumulateAdvertisingPayload( |
jstroud | 2:3015a85eb00a | 183 | GapAdvertisingData::BREDR_NOT_SUPPORTED | |
jstroud | 2:3015a85eb00a | 184 | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
jstroud | 2:3015a85eb00a | 185 | ble.accumulateAdvertisingPayload( |
jstroud | 2:3015a85eb00a | 186 | GapAdvertisingData::COMPLETE_LOCAL_NAME, |
jstroud | 2:3015a85eb00a | 187 | (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
jstroud | 2:3015a85eb00a | 188 | ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
jstroud | 2:3015a85eb00a | 189 | ble.setAdvertisingInterval(160); // 100ms |
jstroud | 2:3015a85eb00a | 190 | INFO_NL(">> configured advertising type, payload and interval"); |
jstroud | 2:3015a85eb00a | 191 | |
jstroud | 2:3015a85eb00a | 192 | // configure our callbacks |
jstroud | 2:3015a85eb00a | 193 | //ble.onDisconnection(onDisconnection); |
jstroud | 2:3015a85eb00a | 194 | ble.onConnection(onConnection); |
jstroud | 2:3015a85eb00a | 195 | ble.onDataWritten(onDataWritten); |
jstroud | 2:3015a85eb00a | 196 | INFO_NL(">> registered for callbacks"); |
jstroud | 2:3015a85eb00a | 197 | |
jstroud | 2:3015a85eb00a | 198 | // add our gatt service with two characteristics |
jstroud | 2:3015a85eb00a | 199 | ble.addService(*gatt_service); |
jstroud | 2:3015a85eb00a | 200 | INFO_NL(">> added GATT service with two characteristics"); |
jstroud | 2:3015a85eb00a | 201 | |
jstroud | 2:3015a85eb00a | 202 | // show some debugging information about service/characteristics |
jstroud | 2:3015a85eb00a | 203 | INFO_UUID(" ", nRF51_GATT_SERVICE); |
jstroud | 2:3015a85eb00a | 204 | INFO_UUID(" :", nRF51_GATT_CHAR_BUTTON); |
jstroud | 2:3015a85eb00a | 205 | INFO_UUID(" :", nRF51_GATT_CHAR_LED); |
jstroud | 2:3015a85eb00a | 206 | |
jstroud | 2:3015a85eb00a | 207 | // start advertising |
jstroud | 2:3015a85eb00a | 208 | ble.startAdvertising(); |
jstroud | 2:3015a85eb00a | 209 | INFO_NL(">> device advertising"); |
jstroud | 2:3015a85eb00a | 210 | |
jstroud | 2:3015a85eb00a | 211 | // start monitoring the buttons and posting new values |
jstroud | 2:3015a85eb00a | 212 | Ticker ticker; |
jstroud | 2:3015a85eb00a | 213 | ticker.attach(monitorButtons, 0.1); // every 10th of a second |
jstroud | 2:3015a85eb00a | 214 | INFO_NL(">> monitoring button state"); |
jstroud | 2:3015a85eb00a | 215 | |
jstroud | 2:3015a85eb00a | 216 | // let the device do its thing |
jstroud | 2:3015a85eb00a | 217 | INFO_NL(">> waiting for events "); |
jstroud | 2:3015a85eb00a | 218 | for (;;) |
jstroud | 2:3015a85eb00a | 219 | { |
jstroud | 2:3015a85eb00a | 220 | ble.waitForEvent(); |
jstroud | 2:3015a85eb00a | 221 | } |
jstroud | 2:3015a85eb00a | 222 | } |
jstroud | 2:3015a85eb00a | 223 | |
jstroud | 2:3015a85eb00a | 224 | //------------------------------------------------------------------------- |