Arduino与Flutter通过HM-10蓝牙模块通信:写入正常但无法读取数据的问题排查
嘿,我看了你的代码,知道你为啥读不到数据了——问题主要出在没开启蓝牙特征的通知功能,还有监听逻辑的小问题,咱们一步步来解决:
问题根源
HM-10蓝牙模块的FFE1特征(你代码里的writeUuid)默认需要开启**通知(Notify)**才能主动接收设备发来的数据。你之前只用了read()方法——这个方法是主动拉取一次当前特征的静态值,但Arduino是在收到指令后才回复数据,这时候需要设备主动推送数据,所以必须先开启通知功能。
解决方案步骤
1. 在Flutter中开启蓝牙特征的通知并实时监听
修改你的discoverServices方法,找到目标特征后立即开启通知,同时设置持续监听:
discoverServices() async { var services = await _targetDevice.discoverServices(); services.forEach((service) { if (service.uuid.toString() == uuid) { service.characteristics.forEach((characteristic) { if (characteristic.uuid.toString() == writeUuid) { targetCharacteristic = characteristic; // 开启通知,让设备主动推送数据 await characteristic.setNotifyValue(true); // 持续监听数据推送 characteristic.value.listen((data) { String msg = utf8.decode(data).trim(); // 去除多余空白符 print("收到蓝牙数据: $msg"); // 这里可以把数据同步给UI,比如调用notifyListeners()更新状态 }); print("已准备好与${targetDevice.name}通信"); } }); } }); }
2. 修正readData方法(可选)
如果还是需要主动拉取数据,确保先开启通知再调用read(),不过更推荐上面的实时监听方式:
readData() async { if (targetCharacteristic == null) return; // 确保通知已开启 await targetCharacteristic!.setNotifyValue(true); // 主动读取一次当前数据 List<int> decode = await targetCharacteristic!.read(); String msg = utf8.decode(decode).trim(); print("主动读取到数据: $msg"); }
3. Arduino端优化数据输出
为了避免数据截断或粘包,建议发送数据时加上换行符,方便Flutter端解析完整数据包:
char inputdata = 0; //Variable for storing received data void setup() { Serial.begin(9600); //Sets the baud rate for bluetooth pins } void loop() { if(Serial.available() > 0) // Send data only when you receive data: { inputdata = Serial.read(); //Read the incoming data & store into data // If a measurement is required, measure data and send it back if ( inputdata == 't'){ int t = 32; int m =7200; String data = (String(t)+','+String(m)); Serial.println(data); // 用println代替print,自动添加换行符 }else if(inputdata == 'g') { String temp = "32"; Serial.println(temp); // 同样添加换行符 } } }
4. 额外注意事项
- 确保HM-10模块的波特率和Arduino的
Serial.begin(9600)完全一致,否则会出现乱码或数据丢失。 - 在Flutter页面销毁时,记得取消特征值的监听订阅(比如调用
subscription.cancel()),避免内存泄漏。
这样修改后,当你调用writeData('t')发送指令,Arduino回复的数据会自动通过蓝牙通知推送到Flutter的监听回调里,你就能正常收到数据了。
内容的提问来源于stack exchange,提问作者Vidura Karunarathna
相关产品推荐
相关产品推荐

