Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: BLE_API mbed nRF51822
Fork of BLE_GATT_Example by
main.cpp@23:708cc5ef2604, 2017-05-31 (annotated)
- Committer:
- AidasL
- Date:
- Wed May 31 22:13:36 2017 +0000
- Revision:
- 23:708cc5ef2604
- Parent:
- 22:406127954d1f
Initial commit;
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| mbedAustin | 0:cd5b6733aeb1 | 1 | #include "mbed.h" |
| andresag | 19:477567297aac | 2 | #include "ble/BLE.h" |
| AidasL | 23:708cc5ef2604 | 3 | #include "sensors.h" |
| mbedAustin | 1:94152e7d8b5c | 4 | |
| AidasL | 23:708cc5ef2604 | 5 | |
| mbedAustin | 1:94152e7d8b5c | 6 | |
| AidasL | 23:708cc5ef2604 | 7 | DigitalOut led(LED1); |
| AidasL | 23:708cc5ef2604 | 8 | uint16_t customServiceUUID = 0xABCD; |
| AidasL | 23:708cc5ef2604 | 9 | uint16_t readCharUUID = 0xABCE; |
| AidasL | 23:708cc5ef2604 | 10 | uint16_t writeCharUUID = 0xABCF; |
| AidasL | 23:708cc5ef2604 | 11 | |
| AidasL | 23:708cc5ef2604 | 12 | static volatile bool triggerSensorPolling = false; |
| AidasL | 23:708cc5ef2604 | 13 | |
| AidasL | 23:708cc5ef2604 | 14 | |
| AidasL | 23:708cc5ef2604 | 15 | const static char DEVICE_NAME[] = "WorkGloves"; // change this |
| mbedAustin | 8:60ede963dfe2 | 16 | static const uint16_t uuid16_list[] = {0xFFFF}; //Custom UUID, FFFF is reserved for development |
| mbedAustin | 1:94152e7d8b5c | 17 | |
| andresag | 22:406127954d1f | 18 | /* Set Up custom Characteristics */ |
| AidasL | 23:708cc5ef2604 | 19 | static uint16_t readValue[24] = {0x55, 0x33}; |
| AidasL | 23:708cc5ef2604 | 20 | ReadOnlyArrayGattCharacteristic<uint16_t, sizeof(readValue)> readChar(readCharUUID, readValue); |
| mbedAustin | 2:e84c13abc479 | 21 | |
| AidasL | 23:708cc5ef2604 | 22 | static uint8_t writeValue[8] = {0x00}; |
| mbedAustin | 12:6d1f77d0cb37 | 23 | WriteOnlyArrayGattCharacteristic<uint8_t, sizeof(writeValue)> writeChar(writeCharUUID, writeValue); |
| mbedAustin | 2:e84c13abc479 | 24 | |
| AidasL | 23:708cc5ef2604 | 25 | |
| andresag | 22:406127954d1f | 26 | /* Set up custom service */ |
| mbedAustin | 8:60ede963dfe2 | 27 | GattCharacteristic *characteristics[] = {&readChar, &writeChar}; |
| AidasL | 23:708cc5ef2604 | 28 | GattService customService(customServiceUUID, characteristics, sizeof(characteristics) / sizeof(GattCharacteristic *)); |
| AidasL | 23:708cc5ef2604 | 29 | |
| AidasL | 23:708cc5ef2604 | 30 | void dump(Datapacket todump) |
| AidasL | 23:708cc5ef2604 | 31 | { |
| AidasL | 23:708cc5ef2604 | 32 | uint8_t j; |
| AidasL | 23:708cc5ef2604 | 33 | for (j=0; j<12; j++) |
| AidasL | 23:708cc5ef2604 | 34 | { |
| AidasL | 23:708cc5ef2604 | 35 | readValue[j]=todump.flex[j]; |
| AidasL | 23:708cc5ef2604 | 36 | } |
| AidasL | 23:708cc5ef2604 | 37 | for(j=12; j<18; j++) |
| AidasL | 23:708cc5ef2604 | 38 | { |
| AidasL | 23:708cc5ef2604 | 39 | readValue[j]=todump.acc[0][j%6]; |
| AidasL | 23:708cc5ef2604 | 40 | } |
| AidasL | 23:708cc5ef2604 | 41 | |
| AidasL | 23:708cc5ef2604 | 42 | for(j=18; j<24; j++) |
| AidasL | 23:708cc5ef2604 | 43 | { |
| AidasL | 23:708cc5ef2604 | 44 | readValue[j]=todump.acc[1][j%6]; |
| AidasL | 23:708cc5ef2604 | 45 | } |
| AidasL | 23:708cc5ef2604 | 46 | |
| AidasL | 23:708cc5ef2604 | 47 | |
| AidasL | 23:708cc5ef2604 | 48 | |
| AidasL | 23:708cc5ef2604 | 49 | } |
| mbedAustin | 2:e84c13abc479 | 50 | |
| mbedAustin | 2:e84c13abc479 | 51 | |
| mbedAustin | 8:60ede963dfe2 | 52 | /* |
| mbedAustin | 8:60ede963dfe2 | 53 | * Restart advertising when phone app disconnects |
| AidasL | 23:708cc5ef2604 | 54 | */ |
| andresag | 19:477567297aac | 55 | void disconnectionCallback(const Gap::DisconnectionCallbackParams_t *) |
| mbedAustin | 1:94152e7d8b5c | 56 | { |
| AidasL | 23:708cc5ef2604 | 57 | BLE::Instance(BLE::DEFAULT_INSTANCE).gap().startAdvertising(); |
| AidasL | 23:708cc5ef2604 | 58 | } |
| AidasL | 23:708cc5ef2604 | 59 | |
| AidasL | 23:708cc5ef2604 | 60 | void periodicCallback(void) |
| AidasL | 23:708cc5ef2604 | 61 | { |
| AidasL | 23:708cc5ef2604 | 62 | led = !led; /* Do blinky on LED1 while we're waiting for BLE events */ |
| AidasL | 23:708cc5ef2604 | 63 | |
| AidasL | 23:708cc5ef2604 | 64 | /* Note that the periodicCallback() executes in interrupt context, so it is safer to do |
| AidasL | 23:708cc5ef2604 | 65 | * heavy-weight sensor polling from the main thread. */ |
| AidasL | 23:708cc5ef2604 | 66 | triggerSensorPolling = true; |
| mbedAustin | 1:94152e7d8b5c | 67 | } |
| mbedAustin | 0:cd5b6733aeb1 | 68 | |
| andresag | 19:477567297aac | 69 | /* |
| AidasL | 23:708cc5ef2604 | 70 | * Handle writes to writeCharacteristic for screen data from phone |
| AidasL | 23:708cc5ef2604 | 71 | */ |
| melmon | 18:7d89c4fba362 | 72 | void writeCharCallback(const GattWriteCallbackParams *params) |
| mbedAustin | 3:0fb60f81f693 | 73 | { |
| AidasL | 23:708cc5ef2604 | 74 | /* Check to see what characteristic was written, by handle */ |
| AidasL | 23:708cc5ef2604 | 75 | if(params->handle == writeChar.getValueHandle()) { |
| AidasL | 23:708cc5ef2604 | 76 | /* Update the readChar with the value of writeChar */ |
| AidasL | 23:708cc5ef2604 | 77 | // BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(readChar.getValueHandle(), params->data, params->len); |
| mbedAustin | 8:60ede963dfe2 | 78 | } |
| mbedAustin | 3:0fb60f81f693 | 79 | } |
| andresag | 22:406127954d1f | 80 | /* |
| andresag | 22:406127954d1f | 81 | * Initialization callback |
| andresag | 22:406127954d1f | 82 | */ |
| andresag | 22:406127954d1f | 83 | void bleInitComplete(BLE::InitializationCompleteCallbackContext *params) |
| andresag | 22:406127954d1f | 84 | { |
| AidasL | 23:708cc5ef2604 | 85 | BLE &ble = params->ble; |
| AidasL | 23:708cc5ef2604 | 86 | ble_error_t error = params->error; |
| mbedAustin | 0:cd5b6733aeb1 | 87 | |
| AidasL | 23:708cc5ef2604 | 88 | if (error != BLE_ERROR_NONE) { |
| AidasL | 23:708cc5ef2604 | 89 | return; |
| AidasL | 23:708cc5ef2604 | 90 | } |
| AidasL | 23:708cc5ef2604 | 91 | |
| AidasL | 23:708cc5ef2604 | 92 | ble.gap().onDisconnection(disconnectionCallback); |
| AidasL | 23:708cc5ef2604 | 93 | ble.gattServer().onDataWritten(writeCharCallback); // TODO: update to flush screen !!! |
| mbedAustin | 2:e84c13abc479 | 94 | |
| AidasL | 23:708cc5ef2604 | 95 | /* Setup advertising */ |
| AidasL | 23:708cc5ef2604 | 96 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); // BLE only, no classic BT |
| AidasL | 23:708cc5ef2604 | 97 | ble.gap().setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); // advertising type |
| AidasL | 23:708cc5ef2604 | 98 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); // add name |
| AidasL | 23:708cc5ef2604 | 99 | ble.gap().accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t *)uuid16_list, sizeof(uuid16_list)); // UUID's broadcast in advertising packet |
| AidasL | 23:708cc5ef2604 | 100 | ble.gap().setAdvertisingInterval(500); // 500ms. |
| mbedAustin | 2:e84c13abc479 | 101 | |
| AidasL | 23:708cc5ef2604 | 102 | /* Add our custom service */ |
| AidasL | 23:708cc5ef2604 | 103 | ble.addService(customService); |
| mbedAustin | 2:e84c13abc479 | 104 | |
| AidasL | 23:708cc5ef2604 | 105 | /* Start advertising */ |
| AidasL | 23:708cc5ef2604 | 106 | ble.gap().startAdvertising(); |
| andresag | 22:406127954d1f | 107 | } |
| andresag | 19:477567297aac | 108 | |
| andresag | 22:406127954d1f | 109 | /* |
| andresag | 22:406127954d1f | 110 | * Main loop |
| AidasL | 23:708cc5ef2604 | 111 | */ |
| andresag | 22:406127954d1f | 112 | int main(void) |
| andresag | 22:406127954d1f | 113 | { |
| AidasL | 23:708cc5ef2604 | 114 | /* initialize stuff */ |
| AidasL | 23:708cc5ef2604 | 115 | // printf("\n\r********* Starting Main Loop *********\n\r"); |
| AidasL | 23:708cc5ef2604 | 116 | |
| AidasL | 23:708cc5ef2604 | 117 | led = 1; |
| AidasL | 23:708cc5ef2604 | 118 | Ticker ticker; |
| AidasL | 23:708cc5ef2604 | 119 | ticker.attach(periodicCallback, 0.1); // blink LED every 0.5 second |
| AidasL | 23:708cc5ef2604 | 120 | BLE& ble = BLE::Instance(BLE::DEFAULT_INSTANCE); |
| AidasL | 23:708cc5ef2604 | 121 | ble.init(bleInitComplete); |
| andresag | 22:406127954d1f | 122 | |
| AidasL | 23:708cc5ef2604 | 123 | /* SpinWait for initialization to complete. This is necessary because the |
| AidasL | 23:708cc5ef2604 | 124 | * BLE object is used in the main loop below. */ |
| AidasL | 23:708cc5ef2604 | 125 | while (ble.hasInitialized() == false) { /* spin loop */ } |
| AidasL | 23:708cc5ef2604 | 126 | uint16_t data[24] = {0x11, 0x22}; |
| AidasL | 23:708cc5ef2604 | 127 | /* Infinite loop waiting for BLE interrupt events */ |
| AidasL | 23:708cc5ef2604 | 128 | while (1) { |
| AidasL | 23:708cc5ef2604 | 129 | // check for trigger// from periodicCallback() |
| AidasL | 23:708cc5ef2604 | 130 | if (triggerSensorPolling && ble.getGapState().connected) { |
| AidasL | 23:708cc5ef2604 | 131 | triggerSensorPolling = false; |
| AidasL | 23:708cc5ef2604 | 132 | data[1] = data[1]+1; |
| AidasL | 23:708cc5ef2604 | 133 | BLE::Instance(BLE::DEFAULT_INSTANCE).gattServer().write(readChar.getValueHandle(), (uint8_t*)data , 48 ); |
| AidasL | 23:708cc5ef2604 | 134 | |
| AidasL | 23:708cc5ef2604 | 135 | } |
| AidasL | 23:708cc5ef2604 | 136 | else { |
| AidasL | 23:708cc5ef2604 | 137 | ble.waitForEvent(); // low power wait for event |
| AidasL | 23:708cc5ef2604 | 138 | } |
| AidasL | 23:708cc5ef2604 | 139 | } |
| AidasL | 23:708cc5ef2604 | 140 | } |
