2021-08-05 01:02:30 +00:00
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
2024-12-15 00:45:58 +00:00
< html xmlns = "http://www.w3.org/1999/xhtml" lang = "en-US" >
2021-08-05 01:02:30 +00:00
< head >
< meta http-equiv = "Content-Type" content = "text/xhtml;charset=UTF-8" / >
2024-12-15 00:45:58 +00:00
< meta http-equiv = "X-UA-Compatible" content = "IE=11" / >
< meta name = "generator" content = "Doxygen 1.9.8" / >
2021-08-05 01:02:30 +00:00
< meta name = "viewport" content = "width=device-width, initial-scale=1" / >
2022-01-15 15:23:57 -07:00
< title > esp-nimble-cpp: New User Guide< / title >
2021-08-05 01:02:30 +00:00
< link href = "tabs.css" rel = "stylesheet" type = "text/css" / >
< script type = "text/javascript" src = "jquery.js" > < / script >
< script type = "text/javascript" src = "dynsections.js" > < / script >
< link href = "navtree.css" rel = "stylesheet" type = "text/css" / >
< script type = "text/javascript" src = "resize.js" > < / script >
< script type = "text/javascript" src = "navtreedata.js" > < / script >
< script type = "text/javascript" src = "navtree.js" > < / script >
< link href = "search/search.css" rel = "stylesheet" type = "text/css" / >
< script type = "text/javascript" src = "search/searchdata.js" > < / script >
< script type = "text/javascript" src = "search/search.js" > < / script >
< link href = "doxygen.css" rel = "stylesheet" type = "text/css" / >
< / head >
< body >
< div id = "top" > <!-- do not remove this div, it is closed by doxygen! -->
< div id = "titlearea" >
< table cellspacing = "0" cellpadding = "0" >
< tbody >
2024-12-15 00:45:58 +00:00
< tr id = "projectrow" >
< td id = "projectalign" >
2025-09-05 22:13:32 +00:00
< div id = "projectname" > esp-nimble-cpp< span id = "projectnumber" >   2.3.3< / span >
2021-08-05 01:02:30 +00:00
< / div >
< / td >
< / tr >
< / tbody >
< / table >
< / div >
<!-- end header part -->
2024-12-15 00:45:58 +00:00
<!-- Generated by Doxygen 1.9.8 -->
2021-08-05 01:02:30 +00:00
< script type = "text/javascript" >
2024-12-15 00:45:58 +00:00
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699& dn=expat.txt MIT */
var searchBox = new SearchBox("searchBox", "search/",'.html');
2021-08-05 01:02:30 +00:00
/* @license-end */
< / script >
< script type = "text/javascript" src = "menudata.js" > < / script >
< script type = "text/javascript" src = "menu.js" > < / script >
< script type = "text/javascript" >
2024-12-15 00:45:58 +00:00
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699& dn=expat.txt MIT */
2021-08-05 01:02:30 +00:00
$(function() {
initMenu('',true,false,'search.php','Search');
$(document).ready(function() { init_search(); });
});
2024-12-15 00:45:58 +00:00
/* @license-end */
< / script >
2021-08-05 01:02:30 +00:00
< div id = "main-nav" > < / div >
< / div > <!-- top -->
< div id = "side-nav" class = "ui-resizable side-nav-resizable" >
< div id = "nav-tree" >
< div id = "nav-tree-contents" >
< div id = "nav-sync" class = "sync" > < / div >
< / div >
< / div >
< div id = "splitbar" style = "-moz-user-select:none;"
class="ui-resizable-handle">
< / div >
< / div >
< script type = "text/javascript" >
2024-12-15 00:45:58 +00:00
/* @license magnet:?xt=urn:btih:d3d9a9a6595521f9666a5e94cc830dab83b65699& dn=expat.txt MIT */
$(document).ready(function(){initNavTree('md__new__user__guide.html',''); initResizable(); });
2021-08-05 01:02:30 +00:00
/* @license-end */
< / script >
< div id = "doc-content" >
<!-- window showing the filter options -->
< div id = "MSearchSelectWindow"
onmouseover="return searchBox.OnSearchSelectShow()"
onmouseout="return searchBox.OnSearchSelectHide()"
onkeydown="return searchBox.OnSearchSelectKey(event)">
< / div >
<!-- iframe showing the search results (closed by default) -->
< div id = "MSearchResultsWindow" >
2024-12-15 00:45:58 +00:00
< div id = "MSearchResults" >
< div class = "SRPage" >
< div id = "SRIndex" >
< div id = "SRResults" > < / div >
< div class = "SRStatus" id = "Loading" > Loading...< / div >
< div class = "SRStatus" id = "Searching" > Searching...< / div >
< div class = "SRStatus" id = "NoMatches" > No Matches< / div >
< / div >
< / div >
< / div >
2021-08-05 01:02:30 +00:00
< / div >
2024-12-15 00:45:58 +00:00
< div > < div class = "header" >
< div class = "headertitle" > < div class = "title" > New User Guide< / div > < / div >
2021-08-05 01:02:30 +00:00
< / div > <!-- header -->
< div class = "contents" >
2024-12-15 00:45:58 +00:00
< div class = "textblock" > < p > < a class = "anchor" id = "new-user-guide" > < / a > < b > Note:< / b > If you are migrating an existing project from the original Bluedroid library please see the < a class = "el" href = "md__migration__guide.html" > Migration Guide.< / a > < br / >
2021-08-05 01:02:30 +00:00
< / p >
< p > If you are a new user this will guide you through a simple server and client application. < br / >
< / p >
< ul >
2024-12-15 00:45:58 +00:00
< li > < a class = "el" href = "md__new__user__guide.html#creating-a-server" > Creating a Server< / a > < / li >
< li > < a class = "el" href = "md__new__user__guide.html#creating-a-client" > Creating a Client< / a > < br / >
2021-08-05 01:02:30 +00:00
< br / >
< / li >
< / ul >
2024-12-15 00:45:58 +00:00
< h1 > < a class = "anchor" id = "include-files" > < / a >
2021-08-05 01:02:30 +00:00
Include Files< / h1 >
< p > At the top of your application file add < code > #include < a class = "el" href = "_nim_b_l_e_device_8h_source.html" > NimBLEDevice.h< / a > < / code > , this is the only header required and provides access to all classes. < br / >
< br / >
< / p >
2024-12-15 00:45:58 +00:00
< h1 > < a class = "anchor" id = "using-the-library" > < / a >
2021-08-05 01:02:30 +00:00
Using the Library< / h1 >
< p > In order to perform any BLE tasks you must first initialize the library, this prepares the NimBLE stack to be ready for commands. < br / >
< / p >
2024-12-15 00:45:58 +00:00
< p > To do this you must call < code > < a class = "el" href = "class_nim_b_l_e_device.html#a2e8bb71daabbffd9eab8787493a45ce7" title = "Initialize the BLE environment." > NimBLEDevice::init< / a > ("your device name here")< / code > , the parameter passed is a character string containing the name you want to advertise. < br / >
2021-08-05 01:02:30 +00:00
If you're not creating a server or do not want to advertise a name, simply pass an empty string for the parameter. < br / >
< / p >
< p > This can be called any time you wish to use BLE functions and does not need to be called from app_main(IDF) or setup(Arduino) but usually is. < br / >
< br / >
< / p >
2024-12-15 00:45:58 +00:00
< h1 > < a class = "anchor" id = "creating-a-server" > < / a >
2021-08-05 01:02:30 +00:00
Creating a Server< / h1 >
2022-07-31 11:38:16 -06:00
< p > BLE servers perform 2 tasks, they advertise their existence for clients to find them and they provide services which contain information for the connecting client. < br / >
2021-08-05 01:02:30 +00:00
< / p >
2025-09-02 20:57:38 +00:00
< p > After initializing the NimBLE stack we create a server by calling < code > NimBLEDevice::createServer()< / code > , this will create a server instance and return a pointer to it. < br / >
2021-08-05 01:02:30 +00:00
< / p >
< p > Once we have created the server we need to tell it the services it hosts. < br / >
2025-09-02 20:57:38 +00:00
To do this we call < code > NimBLEServer::createService(const char* uuid)< / code > . Which returns a pointer to an instance of < code > NimBLEService< / code > . < br / >
2021-08-05 01:02:30 +00:00
The < code > uuid< / code > parameter is a hexadecimal string with the uuid we want to give the service, it can be 16, 32, or 128 bits. < br / >
< / p >
< p > For this example we will keep it simple and use a 16 bit value: ABCD. < br / >
< br / >
< / p >
< p > < b > Example code:< / b > < br / >
< / p > < div class = "fragment" > < div class = "line" > #include " NimBLEDevice.h" < / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > extern " C" void app_main(void) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEDevice::init(" NimBLE" );< / div >
< div class = "line" > < / div >
< div class = "line" > NimBLEServer *pServer = NimBLEDevice::createServer();< / div >
< div class = "line" > NimBLEService *pService = pServer-> createService(" ABCD" );< / div >
< div class = "line" > }< / div >
< / div > <!-- fragment --> < p > Now we have NimBLE initialized, a server created and a service assigned to it. < br / >
We can't do much with this yet so now we should add a characteristic to the service to provide some data. < br / >
< / p >
2025-09-02 20:57:38 +00:00
< p > Next we call < code > NimBLEService::createCharacteristic< / code > which returns a pointer to an instance of < code > NimBLECharacteristic< / code > , and takes two parameters: A < code > uuid< / code > to specify the UUID of the characteristic and a bitmask of the properties we want applied to it. < br / >
2021-08-05 01:02:30 +00:00
< / p >
< p > Just as with the service UUID we will use a simple 16 bit value: 1234. < br / >
The properties bitmask is a little more involved. It is a combination of NIMBLE_PROPERTY:: values. < br / >
< / p >
< p > Here is the list of options: < br / >
< / p > < blockquote class = "doxtable" >
2024-12-15 00:45:58 +00:00
< p > ‍ NIMBLE_PROPERTY::READ < br / >
2021-08-05 01:02:30 +00:00
NIMBLE_PROPERTY::READ_ENC < br / >
NIMBLE_PROPERTY::READ_AUTHEN < br / >
NIMBLE_PROPERTY::READ_AUTHOR < br / >
NIMBLE_PROPERTY::WRITE < br / >
NIMBLE_PROPERTY::WRITE_NR < br / >
NIMBLE_PROPERTY::WRITE_ENC < br / >
NIMBLE_PROPERTY::WRITE_AUTHEN < br / >
NIMBLE_PROPERTY::WRITE_AUTHOR < br / >
NIMBLE_PROPERTY::BROADCAST < br / >
NIMBLE_PROPERTY::NOTIFY < br / >
NIMBLE_PROPERTY::INDICATE < br / >
< / p >
< / blockquote >
< p > For this example we won't need to specify these as the default value is < code > NIMBLE_PROPERTY::READ | NIMBLE_PROPERTY::WRITE< / code > < br / >
which will allow reading and writing values to the characteristic without encryption or security. < br / >
The function call will simply be < code > pService-> createCharacteristic("1234");< / code > < br / >
< br / >
< / p >
< p > < b > Our example code now is:< / b > < br / >
< / p > < div class = "fragment" > < div class = "line" > #include " NimBLEDevice.h" < / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > extern " C" void app_main(void) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEDevice::init(" NimBLE" );< / div >
< div class = "line" > < / div >
< div class = "line" > NimBLEServer *pServer = NimBLEDevice::createServer();< / div >
< div class = "line" > NimBLEService *pService = pServer-> createService(" ABCD" );< / div >
< div class = "line" > NimBLECharacteristic *pCharacteristic = pService-> createCharacteristic(" 1234" );< / div >
< div class = "line" > }< / div >
2022-07-31 11:38:16 -06:00
< / div > <!-- fragment --> < p > All that's left to do now is start the service, give the characteristic a value and start advertising for clients. < br / >
2021-08-05 01:02:30 +00:00
< / p >
2025-09-02 20:57:38 +00:00
< p > Fist we start the service by calling < code > NimBLEService::start()< / code > .< / p >
2024-12-15 00:45:58 +00:00
< p > Next we need to call < code > NimBLECharacteristic::setValue< / code > to set the characteristic value that the client will read. < br / >
2021-08-05 01:02:30 +00:00
There are many different types you can send as parameters for the value but for this example we will use a simple string. < code > pCharacteristic-> setValue("Hello BLE");< / code > < br / >
< / p >
< p > Next we need to advertise for connections. < br / >
2025-01-13 02:22:00 +00:00
To do this we create an instance of < code > < a class = "el" href = "class_nim_b_l_e_advertising.html" title = "Perform and manage BLE advertising." > NimBLEAdvertising< / a > < / code > add our service to it (optional) and start advertising. < br / >
2021-08-05 01:02:30 +00:00
< / p >
< p > < b > The code for this will be:< / b > < br / >
< / p > < div class = "fragment" > < div class = "line" > NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising(); // create advertising instance< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > pAdvertising-> addServiceUUID(" ABCD" ); // advertise the UUID of our service< / div >
< div class = "line" > pAdvertising-> setName(" NimBLE" ); // advertise the device name< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > pAdvertising-> start(); // start advertising< / div >
< / div > <!-- fragment --> < p > That's it, this will be enough to create a BLE server with a service and a characteristic and advertise for client connections. < br / >
< / p >
< p > < b > The full example code:< / b > < br / >
< / p > < div class = "fragment" > < div class = "line" > #include " NimBLEDevice.h" < / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > extern " C" void app_main(void) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEDevice::init(" NimBLE" );< / div >
< div class = "line" > < / div >
< div class = "line" > NimBLEServer *pServer = NimBLEDevice::createServer();< / div >
< div class = "line" > NimBLEService *pService = pServer-> createService(" ABCD" );< / div >
< div class = "line" > NimBLECharacteristic *pCharacteristic = pService-> createCharacteristic(" 1234" );< / div >
< div class = "line" > < / div >
< div class = "line" > pService-> start();< / div >
< div class = "line" > pCharacteristic-> setValue(" Hello BLE" );< / div >
< div class = "line" > < / div >
< div class = "line" > NimBLEAdvertising *pAdvertising = NimBLEDevice::getAdvertising();< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > pAdvertising-> addServiceUUID(" ABCD" ); // advertise the UUID of our service< / div >
< div class = "line" > pAdvertising-> setName(" NimBLE" ); // advertise the device name< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > pAdvertising-> start(); < / div >
< div class = "line" > }< / div >
< / div > <!-- fragment --> < p > Now if you scan with your phone using nRFConnect or any other BLE app you should see a device named "NimBLE" with a service of "ABCD". < br / >
< / p >
< p > For more advanced features and options please see the server examples in the examples folder. < br / >
< br / >
< / p >
2024-12-15 00:45:58 +00:00
< h1 > < a class = "anchor" id = "creating-a-client" > < / a >
2021-08-05 01:02:30 +00:00
Creating a Client< / h1 >
< p > BLE clients perform 2 tasks, they scan for advertising servers and form connections to them to read and write to their characteristics/descriptors.< / p >
2025-09-02 20:57:38 +00:00
< p > After initializing the NimBLE stack we create a scan instance by calling < code > NimBLEDevice::getScan()< / code > , this will create a < code > NimBLEScan< / code > instance and return a pointer to it. < br / >
2021-08-05 01:02:30 +00:00
< / p >
< p > Once we have created the scan we can start looking for advertising servers. < br / >
< / p >
2025-01-13 02:22:00 +00:00
< p > To do this we call < code > NimBLEScan::getResults(duration)< / code > , the duration parameter is a uint32_t that specifies the number of milliseconds to scan for, < br / >
2021-08-05 01:02:30 +00:00
passing 0 will scan forever. < br / >
< / p >
< p > In this example we will scan for 10 seconds. This is a blocking function (a non blocking overload is also available). < br / >
2025-09-02 20:57:38 +00:00
This call returns an instance of < code > NimBLEScanResults< / code > when the scan completes which can be parsed for advertisers we are interested in. < br / >
2021-08-05 01:02:30 +00:00
< / p >
< p > < b > Example Code:< / b > < br / >
< / p > < div class = "fragment" > < div class = "line" > #include " NimBLEDevice.h" < / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > extern " C" void app_main(void) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEDevice::init(" " );< / div >
< div class = "line" > < / div >
< div class = "line" > NimBLEScan *pScan = NimBLEDevice::getScan();< / div >
2024-12-15 00:45:58 +00:00
< div class = "line" > NimBLEScanResults results = pScan-> getResults(10 * 1000);< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > }< / div >
< / div > <!-- fragment --> < p > < br / >
< / p >
< p > Now that we have scanned we need to check the results for any advertisers we are interested in connecting to. < br / >
< / p >
< p > To do this we iterate through the results and check if any of the devices found are advertising the service we want < code > ABCD< / code > . < br / >
2025-09-02 20:57:38 +00:00
Each result in < code > NimBLEScanResults< / code > is a < code > const NimBLEAdvertisedDevice*< / code > that we can access data from.< / p >
< p > We will check each device found for the < code > ABCD< / code > service by calling < code > NimBLEAdvertisedDevice::isAdvertisingService< / code > . < br / >
2021-08-05 01:02:30 +00:00
This takes an instance of < code > < a class = "el" href = "class_nim_b_l_e_u_u_i_d.html" title = "A model of a BLE UUID." > NimBLEUUID< / a > < / code > as a parameter so we will need to create one. < br / >
< / p >
< p > < b > The code for this looks like:< / b > < / p > < div class = "fragment" > < div class = "line" > NimBLEUUID serviceUuid(" ABCD" );< / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > for (int i = 0; i < results.getCount(); i++) {< / div >
< div class = "line" > const NimBLEAdvertisedDevice *device = results.getDevice(i);< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > if (device-> isAdvertisingService(serviceUuid)) {< / div >
< div class = "line" > // create a client and connect< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< / div > <!-- fragment --> < p > < br / >
< / p >
2025-09-02 20:57:38 +00:00
< p > Now that we can scan and parse advertisers we need to be able to create a < code > NimBLEClient< / code > instance and use it to connect. < br / >
2021-08-05 01:02:30 +00:00
< / p >
2025-09-02 20:57:38 +00:00
< p > To do this we call < code > NimBLEDevice::createClient< / code > which creates the < code > NimBLEClient< / code > instance and returns a pointer to it. < br / >
2021-08-05 01:02:30 +00:00
< / p >
2025-09-02 20:57:38 +00:00
< p > After this we call < code > NimBLEClient::connect< / code > to connect to the advertiser. < br / >
This takes a pointer to the < code > NimBLEAdvertisedDevice< / code > and returns < code > true< / code > if successful.< / p >
2021-08-05 01:02:30 +00:00
< p > < b > Lets do that now:< / b > < / p > < div class = "fragment" > < div class = "line" > NimBLEUUID serviceUuid(" ABCD" );< / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > for (int i = 0; i < results.getCount(); i++) {< / div >
< div class = "line" > const NimBLEAdvertisedDevice *device = results.getDevice(i);< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > if (device-> isAdvertisingService(serviceUuid)) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEClient *pClient = NimBLEDevice::createClient();< / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > if (pClient-> connect(& device)) {< / div >
< div class = "line" > //success< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > } else {< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > // failed to connect< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
2025-09-02 20:57:38 +00:00
< / div > <!-- fragment --> < p > As shown, the call to < code > NimBLEClient::connect< / code > should have it's return value tested to make sure it succeeded before proceeding to get data. < br / >
2021-08-05 01:02:30 +00:00
< br / >
< / p >
< p > Next we need to access the servers data by asking it for the service and the characteristic we are interested in, then read the characteristic value.< / p >
2025-09-02 20:57:38 +00:00
< p > To do this we call < code > NimBLEClient::getService< / code > , which takes as a parameter the UUID of the service and returns < br / >
a pointer an instance to < code > NimBLERemoteService< / code > or < code > nullptr< / code > if the service was not found. < br / >
2021-08-05 01:02:30 +00:00
< / p >
2025-09-02 20:57:38 +00:00
< p > Next we will call < code > NimBLERemoteService::getCharacteristic< / code > which takes as a parameter the UUID of the service and returns < br / >
a pointer to an instance of < code > NimBLERemoteCharacteristic< / code > or < code > nullptr< / code > if not found. < br / >
2021-08-05 01:02:30 +00:00
< / p >
2024-12-15 00:45:58 +00:00
< p > Finally we will read the characteristic value with < code > NimBLERemoteCharacteristic::readValue()< / code > . < br / >
2021-08-05 01:02:30 +00:00
< / p >
< p > < b > Here is what that looks like:< / b > < / p > < div class = "fragment" > < div class = "line" > NimBLEUUID serviceUuid(" ABCD" );< / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > for (int i = 0; i < results.getCount(); i++) {< / div >
< div class = "line" > const NimBLEAdvertisedDevice *device = results.getDevice(i);< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > if (device-> isAdvertisingService(serviceUuid)) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEClient *pClient = NimBLEDevice::createClient();< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
< div class = "line" > if (!pClient) { // Make sure the client was created< / div >
< div class = "line" > break;< / div >
< div class = "line" > }< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > < / div >
< div class = "line" > if (pClient-> connect(& device)) {< / div >
< div class = "line" > NimBLERemoteService *pService = pClient-> getService(serviceUuid);< / div >
< div class = "line" > < / div >
< div class = "line" > if (pService != nullptr) {< / div >
< div class = "line" > NimBLERemoteCharacteristic *pCharacteristic = pService-> getCharacteristic(" 1234" );< / div >
< div class = "line" > < / div >
< div class = "line" > if (pCharacteristic != nullptr) {< / div >
< div class = "line" > std::string value = pCharacteristic-> readValue();< / div >
< div class = "line" > // print or do whatever you need with the value< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< div class = "line" > } else {< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > // failed to connect< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< / div > <!-- fragment --> < p > < br / >
< / p >
< p > The last thing we should do is clean up once we are done with the connection. < br / >
Because multiple clients are supported and can be created we should delete them when finished with them to conserve resources. < br / >
2025-09-02 20:57:38 +00:00
This is done by calling < code > NimBLEDevice::deleteClient< / code > .< / p >
2021-08-05 01:02:30 +00:00
< p > < b > Lets add that now:< / b > < / p > < div class = "fragment" > < div class = "line" > NimBLEUUID serviceUuid(" ABCD" );< / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > for (int i = 0; i < results.getCount(); i++) {< / div >
< div class = "line" > const NimBLEAdvertisedDevice *device = results.getDevice(i);< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > if (device-> isAdvertisingService(serviceUuid)) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEClient *pClient = NimBLEDevice::createClient();< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
< div class = "line" > if (!pClient) { // Make sure the client was created< / div >
< div class = "line" > break;< / div >
< div class = "line" > }< / div >
< div class = "line" > < / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > if (pClient-> connect(& device)) {< / div >
< div class = "line" > NimBLERemoteService *pService = pClient-> getService(serviceUuid);< / div >
< div class = "line" > < / div >
< div class = "line" > if (pService != nullptr) {< / div >
< div class = "line" > NimBLERemoteCharacteristic *pCharacteristic = pService-> getCharacteristic(" 1234" );< / div >
< div class = "line" > < / div >
< div class = "line" > if (pCharacteristic != nullptr) {< / div >
< div class = "line" > std::string value = pCharacteristic-> readValue();< / div >
< div class = "line" > // print or do whatever you need with the value< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< div class = "line" > } else {< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > // failed to connect< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > }< / div >
< div class = "line" > < / div >
< div class = "line" > NimBLEDevice::deleteClient(pClient);< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< / div > <!-- fragment --> < p > Note that there is no need to disconnect as that will be done when deleting the client instance. < br / >
< br / >
< / p >
< p > < b > Here is the full example code:< / b > < br / >
< / p > < div class = "fragment" > < div class = "line" > #include " NimBLEDevice.h" < / div >
< div class = "line" > < / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > extern " C" void app_main(void) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEDevice::init(" " );< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEScan *pScan = NimBLEDevice::getScan();< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > NimBLEScanResults results = pScan-> getResults(10 * 1000);< / div >
< div class = "line" > < / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEUUID serviceUuid(" ABCD" );< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
< div class = "line" > for (int i = 0; i < results.getCount(); i++) {< / div >
< div class = "line" > const NimBLEAdvertisedDevice *device = results.getDevice(i);< / div >
< div class = "line" > < / div >
< div class = "line" > if (device-> isAdvertisingService(serviceUuid)) {< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEClient *pClient = NimBLEDevice::createClient();< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
< div class = "line" > if (!pClient) { // Make sure the client was created< / div >
< div class = "line" > break;< / div >
< div class = "line" > }< / div >
< div class = "line" > < / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > if (pClient-> connect(& device)) {< / div >
< div class = "line" > NimBLERemoteService *pService = pClient-> getService(serviceUuid);< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > if (pService != nullptr) {< / div >
< div class = "line" > NimBLERemoteCharacteristic *pCharacteristic = pService-> getCharacteristic(" 1234" );< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > if (pCharacteristic != nullptr) {< / div >
< div class = "line" > std::string value = pCharacteristic-> readValue();< / div >
< div class = "line" > // print or do whatever you need with the value< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< div class = "line" > } else {< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > // failed to connect< / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > }< / div >
2025-01-13 02:22:00 +00:00
< div class = "line" > < / div >
2021-08-05 01:02:30 +00:00
< div class = "line" > NimBLEDevice::deleteClient(pClient);< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< div class = "line" > }< / div >
< / div > <!-- fragment --> < p > < br / >
< / p >
< p > For more advanced features and options please see the client examples in the examples folder. < br / >
< br / >
< / p >
< / div > < / div > <!-- contents -->
< / div > <!-- PageDoc -->
< / div > <!-- doc - content -->
<!-- start footer part -->
< div id = "nav-path" class = "navpath" > <!-- id is needed for treeview function! -->
< ul >
2024-12-15 00:45:58 +00:00
< li class = "footer" > Generated by < a href = "https://www.doxygen.org/index.html" > < img class = "footer" src = "doxygen.svg" width = "104" height = "31" alt = "doxygen" / > < / a > 1.9.8 < / li >
2021-08-05 01:02:30 +00:00
< / ul >
< / div >
< / body >
< / html >