You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 18:12:34