2017年4月20日 豆包柠檬树

Windows上的蓝牙4.0BLE心率设备数据采集

本文所述方法在windows 10 1703(创意者更新)无法使用,在之前的版本没有问题,不知道之后的版本是否会修复,所以现在暂且先用1607等版本的win10禁止大更新使用了,详情见 https://developercommunity.visualstudio.com/content/problem/57636/gattdeviceservicefromidasync-broken-on-winforms-ap.html

最近开发了Windows系统上的心率功率墙,用到了蓝牙设备数据采集。

因为BLE比用SPP方便很多,所以连接现代蓝牙4.0+心率或其他BLE传感器获得数据要比以前省事很多,对于可以主动通知主机的设备,大致步骤如下:

  1. 在Windows建立配对,通常没有密码或者是六个零,如果不对的话,看看说明书。
  2. 用Windows SDK里的Windows.Devices.Enumeration.DeviceInformation.FindAllAsync获得对应类别的设备列表并枚举。
  3. 对于遍历的每一个设备,用蓝牙空间里的GattDeviceService.FromIdAsync得到service。
  4. 用得到的service对象的GetCharacteristics得到characteristic。
  5. 把characteristic的ValueChanged绑定指定的事件处理函数。
  6. 用characteristic的WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);设定主动通知模式。
  7. 在指定的事件处理函数中用DataReader.FromBuffer(args.CharacteristicValue).ReadBytes得到设备主动发来的数据。

工程源代码下载链接:(里面也同时提供了MSDN提供的针对Windows8.1 StoreApp的蓝牙心率采集demo,但默认启动工程没有用那个,也没有依赖)

BLEHeartRateReceiver

值得注意的是,在微软提供的demo里进行了一系列额外没用的设置,比如数据可加密、超范围断线回来自动重连,而那些都是不必要的,因为山寨设备都不加密,而且自动重连完全可以在更顶层统一实现,效率也并不会差多少。更重要的是,在微软的demo直接用.Net Core而不用FrameWork会带来很多额外的麻烦,比如连接数据库、使用Redis或其他Windows上的第三方组件等,既然是在Windows用不考虑跨平台,就没有必要用那个demo的方式了,因为即便用UWP、.Net Core,蓝牙BLE操作对Windows SDK的依赖也导致了无法直接用于其他平台(WindowsPhone基本没人用,我直接把demo里那个csproj给删了- -||),不如直接用我后来写的WinForm。(但目前如文章最开始所述,这个方法在版本1703行不通了,只能用store app,UWP操作其他东西非常麻烦。不知道是微软故意的还是bug,但愿下个版本能继续用吧)