This base class is used when defining custom BLE Gatt Clients.
Unless you are implementing a custom GATT client service and characteristic, you normally won't use this base class directly, and would instantiate and call a higher level helper service or characteristic included in the Bluefruit nRF52 API.
Basic Usage
There are normally only threes operations required to use the BLEClientService class:
1.) You need to declare and instantiate the class with an appropriate 16-bit or 128-bit UUID in the constructor:
BLEClientService myService = BLEService(0x1234);
2.) You then need to call the .begin() method on the instance before adding any BLEClientCharacteristics to it (via the BLEClientCharacteristic's respective .begin() function call):
myService.begin();
3) When connected e.g in connect callback, you should call .discover() to discover the service
myService.discover();
BLEUuid uuid; // Constructors BLEClientService(void); BLEClientService(BLEUuid bleuuid); virtual bool begin(void); virtual bool discover (uint16_t conn_handle); bool discovered(void); uint16_t connHandle(void); void setHandleRange(ble_gattc_handle_range_t handle_range); ble_gattc_handle_range_t getHandleRange(void);
Example
The following example declares a HRM (Heart Rate Monitor) service, and assigns some characteristics to it:
/********************************************************************* This is an example for our nRF52 based Bluefruit LE modules Pick one up today in the adafruit shop! Adafruit invests time and resources providing this open source code, please support Adafruit and open-source hardware by purchasing products from Adafruit! MIT license, check LICENSE for more information All text above, and the splash screen below must be included in any redistribution *********************************************************************/ /* This sketch show how to use BLEClientService and BLEClientCharacteristic * to implement a custom client that is used to talk with Gatt server on * peripheral. * * Note: you will need another feather52 running peripheral/custom_HRM sketch * to test with. */ #include <bluefruit.h> /* HRM Service Definitions * Heart Rate Monitor Service: 0x180D * Heart Rate Measurement Char: 0x2A37 (Mandatory) * Body Sensor Location Char: 0x2A38 (Optional) */ BLEClientService hrms(UUID16_SVC_HEART_RATE); BLEClientCharacteristic hrmc(UUID16_CHR_HEART_RATE_MEASUREMENT); BLEClientCharacteristic bslc(UUID16_CHR_BODY_SENSOR_LOCATION); void setup() { Serial.begin(115200); Serial.println("Bluefruit52 Central Custom HRM Example"); Serial.println("--------------------------------------\n"); // Initialize Bluefruit with maximum connections as Peripheral = 0, Central = 1 // SRAM usage required by SoftDevice will increase dramatically with number of connections Bluefruit.begin(0, 1); Bluefruit.setName("Bluefruit52 Central"); // Initialize HRM client hrms.begin(); // Initialize client characteristics of HRM. // Note: Client Char will be added to the last service that is begin()ed. bslc.begin(); // set up callback for receiving measurement hrmc.setNotifyCallback(hrm_notify_callback); hrmc.begin(); // Increase Blink rate to different from PrPh advertising mode Bluefruit.setConnLedInterval(250); // Callbacks for Central Bluefruit.Central.setDisconnectCallback(disconnect_callback); Bluefruit.Central.setConnectCallback(connect_callback); /* Start Central Scanning * - Enable auto scan if disconnected * - Interval = 100 ms, window = 80 ms * - Don't use active scan * - Filter only accept HRM service * - Start(timeout) with timeout = 0 will scan forever (until connected) */ Bluefruit.Scanner.setRxCallback(scan_callback); Bluefruit.Scanner.restartOnDisconnect(true); Bluefruit.Scanner.setInterval(160, 80); // in unit of 0.625 ms Bluefruit.Scanner.filterUuid(hrms.uuid); Bluefruit.Scanner.useActiveScan(false); Bluefruit.Scanner.start(0); // // 0 = Don't stop scanning after n seconds } void loop() { // do nothing } /** * Callback invoked when scanner pick up an advertising data * @param report Structural advertising data */ void scan_callback(ble_gap_evt_adv_report_t* report) { // Connect to device with HRM service in advertising Bluefruit.Central.connect(report); } /** * Callback invoked when an connection is established * @param conn_handle */ void connect_callback(uint16_t conn_handle) { Serial.println("Connected"); Serial.print("Discovering HRM Service ... "); // If HRM is not found, disconnect and return if ( !hrms.discover(conn_handle) ) { Serial.println("Found NONE"); // disconect since we couldn't find HRM service Bluefruit.Central.disconnect(conn_handle); return; } // Once HRM service is found, we continue to discover its characteristic Serial.println("Found it"); Serial.print("Discovering Measurement characteristic ... "); if ( !hrmc.discover() ) { // Measurement chr is mandatory, if it is not found (valid), then disconnect Serial.println("not found !!!"); Serial.println("Measurement characteristic is mandatory but not found"); Bluefruit.Central.disconnect(conn_handle); return; } Serial.println("Found it"); // Measurement is found, continue to look for option Body Sensor Location // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.body_sensor_location.xml // Body Sensor Location is optional, print out the location in text if present Serial.print("Discovering Body Sensor Location characteristic ... "); if ( bslc.discover() ) { Serial.println("Found it"); // Body sensor location value is 8 bit const char* body_str[] = { "Other", "Chest", "Wrist", "Finger", "Hand", "Ear Lobe", "Foot" }; // Read 8-bit BSLC value from peripheral uint8_t loc_value = bslc.read8(); Serial.print("Body Location Sensor: "); Serial.println(body_str[loc_value]); }else { Serial.println("Found NONE"); } // Reaching here means we are ready to go, let's enable notification on measurement chr if ( hrmc.enableNotify() ) { Serial.println("Ready to receive HRM Measurement value"); }else { Serial.println("Couldn't enable notify for HRM Measurement. Increase DEBUG LEVEL for troubleshooting"); } } /** * Callback invoked when a connection is dropped * @param conn_handle * @param reason */ void disconnect_callback(uint16_t conn_handle, uint8_t reason) { (void) conn_handle; (void) reason; Serial.println("Disconnected"); } /** * Hooked callback that triggered when a measurement value is sent from peripheral * @param chr Pointer client characteristic that even occurred, * in this example it should be hrmc * @param data Pointer to received data * @param len Length of received data */ void hrm_notify_callback(BLEClientCharacteristic* chr, uint8_t* data, uint16_t len) { // https://www.bluetooth.com/specifications/gatt/viewer?attributeXmlFile=org.bluetooth.characteristic.heart_rate_measurement.xml // Measurement contains of control byte0 and measurement (8 or 16 bit) + optional field // if byte0's bit0 is 0 --> measurement is 8 bit, otherwise 16 bit. Serial.print("HRM Measurement: "); if ( data[0] & bit(0) ) { uint16_t value; memcpy(&value, data+1, 2); Serial.println(value); } else { Serial.println(data[1]); } }
Text editor powered by tinymce.