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

Flutter中Movesense传感器固件更新时设备断连问题求助

解决Movesense固件更新时设备断开导致DFU失败的问题

问题核心是:Movesense进入DFU更新模式时会重启并切换到专门的DFU蓝牙广播,原有的BLE连接会被主动断开。你现在在设备刚连接时就直接触发DFU,此时设备还没完成模式切换断开,导致Nordic DFU无法正确连接到DFU模式下的设备。

直接给你可行的修改方案:

1. 增加DFU模式标记,区分断开类型

在当前逻辑作用域或BleDevice类中添加一个布尔标记,用来识别这次断开是进入DFU模式导致的,而非正常断开:

bool _isInitiatingDfu = false;

2. 修改固件更新方法,仅触发设备进入DFU模式

不要在startDeviceFirmwareUpdate里直接调用NordicDfu.startDfu,先只发送进入更新模式的请求,后续设备断开后再启动DFU:

@override
Future<void> startDeviceFirmwareUpdate(String serial, int value) async {
  final Map<String, int> contract = {"NewState": value};
  await MdsAsync.put(Mds.createRequestUri(serial, "/System/Mode"), jsonEncode(contract));
  // 这里不再直接调用startDfu,等待设备断开后处理
}

3. 调整连接回调逻辑,在断开时启动DFU

修改connectMovesenseBleDeviceById的回调,当触发DFU模式后,在设备断开时启动Nordic DFU:

void connectMovesenseBleDeviceById({
  required BleDevice device,
  required VoidCallback onConnect,
  required VoidCallback onDisconnect,
}) {
  bleDataSource.connectMovesenseDeviceById(
    device.id,
    onConnnect: (serial) async {
      final metaData = await bleDataSource.getMovesenseSensorInfo(device.serial);
      final deviceAppData = await bleDataSource.getMovesenseSensorAppInfo(device.serial);
      device.metaData = metaData;
      device.appData = deviceAppData;

      // 标记即将进入DFU模式
      _isInitiatingDfu = true;
      // 触发设备进入更新模式
      bleDataSource.startDeviceFirmwareUpdate(device.serial, 12);

      // 保留原有正常连接逻辑
      if (device.metaData!.isCompatible && device.appData!.isCompatible) {
        onConnect();
        bleDeviceLocalDataSource.persistBleDevice(bleDeviceModel: device as BleDeviceModel);
      }
      if (!_connectedDevicesStreamController.isClosed)
        _connectedDevicesStreamController.add(
          device.copyWith(status: BleDeviceConnectionStatus.connected) as BleDeviceModel
        );
    },
    onDisconnect: () {
      // 如果是DFU模式触发的断开,启动DFU流程
      if (_isInitiatingDfu) {
        _isInitiatingDfu = false; // 重置标记
        // 启动Nordic DFU,DFU模式下设备蓝牙地址通常不变
        NordicDfu().startDfu(
          device.id,
          'assets/dfu.zip',
          fileInAsset: true,
          onDeviceDisconnecting: (string) => print('deviceAddress: $string'),
          onDeviceConnected: (address) => print("device is connected"),
          onDeviceConnecting: (address) => print("Device is connecting"),
          forceDfu: true,
          onError: (address, error, errorType, message) => 
            print(" error  $error, errorType: $errorType, message: $message"),
          onProgressChanged: (deviceAddress, percent, speed, avgSpeed, currentPart, partsTotal) => 
            print('deviceAddress: $deviceAddress, percent: $percent'),
        );
      } else {
        // 正常断开逻辑
        onDisconnect();
        if (!_connectedDevicesStreamController.isClosed)
          _connectedDevicesStreamController.add(
            device.copyWith(status: BleDeviceConnectionStatus.disconnected) as BleDeviceModel
          );
      }
    },
    onError: () {
      throw BluetoothException('Error occured when pairing the device');
    },
  );
}

额外注意事项

  • 确保你的Nordic DFU包版本兼容Movesense的DFU模式,forceDfu: true必须开启,因为DFU模式下的设备没有正常的GATT服务。
  • 极少数情况下,Movesense进入DFU模式后蓝牙地址可能会变化,如果出现连接失败,需要添加扫描逻辑,找到名称带"DFU"标识的设备,再用新地址启动DFU。

内容的提问来源于stack exchange,提问作者Aymen Ziouche

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 13:07:29