Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitffa08d4

Browse files
committed
feat(ble): Add client multiconnect example
1 parent4a0612f commitffa08d4

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed
Lines changed: 277 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,277 @@
1+
/**
2+
* A BLE client example that connects to multiple BLE servers simultaneously.
3+
*
4+
* This example demonstrates how to:
5+
* - Scan for multiple BLE servers
6+
* - Connect to multiple servers at the same time
7+
* - Interact with characteristics on different servers
8+
* - Handle disconnections and reconnections
9+
*
10+
* The example looks for servers advertising the service UUID: 4fafc201-1fb5-459e-8fcc-c5c9c331914b
11+
* and connects to up to MAX_SERVERS servers.
12+
*
13+
* Created by lucasssvaz
14+
* Based on the original Client example by Neil Kolban and chegewara
15+
*/
16+
17+
#include"BLEDevice.h"
18+
19+
// The remote service we wish to connect to.
20+
static BLEUUIDserviceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
21+
// The characteristic of the remote service we are interested in.
22+
static BLEUUIDcharUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");
23+
24+
// Maximum number of servers to connect to
25+
#defineMAX_SERVERS3
26+
27+
// Structure to hold information about each connected server
28+
structServerConnection {
29+
BLEClient *pClient;
30+
BLEAdvertisedDevice *pDevice;
31+
BLERemoteCharacteristic *pRemoteCharacteristic;
32+
bool connected;
33+
bool doConnect;
34+
String name;
35+
};
36+
37+
// Array to manage multiple server connections
38+
ServerConnection servers[MAX_SERVERS];
39+
int connectedServers =0;
40+
staticbool doScan =true;
41+
42+
// Callback function to handle notifications from any server
43+
staticvoidnotifyCallback(BLERemoteCharacteristic *pBLERemoteCharacteristic,uint8_t *pData,size_t length,bool isNotify) {
44+
// Find which server this notification came from
45+
for (int i =0; i < MAX_SERVERS; i++) {
46+
if (servers[i].connected && servers[i].pRemoteCharacteristic == pBLERemoteCharacteristic) {
47+
Serial.print("Notify from server");
48+
Serial.print(servers[i].name);
49+
Serial.print(" - Characteristic:");
50+
Serial.print(pBLERemoteCharacteristic->getUUID().toString().c_str());
51+
Serial.print(" | Length:");
52+
Serial.print(length);
53+
Serial.print(" | Data:");
54+
Serial.write(pData, length);
55+
Serial.println();
56+
break;
57+
}
58+
}
59+
}
60+
61+
// Client callback class to handle connect/disconnect events
62+
classMyClientCallback :publicBLEClientCallbacks {
63+
int serverIndex;
64+
65+
public:
66+
MyClientCallback(int index) : serverIndex(index) {}
67+
68+
voidonConnect(BLEClient *pclient) {
69+
Serial.print("Connected to server");
70+
Serial.println(servers[serverIndex].name);
71+
}
72+
73+
voidonDisconnect(BLEClient *pclient) {
74+
servers[serverIndex].connected =false;
75+
connectedServers--;
76+
Serial.print("Disconnected from server");
77+
Serial.print(servers[serverIndex].name);
78+
Serial.print(" | Total connected:");
79+
Serial.println(connectedServers);
80+
doScan =true;// Resume scanning to find replacement servers
81+
}
82+
};
83+
84+
// Function to connect to a specific server
85+
boolconnectToServer(int serverIndex) {
86+
Serial.print("Connecting to server");
87+
Serial.print(serverIndex);
88+
Serial.print(" at address:");
89+
Serial.println(servers[serverIndex].pDevice->getAddress().toString().c_str());
90+
91+
servers[serverIndex].pClient =BLEDevice::createClient();
92+
Serial.println(" - Created client");
93+
94+
// Set the callback for this specific server connection
95+
servers[serverIndex].pClient->setClientCallbacks(newMyClientCallback(serverIndex));
96+
97+
// Connect to the remote BLE Server
98+
servers[serverIndex].pClient->connect(servers[serverIndex].pDevice);
99+
Serial.println(" - Connected to server");
100+
servers[serverIndex].pClient->setMTU(517);// Request maximum MTU from server
101+
102+
// Obtain a reference to the service we are after in the remote BLE server
103+
BLERemoteService *pRemoteService = servers[serverIndex].pClient->getService(serviceUUID);
104+
if (pRemoteService ==nullptr) {
105+
Serial.print("Failed to find service UUID:");
106+
Serial.println(serviceUUID.toString().c_str());
107+
servers[serverIndex].pClient->disconnect();
108+
returnfalse;
109+
}
110+
Serial.println(" - Found service");
111+
112+
// Obtain a reference to the characteristic in the service
113+
servers[serverIndex].pRemoteCharacteristic = pRemoteService->getCharacteristic(charUUID);
114+
if (servers[serverIndex].pRemoteCharacteristic ==nullptr) {
115+
Serial.print("Failed to find characteristic UUID:");
116+
Serial.println(charUUID.toString().c_str());
117+
servers[serverIndex].pClient->disconnect();
118+
returnfalse;
119+
}
120+
Serial.println(" - Found characteristic");
121+
122+
// Read the value of the characteristic
123+
if (servers[serverIndex].pRemoteCharacteristic->canRead()) {
124+
String value = servers[serverIndex].pRemoteCharacteristic->readValue();
125+
Serial.print("Initial characteristic value:");
126+
Serial.println(value.c_str());
127+
}
128+
129+
// Register for notifications if available
130+
if (servers[serverIndex].pRemoteCharacteristic->canNotify()) {
131+
servers[serverIndex].pRemoteCharacteristic->registerForNotify(notifyCallback);
132+
Serial.println(" - Registered for notifications");
133+
}
134+
135+
servers[serverIndex].connected =true;
136+
connectedServers++;
137+
Serial.print("Successfully connected! Total servers connected:");
138+
Serial.println(connectedServers);
139+
returntrue;
140+
}
141+
142+
// Scan callback class to find BLE servers
143+
classMyAdvertisedDeviceCallbacks :publicBLEAdvertisedDeviceCallbacks {
144+
voidonResult(BLEAdvertisedDevice advertisedDevice) {
145+
Serial.print("BLE Device found:");
146+
Serial.println(advertisedDevice.toString().c_str());
147+
148+
// Check if this device has the service we're looking for
149+
if (advertisedDevice.haveServiceUUID() && advertisedDevice.isAdvertisingService(serviceUUID)) {
150+
Serial.println(" -> This device has our service!");
151+
152+
// Check if we already know about this device
153+
String deviceAddress = advertisedDevice.getAddress().toString().c_str();
154+
bool alreadyKnown =false;
155+
156+
for (int i =0; i < MAX_SERVERS; i++) {
157+
if (servers[i].pDevice !=nullptr) {
158+
if (servers[i].pDevice->getAddress().toString() == deviceAddress) {
159+
alreadyKnown =true;
160+
break;
161+
}
162+
}
163+
}
164+
165+
if (alreadyKnown) {
166+
Serial.println(" -> Already connected or connecting to this device");
167+
return;
168+
}
169+
170+
// Find an empty slot for this server
171+
for (int i =0; i < MAX_SERVERS; i++) {
172+
if (servers[i].pDevice ==nullptr || (!servers[i].connected && !servers[i].doConnect)) {
173+
servers[i].pDevice =newBLEAdvertisedDevice(advertisedDevice);
174+
servers[i].doConnect =true;
175+
servers[i].name ="Server_" +String(i);
176+
Serial.print(" -> Assigned to slot");
177+
Serial.println(i);
178+
179+
// If we've found enough servers, stop scanning
180+
int pendingConnections =0;
181+
for (int j =0; j < MAX_SERVERS; j++) {
182+
if (servers[j].connected || servers[j].doConnect) {
183+
pendingConnections++;
184+
}
185+
}
186+
if (pendingConnections >= MAX_SERVERS) {
187+
Serial.println("Found enough servers, stopping scan");
188+
BLEDevice::getScan()->stop();
189+
doScan =false;
190+
}
191+
break;
192+
}
193+
}
194+
}
195+
}
196+
};
197+
198+
voidsetup() {
199+
Serial.begin(115200);
200+
Serial.println("=================================");
201+
Serial.println("BLE Multi-Client Example");
202+
Serial.println("=================================");
203+
Serial.print("Max servers to connect:");
204+
Serial.println(MAX_SERVERS);
205+
Serial.println();
206+
207+
// Initialize all server connections
208+
for (int i =0; i < MAX_SERVERS; i++) {
209+
servers[i].pClient =nullptr;
210+
servers[i].pDevice =nullptr;
211+
servers[i].pRemoteCharacteristic =nullptr;
212+
servers[i].connected =false;
213+
servers[i].doConnect =false;
214+
servers[i].name ="";
215+
}
216+
217+
// Initialize BLE
218+
BLEDevice::init("ESP32_MultiClient");
219+
220+
// Set up BLE scanner
221+
BLEScan *pBLEScan =BLEDevice::getScan();
222+
pBLEScan->setAdvertisedDeviceCallbacks(newMyAdvertisedDeviceCallbacks());
223+
pBLEScan->setInterval(1349);
224+
pBLEScan->setWindow(449);
225+
pBLEScan->setActiveScan(true);
226+
pBLEScan->start(5,false);
227+
228+
Serial.println("Scanning for BLE servers...");
229+
}
230+
231+
voidloop() {
232+
// Process any pending connections
233+
for (int i =0; i < MAX_SERVERS; i++) {
234+
if (servers[i].doConnect) {
235+
if (connectToServer(i)) {
236+
Serial.println("Connection successful");
237+
}else {
238+
Serial.println("Connection failed");
239+
// Clear this slot so we can try another server
240+
delete servers[i].pDevice;
241+
servers[i].pDevice =nullptr;
242+
}
243+
servers[i].doConnect =false;
244+
}
245+
}
246+
247+
// If we're connected to servers, send data to each one
248+
if (connectedServers >0) {
249+
for (int i =0; i < MAX_SERVERS; i++) {
250+
if (servers[i].connected && servers[i].pRemoteCharacteristic !=nullptr) {
251+
// Create a unique message for each server
252+
String newValue = servers[i].name +" | Time:" +String(millis() /1000);
253+
254+
Serial.print("Sending to");
255+
Serial.print(servers[i].name);
256+
Serial.print(":");
257+
Serial.println(newValue);
258+
259+
// Write the value to the characteristic
260+
servers[i].pRemoteCharacteristic->writeValue(newValue.c_str(), newValue.length());
261+
}
262+
}
263+
}else {
264+
Serial.println("No servers connected");
265+
}
266+
267+
// Resume scanning if we have room for more connections
268+
if (doScan && connectedServers < MAX_SERVERS) {
269+
Serial.println("Resuming scan for more servers...");
270+
BLEDevice::getScan()->start(5,false);
271+
doScan =false;
272+
delay(5000);// Wait for scan to complete
273+
}
274+
275+
delay(2000);// Delay between loop iterations
276+
}
277+
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
fqbn_append:PartitionScheme=huge_app
2+
3+
requires_any:
4+
-CONFIG_SOC_BLE_SUPPORTED=y
5+
-CONFIG_ESP_HOSTED_ENABLE_BT_NIMBLE=y
6+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp