分析:初步怀疑是连接参数,iOS有自己规定的蓝牙连接参数,如果不符合,会发生这种情况。而我使用的是arduino IDE进行开发,只发现了BLEServer类下的updateConnParams()函数是设置连接参数的,但需要在连接成功后的回调中设置,试了不管用,而且我理解设置连接参数应该是在setup阶段就设置吧。。
求问各位大佬,如何解决?以下附上我的代码。
Code: Select all
#include <Arduino.h>
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
uint8_t txValue = 0; // 后面需要发送的值
BLEServer *pServer = NULL; // BLEServer指针 pServer
BLECharacteristic *pTxCharacteristic = NULL; // BLECharacteristic指针 pTxCharacteristic
bool deviceConnected = false; // 本次连接状态
bool oldDeviceConnected = false; // 上次连接状态
const int relay = 2; // 定义继电器 IN 引脚连接的引脚。
// See the following for generating UUIDs: https://www.uuidgenerator.net/
#define SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define CHARACTERISTIC_UUID_WRITE "12a59e0a-17cc-11ec-9621-0242ac130002"
#define CHARACTERISTIC_UUID_NOTIFY "12a5a148-17cc-11ec-9621-0242ac130002"
class MyServerCallbacks : public BLEServerCallbacks {
void onConnect(BLEServer *pServer, esp_ble_gatts_cb_param_t *param) {
// void updateConnParams(esp_bd_addr_t remote_bda, uint16_t minInterval, uint16_t maxInterval, uint16_t latency, uint16_t timeout);
// iOS BLE要求的连接参数
// •Interval Max * (Slave Latency + 1) <= 2 s
// •Interval Max >= 20 ms
// •Interval Min + 20 ms <= Interval Max
// •Slave Latency <= 4
// •ConnSupervisionTimeout <= 6 s
// •Interval Max * ( Slave Latency + 1) * 3 < ConnSupervisionTimeout
uint16_t latency = 2; // 潜伏期,单位:xx个数据包
uint16_t maxInterval = 50; // 最大连接间隔,单位:ms
uint16_t minInterval = 20; // 最小连接间隔,单位:ms
uint16_t timeout = 3000; // 超时时间,单位:ms
// 设置连接参数
// pServer->updateConnParams(param->connect.remote_bda, minInterval, maxInterval, latency, timeout);
deviceConnected = true;
Serial.println("onConnect");
};
void onDisconnect(BLEServer *pServer) {
deviceConnected = false;
// // 关闭服务
// pService->stop();
// 关闭广播
// pServer->getAdvertising()->stop();
Serial.println("onDisconnect");
}
};
class MyCallbacks : public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
// 接收信息
std::string signal = pCharacteristic->getValue();
int switchValue = atoi(signal.c_str());
// 1开 2关
if (switchValue == 1) {
digitalWrite(relay, HIGH);
Serial.println("turn on");
} else if (switchValue == 2) {
digitalWrite(relay, LOW);
Serial.println("turn off");
} else {
Serial.print("unknown signal...");
Serial.println(switchValue);
}
}
};
void setup() {
// 设置波特率
Serial.begin(115200);
// 将继电器定义为输出。
pinMode(relay, OUTPUT);
setupBLE("ESP32-BLE"); //设置蓝牙名称
}
void setupBLE(String BLEName) {
// 将传入的BLE的名字转换为指针
const char *ble_name = BLEName.c_str();
// 初始化一个蓝牙设备
BLEDevice::init(ble_name);
// 创建一个蓝牙服务器
BLEServer *pServer = BLEDevice::createServer();
// 服务器回调函数设置为MyServerCallbacks
pServer->setCallbacks(new MyServerCallbacks());
// 创建一个BLE服务
BLEService *pService = pServer->createService(SERVICE_UUID);
// 创建一个NOTIFY特征 通知特征
pTxCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_NOTIFY, BLECharacteristic::PROPERTY_NOTIFY);
// 为特征添加一个描述
pTxCharacteristic->addDescriptor(new BLE2902());
// 创建一个WRITE特征 写入特征
BLECharacteristic *pCharacteristic = pService->createCharacteristic(CHARACTERISTIC_UUID_WRITE, BLECharacteristic::PROPERTY_WRITE);
// 为特征添加一个回调
pCharacteristic->setCallbacks(new MyCallbacks());
// 开启服务
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID); //设置服务UUID
pAdvertising->setScanResponse(true); //开启扫描响应(?)
pAdvertising->setMinPreferred(0x06); // 解决ipone手机连接问题,functions that help with iPhone connections issue
pAdvertising->setMinPreferred(0x12);
// 服务器开始广播
BLEDevice::startAdvertising(); //开始广播
Serial.println("Waiting a client connection to notify...");
}
void loop() {
// // deviceConnected 已连接
// if (deviceConnected) {
// pTxCharacteristic->setValue(&txValue, 1); // 设置要发送的值为1
// pTxCharacteristic->notify(); // 广播
// txValue++; // 指针数值自加1
// delay(5000); // 如果有太多包要发送,蓝牙会堵塞
// Serial.print("deviceConnected txValue = ");
// Serial.println(txValue);
// }
// disconnecting 断开连接
if (!deviceConnected && oldDeviceConnected) {
delay(500); // 留时间给蓝牙缓冲
pServer->startAdvertising(); // 重新广播
// 服务器开始广播
// pServer->getAdvertising()->start();
Serial.println("startAdvertising");
oldDeviceConnected = deviceConnected;
}
// connecting 正在连接
if (deviceConnected && !oldDeviceConnected) {
// do stuff here on connecting
oldDeviceConnected = deviceConnected;
Serial.println("connecting");
}
}