如何通过BLE从Flutter应用向ESP32发送Struct数据?
通过BLE从Flutter向ESP32发送Struct数据的实现方案
完全可行。BLE通信的核心是传输字节流,只要将Struct数据序列化为字节数组,就能通过BLE特征值发送,ESP32端再将字节数组反序列化为Struct即可。
Flutter端实现步骤
- 选用BLE插件:使用
flutter_blue_plus(主流稳定的BLE插件),在pubspec.yaml中添加依赖:dependencies: flutter_blue_plus: ^1.13.3 - 定义模拟Struct的Dart类,并实现序列化方法:
class SensorData { int deviceId; // 4字节 double temperature; // 8字节 int humidity; // 4字节 SensorData({required this.deviceId, required this.temperature, required this.humidity}); // 序列化为字节数组,注意字节序和ESP32端统一 List<int> toBytes() { final buffer = ByteData(4 + 8 + 4); buffer.setInt32(0, deviceId, Endian.little); buffer.setFloat64(4, temperature, Endian.little); buffer.setInt32(12, humidity, Endian.little); return buffer.buffer.asUint8List(); } } - 连接设备并发送数据:
// 假设已获取目标BLE设备device和可写特征characteristic final sensorData = SensorData(deviceId: 1001, temperature: 25.5, humidity: 60); List<int> bytes = sensorData.toBytes(); // 发送字节数组,withoutResponse设为false确保可靠传输 await characteristic.write(bytes, withoutResponse: false);
ESP32端实现步骤
- 定义对应C语言Struct,强制取消内存对齐避免字节偏移:
typedef struct __attribute__((packed)) { int deviceId; // 4字节 double temperature; // 8字节 int humidity; // 4字节 } SensorData; - 配置BLE服务与可写特征:
使用ESP-IDF的BLE库(如NimBLE)创建GATT服务,添加具备WRITE权限的特征值,并绑定写入回调函数。 - 接收并反序列化数据:
在回调函数中直接将字节数组转换为Struct:void ble_write_callback(uint16_t conn_handle, uint16_t attr_handle, struct ble_gatt_access_ctxt *ctxt) { // 检查接收字节长度是否匹配Struct大小 if (ctxt->om->om_len != sizeof(SensorData)) { printf("数据长度不匹配\n"); return; } SensorData *data = (SensorData *)ctxt->om->om_data; // 处理解析后的数据 printf("设备ID: %d\n", data->deviceId); printf("温度: %.2f\n", data->temperature); printf("湿度: %d\n", data->humidity); }
关键注意事项
- 字节序统一:两端必须使用相同的字节序(如小端序),否则数值解析会出错。
- 内存对齐处理:C语言Struct默认会有内存对齐,必须用
__attribute__((packed))确保字节布局和Flutter端一致。 - 特征值长度:确保BLE特征值的最大长度能容纳Struct的字节数,若Struct较大需配置更大的MTU。
- 错误校验:两端都要检查数据长度,避免越界访问或解析错误。
内容的提问来源于stack exchange,提问作者Jatin Saini
相关产品推荐
相关产品推荐

