|
| 1 | +/* |
| 2 | + Based on Neil Kolban example for IDF: https://github.com/nkolban/esp32-snippets/blob/master/cpp_utils/tests/BLE%20Tests/SampleScan.cpp |
| 3 | + Ported to Arduino ESP32 by Evandro Copercini |
| 4 | +*/ |
1 | 5 |
|
2 |
| -/** NimBLE Extended Client Demo: |
3 |
| - * |
4 |
| - * Demonstrates the Bluetooth 5.x client capabilities. |
5 |
| - * |
6 |
| - * Created: on April 2 2022 |
7 |
| - * Author: H2zero |
8 |
| - * |
9 |
| - */ |
| 6 | +#include <BLEDevice.h> |
| 7 | +#include <BLEUtils.h> |
| 8 | +#include <BLEScan.h> |
| 9 | +#include <BLEAdvertisedDevice.h> |
10 | 10 |
|
11 |
| -#include <Arduino.h> |
12 |
| -#include <NimBLEDevice.h> |
13 |
| -#if !CONFIG_BT_NIMBLE_EXT_ADV |
14 |
| -# error Must enable extended advertising, see nimconfig.h file. |
15 |
| -#endif |
| 11 | +int scanTime = 5; //In seconds |
| 12 | +BLEScan *pBLEScan; |
16 | 13 |
|
17 |
| -#define SERVICE_UUID "ABCD" |
18 |
| -#define CHARACTERISTIC_UUID "1234" |
19 |
| - |
20 |
| -static const NimBLEAdvertisedDevice* advDevice; |
21 |
| -static bool doConnect = false; |
22 |
| -static uint32_t scanTime = 10 * 1000; // In milliseconds, 0 = scan forever |
23 |
| - |
24 |
| -/** Define the PHY's to use when connecting to peer devices, can be 1, 2, or all 3 (default).*/ |
25 |
| -static uint8_t connectPhys = BLE_GAP_LE_PHY_CODED_MASK | BLE_GAP_LE_PHY_1M_MASK /*| BLE_GAP_LE_PHY_2M_MASK */; |
26 |
| - |
27 |
| -/** Define a class to handle the callbacks for client connection events */ |
28 |
| -class ClientCallbacks : public NimBLEClientCallbacks { |
29 |
| - void onConnect(NimBLEClient* pClient) override { Serial.printf("Connected\n"); }; |
30 |
| - |
31 |
| - void onDisconnect(NimBLEClient* pClient, int reason) override { |
32 |
| - Serial.printf("%s Disconnected, reason = %d - Starting scan\n", pClient->getPeerAddress().toString().c_str(), reason); |
33 |
| - NimBLEDevice::getScan()->start(scanTime); |
34 |
| - } |
35 |
| -} clientCallbacks; |
36 |
| - |
37 |
| -/** Define a class to handle the callbacks when advertisements are received */ |
38 |
| -class scanCallbacks : public NimBLEScanCallbacks { |
39 |
| - void onResult(const NimBLEAdvertisedDevice* advertisedDevice) override { |
40 |
| - Serial.printf("Advertised Device found: %s\n", advertisedDevice->toString().c_str()); |
41 |
| - if (advertisedDevice->isAdvertisingService(NimBLEUUID("ABCD"))) { |
42 |
| - Serial.printf("Found Our Service\n"); |
43 |
| - doConnect = true; |
44 |
| - /** Save the device reference in a global for the client to use*/ |
45 |
| - advDevice = advertisedDevice; |
46 |
| - /** stop scan before connecting */ |
47 |
| - NimBLEDevice::getScan()->stop(); |
48 |
| - } |
49 |
| - } |
50 |
| - |
51 |
| - /** Callback to process the results of the completed scan or restart it */ |
52 |
| - void onScanEnd(const NimBLEScanResults& results, int rc) override { Serial.printf("Scan Ended\n"); } |
53 |
| -} scanCallbacks; |
54 |
| - |
55 |
| -/** Handles the provisioning of clients and connects / interfaces with the server */ |
56 |
| -bool connectToServer() { |
57 |
| - NimBLEClient* pClient = nullptr; |
58 |
| - |
59 |
| - pClient = NimBLEDevice::createClient(); |
60 |
| - pClient->setClientCallbacks(&clientCallbacks, false); |
61 |
| - |
62 |
| - /** |
63 |
| - * Set the PHY's to use for this connection. This is a bitmask that represents the PHY's: |
64 |
| - * * 0x01 BLE_GAP_LE_PHY_1M_MASK |
65 |
| - * * 0x02 BLE_GAP_LE_PHY_2M_MASK |
66 |
| - * * 0x04 BLE_GAP_LE_PHY_CODED_MASK |
67 |
| - * Combine these with OR ("|"), eg BLE_GAP_LE_PHY_1M_MASK | BLE_GAP_LE_PHY_2M_MASK | BLE_GAP_LE_PHY_CODED_MASK; |
68 |
| - */ |
69 |
| - pClient->setConnectPhy(connectPhys); |
70 |
| - |
71 |
| - /** Set how long we are willing to wait for the connection to complete (milliseconds), default is 30000. */ |
72 |
| - pClient->setConnectTimeout(10 * 1000); |
73 |
| - |
74 |
| - if (!pClient->connect(advDevice)) { |
75 |
| - /** Created a client but failed to connect, don't need to keep it as it has no data */ |
76 |
| - NimBLEDevice::deleteClient(pClient); |
77 |
| - Serial.printf("Failed to connect, deleted client\n"); |
78 |
| - return false; |
79 |
| - } |
80 |
| - |
81 |
| - Serial.printf("Connected to: %s RSSI: %d\n", pClient->getPeerAddress().toString().c_str(), pClient->getRssi()); |
82 |
| - |
83 |
| - /** Now we can read/write/subscribe the characteristics of the services we are interested in */ |
84 |
| - NimBLERemoteService* pSvc = nullptr; |
85 |
| - NimBLERemoteCharacteristic* pChr = nullptr; |
86 |
| - |
87 |
| - pSvc = pClient->getService(SERVICE_UUID); |
88 |
| - if (pSvc) { |
89 |
| - pChr = pSvc->getCharacteristic(CHARACTERISTIC_UUID); |
90 |
| - if (pChr) { |
91 |
| - if (pChr->canRead()) { |
92 |
| - std::string value = pChr->readValue(); |
93 |
| - Serial.printf("Characteristic value: %s\n", value.c_str()); |
94 |
| - } |
95 |
| - } |
96 |
| - |
97 |
| - } else { |
98 |
| - Serial.printf("ABCD service not found.\n"); |
99 |
| - } |
100 |
| - |
101 |
| - NimBLEDevice::deleteClient(pClient); |
102 |
| - Serial.printf("Done with this device!\n"); |
103 |
| - return true; |
104 |
| -} |
| 14 | +class MyAdvertisedDeviceCallbacks : public BLEAdvertisedDeviceCallbacks { |
| 15 | + void onResult(BLEAdvertisedDevice advertisedDevice) { |
| 16 | + Serial.printf("Advertised Device: %s \n", advertisedDevice.toString().c_str()); |
| 17 | + } |
| 18 | +}; |
105 | 19 |
|
106 | 20 | void setup() {
|
107 |
| - Serial.begin(115200); |
108 |
| - Serial.printf("Starting NimBLE Client\n"); |
109 |
| - |
110 |
| - /** Initialize NimBLE and set the device name */ |
111 |
| - NimBLEDevice::init("NimBLE Extended Client"); |
112 |
| - |
113 |
| - /** Create aNimBLE Scan instance and set the callbacks for scan events */ |
114 |
| - NimBLEScan* pScan = NimBLEDevice::getScan(); |
115 |
| - pScan->setScanCallbacks(&scanCallbacks); |
116 |
| - |
117 |
| - /** Set scan interval (how often) and window (how long) in milliseconds */ |
118 |
| - pScan->setInterval(97); |
119 |
| - pScan->setWindow(67); |
120 |
| - |
121 |
| - /** |
122 |
| - * Active scan will gather scan response data from advertisers |
123 |
| - * but will use more energy from both devices |
124 |
| - */ |
125 |
| - pScan->setActiveScan(true); |
126 |
| - |
127 |
| - /** |
128 |
| - * Start scanning for advertisers for the scan time specified (in milliseconds) 0 = forever |
129 |
| - * Optional callback for when scanning stops. |
130 |
| - */ |
131 |
| - pScan->start(scanTime); |
132 |
| - |
133 |
| - Serial.printf("Scanning for peripherals\n"); |
| 21 | + Serial.begin(115200); |
| 22 | + Serial.println("Scanning..."); |
| 23 | + |
| 24 | + BLEDevice::init(""); |
| 25 | + pBLEScan = BLEDevice::getScan(); //create new scan |
| 26 | + pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); |
| 27 | + pBLEScan->setActiveScan(true); //active scan uses more power, but get results faster |
| 28 | + pBLEScan->setInterval(100); |
| 29 | + pBLEScan->setWindow(99); // less or equal setInterval value |
134 | 30 | }
|
135 | 31 |
|
136 | 32 | void loop() {
|
137 |
| - /** Loop here until we find a device we want to connect to */ |
138 |
| - if (doConnect) { |
139 |
| - if (connectToServer()) { |
140 |
| - Serial.printf("Success!, scanning for more!\n"); |
141 |
| - } else { |
142 |
| - Serial.printf("Failed to connect, starting scan\n"); |
143 |
| - } |
144 |
| - |
145 |
| - doConnect = false; |
146 |
| - NimBLEDevice::getScan()->start(scanTime); |
147 |
| - } |
148 |
| - |
149 |
| - delay(10); |
| 33 | + // put your main code here, to run repeatedly: |
| 34 | + BLEScanResults *foundDevices = pBLEScan->start(scanTime, false); |
| 35 | + Serial.print("Devices found: "); |
| 36 | + Serial.println(foundDevices->getCount()); |
| 37 | + Serial.println("Scan done!"); |
| 38 | + pBLEScan->clearResults(); // delete results fromBLEScan buffer to release memory |
| 39 | + delay(2000); |
150 | 40 | }
|
0 commit comments