mirror of
https://github.com/h2zero/esp-nimble-cpp.git
synced 2024-12-26 20:50:46 +01:00
409 lines
26 KiB
HTML
409 lines
26 KiB
HTML
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "https://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
|
||
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||
|
<head>
|
||
|
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
|
||
|
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
|
||
|
<meta name="generator" content="Doxygen 1.9.0"/>
|
||
|
<meta name="viewport" content="width=device-width, initial-scale=1"/>
|
||
|
<title>esp-nimble-cpp / NimBLE-Arduino: New User Guide</title>
|
||
|
<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>
|
||
|
<tr style="height: 56px;">
|
||
|
<td id="projectalign" style="padding-left: 0.5em;">
|
||
|
<div id="projectname">esp-nimble-cpp / NimBLE-Arduino
|
||
|
 <span id="projectnumber">1.3.1</span>
|
||
|
</div>
|
||
|
</td>
|
||
|
</tr>
|
||
|
</tbody>
|
||
|
</table>
|
||
|
</div>
|
||
|
<!-- end header part -->
|
||
|
<!-- Generated by Doxygen 1.9.0 -->
|
||
|
<script type="text/javascript">
|
||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||
|
var searchBox = new SearchBox("searchBox", "search",false,'Search','.html');
|
||
|
/* @license-end */
|
||
|
</script>
|
||
|
<script type="text/javascript" src="menudata.js"></script>
|
||
|
<script type="text/javascript" src="menu.js"></script>
|
||
|
<script type="text/javascript">
|
||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||
|
$(function() {
|
||
|
initMenu('',true,false,'search.php','Search');
|
||
|
$(document).ready(function() { init_search(); });
|
||
|
});
|
||
|
/* @license-end */</script>
|
||
|
<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">
|
||
|
/* @license magnet:?xt=urn:btih:cf05388f2679ee054f2beb29a391d25f4e673ac3&dn=gpl-2.0.txt GPL-v2 */
|
||
|
$(document).ready(function(){initNavTree('md_docs__new_user_guide.html',''); initResizable(); });
|
||
|
/* @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">
|
||
|
<iframe src="javascript:void(0)" frameborder="0"
|
||
|
name="MSearchResults" id="MSearchResults">
|
||
|
</iframe>
|
||
|
</div>
|
||
|
|
||
|
<div class="PageDoc"><div class="header">
|
||
|
<div class="headertitle">
|
||
|
<div class="title">New User Guide </div> </div>
|
||
|
</div><!--header-->
|
||
|
<div class="contents">
|
||
|
<div class="textblock"><p><b>Note:</b> If you are migrating an existing project from the original Bluedroid library please see the <a class="el" href="md_docs__migration_guide.html">Migration Guide.</a> <br />
|
||
|
</p>
|
||
|
<p>If you are a new user this will guide you through a simple server and client application. <br />
|
||
|
</p>
|
||
|
<ul>
|
||
|
<li><a href="#creating-a-server">Creating a Server</a></li>
|
||
|
<li><a href="#creating-a-client">Creating a Client</a> <br />
|
||
|
<br />
|
||
|
</li>
|
||
|
</ul>
|
||
|
<h1><a class="anchor" id="autotoc_md62"></a>
|
||
|
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>
|
||
|
<h1><a class="anchor" id="autotoc_md63"></a>
|
||
|
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>
|
||
|
<p>To do this you must call <code><a class="el" href="class_nim_b_l_e_device.html#a674d2e68d4ba0e3f84d7993f9da7d15b" 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 />
|
||
|
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>
|
||
|
<p><a class="anchor" id="creating-a-server"></a> </p>
|
||
|
<h1><a class="anchor" id="autotoc_md64"></a>
|
||
|
Creating a Server</h1>
|
||
|
<p>BLE servers perform 2 tasks, they advertise their existance for clients to find them and they provide services which contain information for the connecting client. <br />
|
||
|
</p>
|
||
|
<p>After initializing the NimBLE stack we create a server by calling <code><a class="el" href="class_nim_b_l_e_device.html#a4d9780d0b5fafc279483822af802a508" title="Create a new instance of a server.">NimBLEDevice::createServer()</a></code>, this will create a server instance and return a pointer to it. <br />
|
||
|
</p>
|
||
|
<p>Once we have created the server we need to tell it the services it hosts. <br />
|
||
|
To do this we call <code><a class="el" href="class_nim_b_l_e_server.html#aaeb58b4de85754d1aac6964e9248aa35" title="Create a BLE Service.">NimBLEServer::createService(const char* uuid)</a></code>. Which returns a pointer to an instance of <code><a class="el" href="class_nim_b_l_e_service.html" title="The model of a BLE service.">NimBLEService</a></code>. <br />
|
||
|
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>
|
||
|
<div class="line">// void setup() in Arduino</div>
|
||
|
<div class="line">void app_main(void) </div>
|
||
|
<div class="line">{</div>
|
||
|
<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>
|
||
|
<p>Next we call <code><a class="el" href="class_nim_b_l_e_service.html#adab5552c080b9cb88095af262d326309" title="Create a new BLE Characteristic associated with this service.">NimBLEService::createCharacteristic</a></code> which returns a pointer to an instance of <code><a class="el" href="class_nim_b_l_e_characteristic.html" title="The model of a BLE Characteristic.">NimBLECharacteristic</a></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 />
|
||
|
</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">
|
||
|
<p>NIMBLE_PROPERTY::READ <br />
|
||
|
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>
|
||
|
<div class="line">// void setup() in Arduino</div>
|
||
|
<div class="line">void app_main(void)</div>
|
||
|
<div class="line">{</div>
|
||
|
<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><!-- fragment --><p>All that's left to do now is start the sevice, give the characteristic a value and start advertising for clients. <br />
|
||
|
</p>
|
||
|
<p>Fist we start the service by calling <code><a class="el" href="class_nim_b_l_e_service.html#ad37324ed0404d596923d6fdc0133b985" title="Builds the database of characteristics/descriptors for the service and registers it with the NimBLE s...">NimBLEService::start()</a></code>.</p>
|
||
|
<p>Next we need to call <code><a class="el" href="class_nim_b_l_e_characteristic.html#a7cd211a8bb9a0c2ffaed57f2af273677" title="Set the value of the characteristic.">NimBLECharacteristic::setValue</a></code> to set the characteristic value that the client will read. <br />
|
||
|
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 />
|
||
|
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 advertisng. <br />
|
||
|
</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>
|
||
|
<div class="line">pAdvertising->addServiceUUID("ABCD"); // tell advertising the UUID of our service</div>
|
||
|
<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>
|
||
|
<div class="line">// void setup() in Arduino</div>
|
||
|
<div class="line">void app_main(void)</div>
|
||
|
<div class="line">{</div>
|
||
|
<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>
|
||
|
<div class="line"> pAdvertising->addServiceUUID("ABCD"); </div>
|
||
|
<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>
|
||
|
<p><a class="anchor" id="creating-a-client"></a> </p>
|
||
|
<h1><a class="anchor" id="autotoc_md65"></a>
|
||
|
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>
|
||
|
<p>After initializing the NimBLE stack we create a scan instance by calling <code><a class="el" href="class_nim_b_l_e_device.html#af93d92316454b051125460056368baec" title="Retrieve the Scan object that we use for scanning.">NimBLEDevice::getScan()</a></code>, this will create a <code><a class="el" href="class_nim_b_l_e_scan.html" title="Perform and manage BLE scans.">NimBLEScan</a></code> instance and return a pointer to it. <br />
|
||
|
</p>
|
||
|
<p>Once we have created the scan we can start looking for advertising servers. <br />
|
||
|
</p>
|
||
|
<p>To do this we call <code>NimBLEScan::start(duration)</code>, the duration parameter is a uint32_t that specifies the number of seconds to scan for, <br />
|
||
|
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 />
|
||
|
This call returns an instance of <code><a class="el" href="class_nim_b_l_e_scan_results.html" title="A class that contains and operates on the results of a BLE scan.">NimBLEScanResults</a></code> when the scan completes which can be parsed for advertisers we are interested in. <br />
|
||
|
</p>
|
||
|
<p><b>Example Code:</b> <br />
|
||
|
</p><div class="fragment"><div class="line">#include "NimBLEDevice.h"</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line">// void setup() in Arduino</div>
|
||
|
<div class="line">void app_main(void) </div>
|
||
|
<div class="line">{</div>
|
||
|
<div class="line"> NimBLEDevice::init("");</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> NimBLEScan *pScan = NimBLEDevice::getScan();</div>
|
||
|
<div class="line"> NimBLEScanResults results = pScan->start(10);</div>
|
||
|
<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 />
|
||
|
Each result in <code><a class="el" href="class_nim_b_l_e_scan_results.html" title="A class that contains and operates on the results of a BLE scan.">NimBLEScanResults</a></code> is a <code><a class="el" href="class_nim_b_l_e_advertised_device.html" title="A representation of a BLE advertised device found by a scan.">NimBLEAdvertisedDevice</a></code> instance that we can access data from.</p>
|
||
|
<p>We will check each device found for the <code>ABCD</code> service by calling <code><a class="el" href="class_nim_b_l_e_advertised_device.html#a37ad095c066aa231a52a7259734c9bce" title="Check advertised services for existance of the required UUID.">NimBLEAdvertisedDevice::isAdvertisingService</a></code>. <br />
|
||
|
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>
|
||
|
<div class="line">for(int i = 0; i < results.getCount(); i++) {</div>
|
||
|
<div class="line"> NimBLEAdvertisedDevice device = results.getDevice(i);</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> if (device.isAdvertisingService(serviceUuid)) {</div>
|
||
|
<div class="line"> // create a client and connect</div>
|
||
|
<div class="line"> }</div>
|
||
|
<div class="line">}</div>
|
||
|
</div><!-- fragment --><p> <br />
|
||
|
</p>
|
||
|
<p>Now that we can scan and parse advertisers we need to be able to create a <code><a class="el" href="class_nim_b_l_e_client.html" title="A model of a BLE client.">NimBLEClient</a></code> instance and use it to connect. <br />
|
||
|
</p>
|
||
|
<p>To do this we call <code><a class="el" href="class_nim_b_l_e_device.html#af8142995252f486916dbb9de2a5b0c9e" title="Creates a new client object and maintains a list of all client objects each client can connect to 1 p...">NimBLEDevice::createClient</a></code> which creates the <code><a class="el" href="class_nim_b_l_e_client.html" title="A model of a BLE client.">NimBLEClient</a></code> instance and returns a pointer to it. <br />
|
||
|
</p>
|
||
|
<p>After this we call <code><a class="el" href="class_nim_b_l_e_client.html#aab311f0a8af21fb63f78e7fbac29951a" title="Connect to an advertising device.">NimBLEClient::connect</a></code> to connect to the advertiser. <br />
|
||
|
This takes a pointer to the <code><a class="el" href="class_nim_b_l_e_advertised_device.html" title="A representation of a BLE advertised device found by a scan.">NimBLEAdvertisedDevice</a></code> and returns <code>true</code> if successful.</p>
|
||
|
<p><b>Lets do that now:</b> </p><div class="fragment"><div class="line">NimBLEUUID serviceUuid("ABCD");</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line">for(int i = 0; i < results.getCount(); i++) {</div>
|
||
|
<div class="line"> NimBLEAdvertisedDevice device = results.getDevice(i);</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> if (device.isAdvertisingService(serviceUuid)) {</div>
|
||
|
<div class="line"> NimBLEClient *pClient = NimBLEDevice::createClient();</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> if(pClient->connect(&device)) {</div>
|
||
|
<div class="line"> //success</div>
|
||
|
<div class="line"> } else {</div>
|
||
|
<div class="line"> // failed to connect</div>
|
||
|
<div class="line"> }</div>
|
||
|
<div class="line"> }</div>
|
||
|
<div class="line">}</div>
|
||
|
</div><!-- fragment --><p> As shown, the call to <code><a class="el" href="class_nim_b_l_e_client.html#aab311f0a8af21fb63f78e7fbac29951a" title="Connect to an advertising device.">NimBLEClient::connect</a></code> should have it's eturn value tested to make sure it succeeded before proceeding to get data. <br />
|
||
|
<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>
|
||
|
<p>To do this we call <code><a class="el" href="class_nim_b_l_e_client.html#ae22379ab10bd82932d2303fb3753c366" title="Get the service BLE Remote Service instance corresponding to the uuid.">NimBLEClient::getService</a></code>, which takes as a parameter the UUID of the service and returns <br />
|
||
|
a pointer an instance to <code><a class="el" href="class_nim_b_l_e_remote_service.html" title="A model of a remote BLE service.">NimBLERemoteService</a></code> or <code>nullptr</code> if the service was not found. <br />
|
||
|
</p>
|
||
|
<p>Next we will call <code>NimBLERemoteService::getCharateristic</code> which takes as a parameter the UUID of the service and returns <br />
|
||
|
a pointer to an instance of <code><a class="el" href="class_nim_b_l_e_remote_characteristic.html" title="A model of a remote BLE characteristic.">NimBLERemoteCharacteristic</a></code> or <code>nullptr</code> if not found. <br />
|
||
|
</p>
|
||
|
<p>Finally we will read the characteristic value with <code><a class="el" href="class_nim_b_l_e_remote_characteristic.html#a7e10fa37095d7c80dc36c768fe783e67" title="Read the value of the remote characteristic.">NimBLERemoteCharacteristic::readValue()</a></code>. <br />
|
||
|
</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>
|
||
|
<div class="line">for(int i = 0; i < results.getCount(); i++) {</div>
|
||
|
<div class="line"> NimBLEAdvertisedDevice device = results.getDevice(i);</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> if (device.isAdvertisingService(serviceUuid)) {</div>
|
||
|
<div class="line"> NimBLEClient *pClient = NimBLEDevice::createClient();</div>
|
||
|
<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>
|
||
|
<div class="line"> // failed to connect</div>
|
||
|
<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 />
|
||
|
This is done by calling <code><a class="el" href="class_nim_b_l_e_device.html#a83aa0a3d9d57358d35082a442edf8549" title="Delete the client object and remove it from the list. Checks if it is connected or trying to connect ...">NimBLEDevice::deleteClient</a></code>.</p>
|
||
|
<p><b>Lets add that now:</b> </p><div class="fragment"><div class="line">NimBLEUUID serviceUuid("ABCD");</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line">for(int i = 0; i < results.getCount(); i++) {</div>
|
||
|
<div class="line"> NimBLEAdvertisedDevice device = results.getDevice(i);</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> if (device.isAdvertisingService(serviceUuid)) {</div>
|
||
|
<div class="line"> NimBLEClient *pClient = NimBLEDevice::createClient();</div>
|
||
|
<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>
|
||
|
<div class="line"> // failed to connect</div>
|
||
|
<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>
|
||
|
<div class="line">// void setup() in Arduino</div>
|
||
|
<div class="line">void app_main(void) </div>
|
||
|
<div class="line">{</div>
|
||
|
<div class="line"> NimBLEDevice::init("");</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> NimBLEScan *pScan = NimBLEDevice::getScan();</div>
|
||
|
<div class="line"> NimBLEScanResults results = pScan->start(10);</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> NimBLEUUID serviceUuid("ABCD");</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> for(int i = 0; i < results.getCount(); i++) {</div>
|
||
|
<div class="line"> NimBLEAdvertisedDevice device = results.getDevice(i);</div>
|
||
|
<div class="line"> </div>
|
||
|
<div class="line"> if (device.isAdvertisingService(serviceUuid)) {</div>
|
||
|
<div class="line"> NimBLEClient *pClient = NimBLEDevice::createClient();</div>
|
||
|
<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>
|
||
|
<div class="line"> // failed to connect</div>
|
||
|
<div class="line"> }</div>
|
||
|
<div class="line"> </div>
|
||
|
<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>
|
||
|
<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.0 </li>
|
||
|
</ul>
|
||
|
</div>
|
||
|
</body>
|
||
|
</html>
|