我正在使用两个 esp32,一个配置为服务器,另一个配置为客户端,建立连接后,我试图关闭其中一个,同时保持另一个运行,发现检测断开需要大约 6 秒,但我想要将其减少到 1 秒或更短(尽可能快)。
我尝试使用应用程序将我的手机(客户端)连接到 esp 服务器并注意到当我单击断开连接时,服务器会立即检测到断开连接,我如何使用我的 esp 客户端实现相同的结果?
这里是客户端代码
#include "BLEDevice.h"
//BLE Server name (the other ESP32 name running the server sketch)
#define bleServerName "bc1"
#define connection_LED 21
/* UUID's of the service, characteristic that we want to read*/
// BLE Service
static BLEUUID ServiceUUID("4fafc201-1fb5-459e-8fcc-c5c9c331914b");
// BLE state Characteristic
static BLEUUID stateCharacteristicUUID("beb5483e-36e1-4688-b7f5-ea07361b26a8");
//Flags stating if should begin connecting and if the connection is up
static boolean doConnect = false;
static boolean connected = false;
static boolean doScan = false;
//Address of the peripheral device. Address will be found during scanning...
static BLEAddress *pServerAddress;
//Characteristic that we want to read
static BLERemoteCharacteristic* stateCharacteristic;
//Activate notify
const uint8_t notificationOn[] = {0x1, 0x0};
const uint8_t notificationOff[] = {0x0, 0x0};
//Flags to check whether new state readings are available
boolean newstate = false;
class MyClientCallback : public BLEClientCallbacks {
void onConnect(BLEClient* pclient) {
digitalWrite(connection_LED, HIGH);
}
void onDisconnect(BLEClient* pclient) {
digitalWrite(connection_LED, LOW);
connected = false;
}
};
//Connect to the BLE Server that has the name, Service, and Characteristics
bool connectToServer(BLEAddress pAddress) {
BLEClient* pClient = BLEDevice::createClient();
pClient->setClientCallbacks(new MyClientCallback());
// Connect to the remote BLE Server.
pClient->connect(pAddress);
Serial.println(" - Connected to server");
// Obtain a reference to the service we are after in the remote BLE server.
BLERemoteService* pRemoteService = pClient->getService(ServiceUUID);
if (pRemoteService == nullptr) {
Serial.print("Failed to find our service UUID: ");
Serial.println(ServiceUUID.toString().c_str());
pClient->disconnect();
return (false);
}
Serial.println(" - Found our service");
// Obtain a reference to the characteristics in the service of the remote BLE server.
stateCharacteristic = pRemoteService->getCharacteristic(stateCharacteristicUUID);
if (stateCharacteristic == nullptr) {
Serial.print("Failed to find our characteristic UUID");
Serial.println(charUUID.toString().c_str());
pClient->disconnect();
return false;
}
Serial.println(" - Found our characteristics");
//Assign callback functions for the Characteristics
stateCharacteristic->registerForNotify(stateNotifyCallback);
return true;
}
//Callback function that gets called, when another device's advertisement has been received
class MyAdvertisedDeviceCallbacks: public BLEAdvertisedDeviceCallbacks {
void onResult(BLEAdvertisedDevice advertisedDevice) {
if (advertisedDevice.getName() == bleServerName) { //Check if the name of the advertiser matches
advertisedDevice.getScan()->stop(); //Scan can be stopped, we found what we are looking for
pServerAddress = new BLEAddress(advertisedDevice.getAddress()); //Address of advertiser is the one we need
doConnect = true; //Set indicator, stating that we are ready to connect
doScan = true;
Serial.println("Device found. Connecting!");
}
}
};
//When the BLE Server sends a new state reading with the notify property
static void stateNotifyCallback(BLERemoteCharacteristic* pBLERemoteCharacteristic,
uint8_t* pData, size_t length, bool isNotify) {
newstate = true;
}
void setup() {
pinMode(connection_LED, OUTPUT);
//Start serial communication
Serial.begin(115200);
Serial.println("Starting Arduino BLE Client application...");
Serial.println("waiting for a server connection...");
//Init BLE device
BLEDevice::init("");
// Retrieve a Scanner and set the callback we want to use to be informed when we
// have detected a new device. Specify that we want active scanning and start the
// scan to run for 30 seconds.
BLEScan* pBLEScan = BLEDevice::getScan();
pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks());
pBLEScan->setActiveScan(true);
pBLEScan->start(30);
}
void loop() {
// If the flag "doConnect" is true then we have scanned for and found the desired
// BLE Server with which we wish to connect. Now we connect to it. Once we are
// connected we set the connected flag to be true.
if (doConnect == true) {
if (connectToServer(*pServerAddress)) {
Serial.println("We are now connected to the BLE Server.");
//Activate the Notify property of each Characteristic
stateCharacteristic->getDescriptor(BLEUUID((uint16_t)0x2902))->writeValue((uint8_t*)notificationOn, 2, true);
connected = true;
} else {
Serial.println("We have failed to connect to the server; Restart your device to scan for nearby BLE server again.");
}
doConnect = false;
}
if(connected){
//if new state readings are available,
if (newstate){
newstate = false;
std::string value = stateCharacteristic->readValue();
Serial.println(value);
}
} else if(doScan){
Serial.println("Disconnected from server");
Serial.println("rescan");
BLEDevice::getScan()->start(0); // starting scan after disconnect
}
}
您可以访问以调用 BLEServer::onDisconnect 方法结束的实际 GATT 事件流。
GATT 客户端和服务器都有事件。这些在 esp_gattc_api.h 和 esp_gatts_api.h 中列举了
例如,您可以在初始化之前设置一个自定义的GATT handler。在处理 GATT 事件(挂钩模式)后立即调用处理程序。
static void my_gatts_event_handler(esp_gatts_cb_event_t event, esp_gatt_if_t gatts_if, esp_ble_gatts_cb_param_t* param) {
// Do stuff depending on event type
// Eg. 'listen' to GATT events in realtime (very star trek).
// tone(2000 + event*200, volume, delay);
}
在你的设置中()
BLEDevice::setCustomGattsHandler(my_gatts_event_handler);
BLEDevice::init(SERVICE_NAME);
您会看到(听到)GATT 事件在 BLEServer::onDisconnect() 被调用之前发送。您可以在断开连接流程的早期做一些事情,但请记住 BLEServer 依赖于此流程来调用 onDisconnect();