蓝牙外设通讯协议设计
市场上比较流行的分为有链接的BLE和无链接的Beacon方式,我们以流程的ESP32-C2为例子,进行说明,您可以基于此代码扩展自已的情趣应用。我们将设计两种通讯方式:一种是通过有链接的BLE(Bluetooth Low Energy),另一种是通过蓝牙Beacon实现的无连接通讯。
1. 有链接的BLE通讯协议
通讯流程:
- 连接建立:设备通过BLE与控制端(如手机应用)配对连接。
- 命令发送:控制端发送命令(如振动强度、模式切换)到设备。
- 数据反馈:设备可以返回状态信息(如电量、连接状态)。
命令结构:
- 振动命令格式:
0x01
+强度值
(0-100) - 模式切换:
0x02
+模式编号
(0-5)
ESP32-C2实现代码:
#include <BLEDevice.h>
#include <BLEServer.h>
#include <BLEUtils.h>
#include <BLE2902.h>
#define SERVICE_UUID "12345678-1234-1234-1234-123456789abc"
#define CHARACTERISTIC_UUID "abcdef12-1234-1234-1234-abcdef123456"
BLEServer *pServer = NULL;
BLECharacteristic *pCharacteristic = NULL;
void setup() {
Serial.begin(115200);
BLEDevice::init("BLE Vibrator");
pServer = BLEDevice::createServer();
BLEService *pService = pServer->createService(SERVICE_UUID);
pCharacteristic = pService->createCharacteristic(
CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ |
BLECharacteristic::PROPERTY_WRITE
);
pCharacteristic->setCallbacks(new MyCallbacks());
pService->start();
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->addServiceUUID(SERVICE_UUID);
pAdvertising->setScanResponse(true);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
BLEDevice::startAdvertising();
Serial.println("Waiting for a client connection to notify...");
}
void loop() {
// 振动控制逻辑可以根据接收到的命令执行
}
class MyCallbacks: public BLECharacteristicCallbacks {
void onWrite(BLECharacteristic *pCharacteristic) {
std::string rxValue = pCharacteristic->getValue();
if (rxValue.length() > 0) {
Serial.println("Received Value: ");
for (int i = 0; i < rxValue.length(); i++)
Serial.print(rxValue[i]);
Serial.println();
if (rxValue[0] == 0x01) {
int intensity = rxValue[1];
// 调整振动强度
} else if (rxValue[0] == 0x02) {
int mode = rxValue[1];
// 切换振动模式
}
}
}
};
``### **2. 通过蓝牙Beacon实现的无连接通讯**
**通讯流程:**
- **信号广播**:设备周期性广播包含命令或状态的Beacon信号。
- **信号解析**:控制端接收并解析Beacon数据,以了解设备状态或发送简单命令。
**命令结构:**
- 振动强度通过广播包的特定字节表示。
- 数据广播周期可设置为100ms或更长,以节省电力。
**ESP32-C2实现代码:**
```cpp
#include <BLEDevice.h>
#include <BLEUtils.h>
#include <BLEBeacon.h>
#include <esp_sleep.h>
void setup() {
Serial.begin(115200);
BLEDevice::init("BLE Beacon Vibrator");
BLEBeacon beacon;
beacon.setManufacturerId(0x4C00);
beacon.setProximityUUID(BLEUUID("12345678-1234-1234-1234-123456789abc"));
beacon.setMajor(1);
beacon.setMinor(100); // Vibrator intensity or mode can be encoded here
BLEAdvertising *pAdvertising = BLEDevice::getAdvertising();
pAdvertising->setScanResponse(false);
pAdvertising->setMinPreferred(0x06);
pAdvertising->setMinPreferred(0x12);
pAdvertising->setAdvertisementType(ADV_TYPE_NONCONN_IND);
BLEAdvertisementData oAdvertisementData = BLEAdvertisementData();
oAdvertisementData.setFlags(0x04);
oAdvertisementData.setManufacturerData(beacon.getData());
pAdvertising->setAdvertisementData(oAdvertisementData);
pAdvertising->start();
Serial.println("Beacon broadcasting...");
esp_sleep_enable_timer_wakeup(1000000); // 1 second deep sleep
esp_deep_sleep_start();
}
void loop() {
// Beacon广播间歇性地运行以节省电力
}
小程序代码示例
以下是一个简单的微信小程序代码片段,用于接收BLE广播数据:
Page({
data: {
devices: [],
},
onLoad: function() {
wx.openBluetoothAdapter({
success: (res) => {
wx.startBluetoothDevicesDiscovery({
services: [],
allowDuplicatesKey: false,
success: (res) => {
console.log('Bluetooth discovery started');
}
});
}
});
wx.onBluetoothDeviceFound((res) => {
const devices = this.data.devices;
res.devices.forEach(device => {
if (device.name === "BLE Beacon Vibrator") {
devices.push(device);
this.setData({ devices });
}
});
});
},
});
总结
通过这两种蓝牙通讯方式,可以灵活地控制和监控ESP32-C2蓝牙设备。BLE模式适合需要双向通信和实时控制的场景,而Beacon模式则适合简单的状态广播和节能应用。使用ESP32-C2实现这些功能可以极大地简化开发过程,并通过微信小程序实现用户友好的控制界面。