ble
Dependencies: HC_SR04_Ultrasonic_Library Servo mbed
Fork of FIP_REV1 by
main.cpp@0:3d641e170a74, 2015-05-19 (annotated)
- Committer:
- julientiron
- Date:
- Tue May 19 16:43:59 2015 +0000
- Revision:
- 0:3d641e170a74
- Child:
- 2:b5166e24c7a6
BLE;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
julientiron | 0:3d641e170a74 | 1 | #include "mbed.h" |
julientiron | 0:3d641e170a74 | 2 | |
julientiron | 0:3d641e170a74 | 3 | DigitalOut myled(LED1); |
julientiron | 0:3d641e170a74 | 4 | |
julientiron | 0:3d641e170a74 | 5 | #include "debug.h" |
julientiron | 0:3d641e170a74 | 6 | #include "btle.h" |
julientiron | 0:3d641e170a74 | 7 | //#include "BlueNRGDevice.h"//User does not use any platform specific header file |
julientiron | 0:3d641e170a74 | 8 | #include "BLEDevice.h" |
julientiron | 0:3d641e170a74 | 9 | #include "UUID.h" |
julientiron | 0:3d641e170a74 | 10 | #include "Utils.h" |
julientiron | 0:3d641e170a74 | 11 | |
julientiron | 0:3d641e170a74 | 12 | BLEDevice dev; |
julientiron | 0:3d641e170a74 | 13 | |
julientiron | 0:3d641e170a74 | 14 | const static char DEVICE_NAME[] = "Proximity Sensor"; |
julientiron | 0:3d641e170a74 | 15 | const uint8_t device_address[6] = { 0xaa, 0x00, 0x00, 0xE1, 0x80, 0x03 }; //Peripheral address |
julientiron | 0:3d641e170a74 | 16 | |
julientiron | 0:3d641e170a74 | 17 | void Append128bitUUID(uint8_t *uuid128_list, const LongUUID_t HRM_SERVICE_UUID_128); |
julientiron | 0:3d641e170a74 | 18 | void print_array(uint8_t *array); |
julientiron | 0:3d641e170a74 | 19 | |
julientiron | 0:3d641e170a74 | 20 | /*********128 bit UUIDs. Not defined in GattCharacteristic.h and GattService.h*************/ |
julientiron | 0:3d641e170a74 | 21 | |
julientiron | 0:3d641e170a74 | 22 | InterruptIn event_button(USER_BUTTON); |
julientiron | 0:3d641e170a74 | 23 | volatile bool go_to_sleep = true; |
julientiron | 0:3d641e170a74 | 24 | |
julientiron | 0:3d641e170a74 | 25 | #define MAX_SERVICES_NOS 1 |
julientiron | 0:3d641e170a74 | 26 | //typedef uint8_t UUID_128_BIT[16]; |
julientiron | 0:3d641e170a74 | 27 | const LongUUID_t HEART_RATE_CHAR_UUID_128 = {0x42,0x82,0x1a,0x40, 0xe4,0x77, 0x11,0xe2, 0x82,0xd0, 0x00,0x02,0xa5,0xd5,0xc5,0x1a}; |
julientiron | 0:3d641e170a74 | 28 | const LongUUID_t HRM_SERVICE_UUID_128 = {0x42,0x82,0x1a,0x40, 0xe4,0x77, 0x11,0xe2, 0x82,0xd0, 0x00,0x02,0xa5,0xd5,0xc5,0x1b}; |
julientiron | 0:3d641e170a74 | 29 | |
julientiron | 0:3d641e170a74 | 30 | uint8_t UUID_Count=0; |
julientiron | 0:3d641e170a74 | 31 | |
julientiron | 0:3d641e170a74 | 32 | static uint8_t hrmCounter = 100; |
julientiron | 0:3d641e170a74 | 33 | static uint8_t bpm[2] = {0x00, hrmCounter}; |
julientiron | 0:3d641e170a74 | 34 | static uint8_t hcpCounter = 99; |
julientiron | 0:3d641e170a74 | 35 | static uint8_t hcp[2] = {0x00, hrmCounter}; |
julientiron | 0:3d641e170a74 | 36 | |
julientiron | 0:3d641e170a74 | 37 | GattCharacteristic hrmRate(GattCharacteristic::UUID_HEART_RATE_MEASUREMENT_CHAR, bpm, sizeof(bpm), sizeof(bpm), |
julientiron | 0:3d641e170a74 | 38 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ |
julientiron | 0:3d641e170a74 | 39 | /*GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_INDICATE*/); |
julientiron | 0:3d641e170a74 | 40 | |
julientiron | 0:3d641e170a74 | 41 | GattCharacteristic hcpControlPoint(GattCharacteristic::UUID_HEART_RATE_CONTROL_POINT_CHAR, hcp, sizeof(hcp), sizeof(hcp), |
julientiron | 0:3d641e170a74 | 42 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE| |
julientiron | 0:3d641e170a74 | 43 | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE|GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_READ); |
julientiron | 0:3d641e170a74 | 44 | |
julientiron | 0:3d641e170a74 | 45 | GattCharacteristic *hrmChars[] = {&hrmRate, &hcpControlPoint }; |
julientiron | 0:3d641e170a74 | 46 | UUID HRMSERVICE(GattService::UUID_HEART_RATE_SERVICE); |
julientiron | 0:3d641e170a74 | 47 | GattService hrmService(HRMSERVICE/*GattService::UUID_HEART_RATE_SERVICE*/, hrmChars, sizeof(hrmChars) / sizeof(GattCharacteristic *)); |
julientiron | 0:3d641e170a74 | 48 | |
julientiron | 0:3d641e170a74 | 49 | uint8_t uuid128_list[16*MAX_SERVICES_NOS];// = {HRM_SERVICE_UUID_128[0], HRM_SERVICE_UUID_128[1]}; |
julientiron | 0:3d641e170a74 | 50 | static const uint16_t uuid16_list[] = {GattService::UUID_HEART_RATE_SERVICE}; |
julientiron | 0:3d641e170a74 | 51 | |
julientiron | 0:3d641e170a74 | 52 | void ISR_pressed() // ISR for the button press |
julientiron | 0:3d641e170a74 | 53 | { |
julientiron | 0:3d641e170a74 | 54 | printf("Button pressed\n"); // Show that the button has pressed |
julientiron | 0:3d641e170a74 | 55 | go_to_sleep = !go_to_sleep; // Toogle the sleep state |
julientiron | 0:3d641e170a74 | 56 | event_button.disable_irq(); // Disable the interrupt request |
julientiron | 0:3d641e170a74 | 57 | } |
julientiron | 0:3d641e170a74 | 58 | |
julientiron | 0:3d641e170a74 | 59 | void disconnectionCallback(uint16_t Handle_t) |
julientiron | 0:3d641e170a74 | 60 | { |
julientiron | 0:3d641e170a74 | 61 | DEBUG("Disconnected!\n\r"); |
julientiron | 0:3d641e170a74 | 62 | DEBUG("Restarting the advertising process\n\r"); |
julientiron | 0:3d641e170a74 | 63 | dev.startAdvertising(); |
julientiron | 0:3d641e170a74 | 64 | } |
julientiron | 0:3d641e170a74 | 65 | |
julientiron | 0:3d641e170a74 | 66 | void onWriteCallback(uint16_t attributeHandle) { |
julientiron | 0:3d641e170a74 | 67 | DEBUG("Write Callback!!\n\r"); |
julientiron | 0:3d641e170a74 | 68 | } |
julientiron | 0:3d641e170a74 | 69 | |
julientiron | 0:3d641e170a74 | 70 | void onConnectionCallback(uint16_t Handle_t) { |
julientiron | 0:3d641e170a74 | 71 | //myled = 1; // LED is ON |
julientiron | 0:3d641e170a74 | 72 | DEBUG("Connected BlueNRG!!\n\r"); |
julientiron | 0:3d641e170a74 | 73 | } |
julientiron | 0:3d641e170a74 | 74 | |
julientiron | 0:3d641e170a74 | 75 | |
julientiron | 0:3d641e170a74 | 76 | void onNotifyEnabled(uint16_t charHandle) { |
julientiron | 0:3d641e170a74 | 77 | //myled = 1; // LED is ON |
julientiron | 0:3d641e170a74 | 78 | DEBUG("onNotifyEnabled!!\n\r"); |
julientiron | 0:3d641e170a74 | 79 | } |
julientiron | 0:3d641e170a74 | 80 | |
julientiron | 0:3d641e170a74 | 81 | void onNotifyDisabled(uint16_t charHandle) { |
julientiron | 0:3d641e170a74 | 82 | //myled = 1; // LED is ON |
julientiron | 0:3d641e170a74 | 83 | DEBUG("onNotifyDisabled!!\n\r"); |
julientiron | 0:3d641e170a74 | 84 | } |
julientiron | 0:3d641e170a74 | 85 | |
julientiron | 0:3d641e170a74 | 86 | void onDataSentNotify() { |
julientiron | 0:3d641e170a74 | 87 | //myled = 1; // LED is ON |
julientiron | 0:3d641e170a74 | 88 | DEBUG("on Data Sent Notify!!\n\r"); |
julientiron | 0:3d641e170a74 | 89 | } |
julientiron | 0:3d641e170a74 | 90 | |
julientiron | 0:3d641e170a74 | 91 | void Append128bitUUID(uint8_t *array, const LongUUID_t SERVICE_UUID_128) |
julientiron | 0:3d641e170a74 | 92 | { |
julientiron | 0:3d641e170a74 | 93 | for(int x=0;x<16; x++) |
julientiron | 0:3d641e170a74 | 94 | { |
julientiron | 0:3d641e170a74 | 95 | array[x+UUID_Count*16]=SERVICE_UUID_128[x]; |
julientiron | 0:3d641e170a74 | 96 | } |
julientiron | 0:3d641e170a74 | 97 | UUID_Count++; |
julientiron | 0:3d641e170a74 | 98 | return; |
julientiron | 0:3d641e170a74 | 99 | } |
julientiron | 0:3d641e170a74 | 100 | |
julientiron | 0:3d641e170a74 | 101 | /** |
julientiron | 0:3d641e170a74 | 102 | * Triggered periodically by the 'ticker' interrupt; updates hrmCounter. |
julientiron | 0:3d641e170a74 | 103 | */ |
julientiron | 0:3d641e170a74 | 104 | void periodicCallback(void) |
julientiron | 0:3d641e170a74 | 105 | { |
julientiron | 0:3d641e170a74 | 106 | //myled = !myled; /* Do blinky on LED1 while we're waiting for BLE events */ |
julientiron | 0:3d641e170a74 | 107 | |
julientiron | 0:3d641e170a74 | 108 | if (dev.getGapState().connected) { |
julientiron | 0:3d641e170a74 | 109 | hrmCounter = rand()%(200-100) +100; |
julientiron | 0:3d641e170a74 | 110 | bpm[1] = hrmCounter; |
julientiron | 0:3d641e170a74 | 111 | uint16_t t = sizeof(bpm); |
julientiron | 0:3d641e170a74 | 112 | //DEBUG("Char Handle 0x%x OK.",hrmRate.getHandle()); |
julientiron | 0:3d641e170a74 | 113 | //dev.readCharacteristicValue(hrmRate.getHandle(), bpm, (uint16_t *const)t); |
julientiron | 0:3d641e170a74 | 114 | dev.updateCharacteristicValue(hrmRate.getHandle(), bpm, sizeof(bpm)); |
julientiron | 0:3d641e170a74 | 115 | //DEBUG("Ticker CB..\n\r"); |
julientiron | 0:3d641e170a74 | 116 | } //else DEBUG("Not Connected..\n\r"); |
julientiron | 0:3d641e170a74 | 117 | else //if not connected |
julientiron | 0:3d641e170a74 | 118 | { |
julientiron | 0:3d641e170a74 | 119 | hrmCounter = rand()%(200-100) +100; |
julientiron | 0:3d641e170a74 | 120 | } |
julientiron | 0:3d641e170a74 | 121 | } |
julientiron | 0:3d641e170a74 | 122 | |
julientiron | 0:3d641e170a74 | 123 | int main() { |
julientiron | 0:3d641e170a74 | 124 | |
julientiron | 0:3d641e170a74 | 125 | Ticker ticker; //For Tick interrupt if used later on (periodic data updates?) |
julientiron | 0:3d641e170a74 | 126 | event_button.mode(PullUp); // Setup the internall pull-up resistor |
julientiron | 0:3d641e170a74 | 127 | event_button.fall(&ISR_pressed); // Set the ISR associated to event fall (push the button) |
julientiron | 0:3d641e170a74 | 128 | |
julientiron | 0:3d641e170a74 | 129 | //LongUUID_t HEART_RATE_CHAR_UUID_128, HRM_SERVICE_UUID_128; |
julientiron | 0:3d641e170a74 | 130 | //COPY_HRM_SERVICE_UUID(HRM_SERVICE_UUID_128); |
julientiron | 0:3d641e170a74 | 131 | //COPY_HRM_CHAR_UUID(HEART_RATE_CHAR_UUID_128); |
julientiron | 0:3d641e170a74 | 132 | UUID heart_rate_char_UUID = UUID(HEART_RATE_CHAR_UUID_128); |
julientiron | 0:3d641e170a74 | 133 | UUID hrm_service_UUID = UUID(HRM_SERVICE_UUID_128); |
julientiron | 0:3d641e170a74 | 134 | |
julientiron | 0:3d641e170a74 | 135 | myled = 0;//Switch OFF LED1 |
julientiron | 0:3d641e170a74 | 136 | |
julientiron | 0:3d641e170a74 | 137 | DEBUG("Initializing BlueNRG...\n\r"); |
julientiron | 0:3d641e170a74 | 138 | dev.init(); |
julientiron | 0:3d641e170a74 | 139 | |
julientiron | 0:3d641e170a74 | 140 | dev.onConnection(onConnectionCallback); |
julientiron | 0:3d641e170a74 | 141 | dev.onDisconnection(disconnectionCallback); |
julientiron | 0:3d641e170a74 | 142 | dev.onDataWritten(onWriteCallback); |
julientiron | 0:3d641e170a74 | 143 | dev.onUpdatesEnabled(onNotifyEnabled); |
julientiron | 0:3d641e170a74 | 144 | dev.onDataSent(onDataSentNotify); |
julientiron | 0:3d641e170a74 | 145 | dev.onUpdatesDisabled(onNotifyDisabled); |
julientiron | 0:3d641e170a74 | 146 | |
julientiron | 0:3d641e170a74 | 147 | //TODO. |
julientiron | 0:3d641e170a74 | 148 | dev.setAddress(Gap::ADDR_TYPE_PUBLIC, device_address);//Will reset the device and re-init() |
julientiron | 0:3d641e170a74 | 149 | //TODO. |
julientiron | 0:3d641e170a74 | 150 | |
julientiron | 0:3d641e170a74 | 151 | //Append128bitUUID(uuid128_list, HRM_SERVICE_UUID_128); |
julientiron | 0:3d641e170a74 | 152 | |
julientiron | 0:3d641e170a74 | 153 | /* setup advertising */ |
julientiron | 0:3d641e170a74 | 154 | dev.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED | GapAdvertisingData::LE_GENERAL_DISCOVERABLE); |
julientiron | 0:3d641e170a74 | 155 | |
julientiron | 0:3d641e170a74 | 156 | //TODO:IMP STUFF: 128bit list is basically a uint8_t list. User should know how many services he supports and define the number in MAX_SERVICES_NOS |
julientiron | 0:3d641e170a74 | 157 | dev.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_16BIT_SERVICE_IDS, (uint8_t*)uuid16_list, sizeof(uuid16_list)); |
julientiron | 0:3d641e170a74 | 158 | |
julientiron | 0:3d641e170a74 | 159 | dev.accumulateAdvertisingPayload(GapAdvertisingData::HEART_RATE_SENSOR_HEART_RATE_BELT); |
julientiron | 0:3d641e170a74 | 160 | |
julientiron | 0:3d641e170a74 | 161 | dev.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LOCAL_NAME, (uint8_t *)DEVICE_NAME, sizeof(DEVICE_NAME)); |
julientiron | 0:3d641e170a74 | 162 | dev.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED); |
julientiron | 0:3d641e170a74 | 163 | dev.setAdvertisingInterval(160); /* 100ms; in multiples of 0.625ms. */ |
julientiron | 0:3d641e170a74 | 164 | DEBUG("Starting Advertising...\n\r"); |
julientiron | 0:3d641e170a74 | 165 | dev.startAdvertising(); |
julientiron | 0:3d641e170a74 | 166 | |
julientiron | 0:3d641e170a74 | 167 | dev.addService(hrmService); |
julientiron | 0:3d641e170a74 | 168 | //ticker.attach(periodicCallback, 1); Multi threading and called from ISR context does not work! |
julientiron | 0:3d641e170a74 | 169 | |
julientiron | 0:3d641e170a74 | 170 | while(1) { |
julientiron | 0:3d641e170a74 | 171 | |
julientiron | 0:3d641e170a74 | 172 | if(go_to_sleep) |
julientiron | 0:3d641e170a74 | 173 | { |
julientiron | 0:3d641e170a74 | 174 | myled = 0; |
julientiron | 0:3d641e170a74 | 175 | event_button.enable_irq(); // Enable the interrupt request |
julientiron | 0:3d641e170a74 | 176 | //sleep(); // Enter Low Power Mode |
julientiron | 0:3d641e170a74 | 177 | deepsleep(); // Enter Low Power Mode (deep) |
julientiron | 0:3d641e170a74 | 178 | wait_ms(200); // Wait 200ms for debounce |
julientiron | 0:3d641e170a74 | 179 | event_button.enable_irq(); // Enable the interrupt request |
julientiron | 0:3d641e170a74 | 180 | } |
julientiron | 0:3d641e170a74 | 181 | else |
julientiron | 0:3d641e170a74 | 182 | { |
julientiron | 0:3d641e170a74 | 183 | myled = 1; |
julientiron | 0:3d641e170a74 | 184 | wait(1); |
julientiron | 0:3d641e170a74 | 185 | //DEBUG("tic!\n\r"); |
julientiron | 0:3d641e170a74 | 186 | periodicCallback();//Works from here!! |
julientiron | 0:3d641e170a74 | 187 | |
julientiron | 0:3d641e170a74 | 188 | dev.waitForEvent(); |
julientiron | 0:3d641e170a74 | 189 | } |
julientiron | 0:3d641e170a74 | 190 | } |
julientiron | 0:3d641e170a74 | 191 | } |