无法使用 Windows 蓝牙 API 读取 BLE 特性

Unable to read BLE characteristic with Windows Bluetooth APIs

我有一个 Adafruit Bluefruit UART Friend 模块(https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend/introduction) and i am trying to make an Universal Windows App from which i can read the bluetooth data. I followed the steps showed on the microsoft page and succesfully connected to the device but when trying to read the data from the specific RX characteristic, i get System.ArgumentException in console. I checked the flags on the characteristic and it looks like th READ flag return false, only the NOTIFY flag being true. Is it possible that I am not reading the right characteristic? I got the UUID from Adafruit site: 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;

        }`

因为刚连接就在读数据,所以可能没有什么可读的。

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

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

中阅读

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

代码示例编译正常,但不要指望它能工作 "out of the box",我看不到您的其余代码,也无法访问 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 原样,因此更容易将它与您的代码进行比较。

希望对您有所帮助。