【问题标题】:Unable to read BLE characteristic with Windows Bluetooth APIs无法使用 Windows 蓝牙 API 读取 BLE 特征
【发布时间】:2017-09-30 16:41:45
【问题描述】:

我有一个 Adafruit Bluefruit UART Friend 模块 (https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend/introduction),我正在尝试制作一个通用 Windows 应用程序,我可以从中读取蓝牙数据。我按照微软页面上显示的步骤成功连接到设备,但是当尝试从特定 RX 特征读取数据时,我在控制台中得到 System.ArgumentException。我检查了特征上的标志,看起来 READ 标志返回 false,只有 NOTIFY 标志为 true。是否有可能我没有阅读正确的特征?我从 Adafruit 网站获得了 UUID:https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend/uart-service 这是我的 C# 代码示例:`

public static async Task connectToAddress() {

      Guid guid = new Guid("6e400001b5a3f393e0a9e50e24dcca9e"); // Base UUID for UART service
      Guid charachID = new Guid("6e400003b5a3f393e0a9e50e24dcca9e"); // RX characteristic UUID

      deviceReference = await BluetoothLEDevice.FromBluetoothAddressAsync(_deviceAddress);
      GattDeviceServicesResult result = await deviceReference.GetGattServicesAsync();

      var characs = await result.Services.Single(s => s.Uuid == guid).GetCharacteristicsAsync();
      var charac = characs.Characteristics.Single(c => c.Uuid == charachID);

      GattCharacteristicProperties properties = charac.CharacteristicProperties;

      if (properties.HasFlag(GattCharacteristicProperties.Read))
            {
            Debug.Write("This characteristic supports reading from it.");
            }
      if (properties.HasFlag(GattCharacteristicProperties.Write))
            {
            Debug.Write("This characteristic supports writing.");
            }
      if (properties.HasFlag(GattCharacteristicProperties.Notify))
            {
            Debug.Write("This characteristic supports subscribing to notifications.");
            }

      GattReadResult data = await charac.ReadValueAsync();
      Debug.WriteLine("DATA: " + data.ToString());

      charac.ValueChanged += Characteristic_ValueChanged;

        }`

【问题讨论】:

  • 在您的调试中。写你使用相同的行进行读取和写入(“此特性支持从中读取。”。首先修复此问题。
  • 谢谢,但我仍然无法读取特征。

标签: c# bluetooth win-universal-app bluetooth-lowenergy


【解决方案1】:

因为你是在连接后才读取数据,所以可能没有什么要读取的。

你的 Bledevice 是一个 UART 服务,所以我确信它会发送一个通知让你知道有什么要读取,或者数据在通知本身中。

如果数据在通知中,则从 Charac_ValueChanged 事件中的 GattValueChangedEventArgs 中获取。 否则在 Charac_ValueChanged 中读取它。

你收到的数据是 IBuffer 格式的。要将 IBuffer 转换为字符串,我将在代码示例中展示。 使用 Windows.Security.Cryptography 添加到您的代码中。

代码示例编译正常,但不要指望它“开箱即用”,我看不到您的其余代码,也无法访问 Ble 设备。 使用调试器并设置断点来检查代码。

 static GattCharacteristic charac = null;

  public static async Task connectToAddress()
  {
     Guid guid = new Guid("6e400001b5a3f393e0a9e50e24dcca9e"); // Base UUID for UART service
     Guid charachID = new Guid("6e400003b5a3f393e0a9e50e24dcca9e"); // RX characteristic UUID

     deviceReference = await BluetoothLEDevice.FromBluetoothAddressAsync(_deviceAddress);
     GattDeviceServicesResult result = await deviceReference.GetGattServicesAsync();
     //Allways check result!
     if (result.Status == GattCommunicationStatus.Success)
     {
        //Put following two lines in try/catch to or check for null!!
        var characs = await result.Services.Single(s => s.Uuid == guid).GetCharacteristicsAsync();
        //Make charac a field so you can use it in Charac_ValueChanged.
         charac = characs.Characteristics.Single(c => c.Uuid == charachID);
        GattCharacteristicProperties properties = charac.CharacteristicProperties;
        if (properties.HasFlag(GattCharacteristicProperties.Read))
        {
           Debug.Write("This characteristic supports reading from it.");
        }
        if (properties.HasFlag(GattCharacteristicProperties.Write))
        {
           Debug.Write("This characteristic supports writing.");
        }
        if (properties.HasFlag(GattCharacteristicProperties.Notify))
        {
           Debug.Write("This characteristic supports subscribing to notifications.");
        }
        try
        {
           //Write the CCCD in order for server to send notifications.               
           var notifyResult = await charac.WriteClientCharacteristicConfigurationDescriptorAsync(
                                                     GattClientCharacteristicConfigurationDescriptorValue.Notify);
           if (notifyResult == GattCommunicationStatus.Success)
           {

              Debug.Write("Successfully registered for notifications");
           }
           else
           {
              Debug.Write($"Error registering for notifications: {notifyResult}");
           }
        }
        catch (UnauthorizedAccessException ex)
        {
           Debug.Write(ex.Message);
        }


        charac.ValueChanged += Charac_ValueChangedAsync; ;
     }
     else
     {
        Debug.Write("No services found");
     }
  }

  private static async void Charac_ValueChangedAsync(GattCharacteristic sender, GattValueChangedEventArgs args)
  {
     CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out byte[] data);
     string dataFromNotify;
     try
     {
        //Asuming Encoding is in ASCII, can be UTF8 or other!
        dataFromNotify = Encoding.ASCII.GetString(data);
        Debug.Write(dataFromNotify);
     }
     catch (ArgumentException)
     {
        Debug.Write("Unknown format");
     }
     GattReadResult dataFromRead = await charac.ReadValueAsync();        
     CryptographicBuffer.CopyToByteArray(dataFromRead.Value, out byte[] dataRead);
     string dataFromReadResult;
     try
     {
        //Asuming Encoding is in ASCII, can be UTF8 or other!
        dataFromReadResult = Encoding.ASCII.GetString(dataRead);
        Debug.Write("DATA FROM READ: " + dataFromReadResult);
     }
     catch (ArgumentException)
     {
        Debug.Write("Unknown format");
     }
  }

也没有必要让你的方法成为静态的。我将 dat 保持原样,因此更容易将其与您的代码进行比较。

希望对你有所帮助。

【讨论】:

  • 非常感谢您的回复。我尝试了您提供的代码,但我进入控制台“注册通知时出错:无法访问”。当我尝试连接我的模块时,这与我从 Bluetooth LE Explorer windows 应用程序得到的响应相同。也许是我的设备问题?我需要一些特殊权限才能连接到它吗?我正在使用的 Bluefruit LE 使用 nRF51822 芯片,我正在尝试从 BT-400 加密狗连接。即使我不能订阅通知,我仍然可以看到服务和特征。
  • 在您应用的 Package.appxmanifest 中,您必须将功能设置为蓝牙。在 Visual Studio 中执行此操作的简单方法是在解决方案资源管理器中右键单击您的项目并选择属性。在应用程序部分单击包清单并选择功能选项卡并选择蓝牙。如果这不是您配置 Adafruit Bluefruit UART 朋友错误的解决方案。再次执行 Adafruit 指令以将其设置为 UART 服务。
  • 我重新配置了我的 Bluefruit 并在我的 arduino 上使用了数据模式草图。现在一切都很完美。非常感谢您的回答,对我帮助很大!
猜你喜欢
  • 2014-05-05
  • 2018-05-29
  • 2016-07-26
  • 2021-12-21
  • 2023-03-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多