【问题标题】:Windows 10 Bluetooth Low Energy Connection c#Windows 10 蓝牙低功耗连接 c#
【发布时间】:2015-10-01 16:49:09
【问题描述】:

对于一个项目,我需要使用 C# 从 Windows 10 上的蓝牙设备获取一些数据。我对蓝牙 API 不太熟悉,无法弄清楚为什么以下内容不起作用:

使用BluetoothLEAdvertisementWatcher 搜索广告,效果很好。我确实收到了来自设备的广告(本地名称适合)以及ServiceUuids。接下来我尝试使用与广告一起收到的BluetoothAddress 连接到设备:

private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, 
                    BluetoothLEAdvertisementReceivedEventArgs eventArgs)
{
    ulong blAdress = eventArgs.BluetoothAddress;
    BluetoothLEDevice blDevice = await 
         Windows.Devices.Bluetooth.BluetoothLEDevice.FromBluetoothAddressAsync(blAdress);
}

但是,这样做会导致异常:

未找到元素。 (HRESULT 异常:0x80070490)。

这是从设备读取数据的正确方法吗?是否有其他选项可用于从服务中读取数据?在 Windows 中手动配对设备并不是一个真正的选择,而且似乎也失败了。

/Edit 1:我检查设备的本地名称以确保我只尝试连接到正确的设备。所以我猜想连接到这个特定设备有问题,但我仍然不知道如何解决这个问题。服务数据在iOS上读取成功,应该是可以的。

【问题讨论】:

    标签: c# windows bluetooth bluetooth-lowenergy windows-10


    【解决方案1】:

    在 MS 解决这个问题之前,我发现连接到 BLE 设备的唯一可靠解决方案是向注册表询问配对 BLE 设备的列表,并将广告中的蓝牙地址与配对的注册表列表进行比较设备。我的经验是,当在未配对的设备上调用 FromBluetoothAddressAsync 时,Windows 会引发异常并终止观察者线程。我有一些我很乐意分享的 C++ 代码,它读取注册表并创建配对的 BLE 设备列表。

    希望 MS 能够像 Apple 一样花时间全面支持 BLE。

    【讨论】:

    • 嗨,你能分享这个代码吗?谢谢
    【解决方案2】:

    这是来自 MS (https://social.msdn.microsoft.com/Forums/vstudio/en-US/e321cb3c-462a-4b16-b7e4-febdb3d0c7d6/windows-10-pairing-a-ble-device-from-code?forum=wdk) 的参考。似乎要使用此 BluetoothLEDevice.FromBluetoothAddressAsync,我们必须在设备正在广告但尚未配对时处理异常。

    【讨论】:

      【解决方案3】:

      当我直接使用 BluetoothLEAdvertisementWatcher 时,我遇到了同样的问题。

      然后我测试了观察者列出的不同地址。我发现它与蓝牙设备有关。

      添加如下过滤器后,我可以成功连接到GATT设备(TI Sensor Tag)。

      public sealed partial class MainPage : Page
      {
          private BluetoothLEAdvertisementWatcher watcher;
      
          public MainPage()
          {
              this.InitializeComponent();
      
              // Create and initialize a new watcher instance.
              watcher = new BluetoothLEAdvertisementWatcher();
      
              // Part 1B: Configuring the signal strength filter for proximity scenarios
      
              // Configure the signal strength filter to only propagate events when in-range
              // Please adjust these values if you cannot receive any advertisement 
              // Set the in-range threshold to -70dBm. This means advertisements with RSSI >= -70dBm 
              // will start to be considered "in-range".
              watcher.SignalStrengthFilter.InRangeThresholdInDBm = -70;
      
              // Set the out-of-range threshold to -75dBm (give some buffer). Used in conjunction with OutOfRangeTimeout
              // to determine when an advertisement is no longer considered "in-range"
              watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -75;
      
              // Set the out-of-range timeout to be 2 seconds. Used in conjunction with OutOfRangeThresholdInDBm
              // to determine when an advertisement is no longer considered "in-range"
              watcher.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);
      
              // By default, the sampling interval is set to zero, which means there is no sampling and all
              // the advertisement received is returned in the Received event
      
              // End of watcher configuration. There is no need to comment out any code beyond this point.
          }
      
      
          protected override void OnNavigatedTo(NavigationEventArgs e)
          {
              watcher.Received += OnAdvertisementReceived;
      
              watcher.Stopped += OnAdvertisementWatcherStopped;
      
              App.Current.Suspending += App_Suspending;
      
              App.Current.Resuming += App_Resuming;
          }
      
      
          protected override void OnNavigatingFrom(NavigatingCancelEventArgs e)
          {
              App.Current.Suspending -= App_Suspending;
              App.Current.Resuming -= App_Resuming;
      
              watcher.Stop();
      
              watcher.Received -= OnAdvertisementReceived;
              watcher.Stopped -= OnAdvertisementWatcherStopped;
      
              base.OnNavigatingFrom(e);
          }
      
      
          private void App_Suspending(object sender, Windows.ApplicationModel.SuspendingEventArgs e)
          {
              // Make sure to stop the watcher on suspend.
              watcher.Stop();
              // Always unregister the handlers to release the resources to prevent leaks.
              watcher.Received -= OnAdvertisementReceived;
              watcher.Stopped -= OnAdvertisementWatcherStopped;
      
          }
      
          private void App_Resuming(object sender, object e)
          {
              watcher.Received += OnAdvertisementReceived;
              watcher.Stopped += OnAdvertisementWatcherStopped;
          }
      
          private async void OnAdvertisementReceived(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementReceivedEventArgs eventArgs)
          {
              var address = eventArgs.BluetoothAddress;
      
              BluetoothLEDevice device = await BluetoothLEDevice.FromBluetoothAddressAsync(address);
      
              var cnt =device.GattServices.Count;
      
              watcher.Stop();
          }
      
          /// <summary>
          /// Invoked as an event handler when the watcher is stopped or aborted.
          /// </summary>
          /// <param name="watcher">Instance of watcher that triggered the event.</param>
          /// <param name="eventArgs">Event data containing information about why the watcher stopped or aborted.</param>
          private void OnAdvertisementWatcherStopped(BluetoothLEAdvertisementWatcher watcher, BluetoothLEAdvertisementWatcherStoppedEventArgs eventArgs)
          {
      
          }
      
          private void start_Click(object sender, RoutedEventArgs e)
          {
              watcher.Start();
          }
      }
      

      【讨论】:

      • 你的代码很相似,但我试了一下。可悲的是,一旦我调用“BluetoothLEDevice device = ...”,就会引发相同的异常:(这是设备特定的问题吗?你知道任何解决方法吗?
      【解决方案4】:

      只是一个猜测,但也许你需要这个:

      watcher.ScanningMode = BluetoothLEScanningMode.Active;
      

      在 OnAdvertisementReceived 事件中

      if (e.AdvertisementType == BluetoothLEAdvertisementType.ScanResponse)
      {
        BluetoothLEDevice blDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(e.BluetoothAddress);
      }
      

      【讨论】:

        【解决方案5】:

        如果这是一个 UWP 项目,请确保启用蓝牙功能。

        为此,请在 Visual Studio 解决方案资源管理器中双击 *.appxmanifest,选择“功能”选项卡并确保选中“蓝牙”。

        它会添加一些与以下类似的xml;

        <Capabilities>
            <Capability Name="internetClientServer" />
            <DeviceCapability Name="bluetooth" />
        </Capabilities>

        【讨论】:

          【解决方案6】:

          这个问题已经超过 3 年了,但是因为它有超过 13000 的浏览量,所以我会回答。 Element not found 的原因是 Windows.Devices 在配对或连接之前不知道广告 Ble 设备。 而是在 OnAdvertisementReceived 中使用:

           var device = await BluetoothLEDevice.FromBluetoothAddressAsync(eventArgs.BluetoothAddress);
          

          我在 github 上也有一个非常简单的 uwp 示例,它没有控制以使其尽可能简单。所有结果都显示在调试输出窗口中。 最有用的信息在 MainPage.xaml.cs 中

          查看:https://github.com/GrooverFromHolland/SimpleBleExample_by_Devicename

          【讨论】:

            猜你喜欢
            • 2014-09-10
            • 2012-10-17
            • 1970-01-01
            • 1970-01-01
            • 2013-11-17
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多