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

时间:2017-09-30 16:41:46

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

我有一个 Adafruit Bluefruit UART Friend 模块(https://learn.adafruit.com/introducing-the-adafruit-bluefruit-le-uart-friend/introduction),我正在尝试制作一个通用Windows应用程序,我可以从中读取蓝牙数据。我按照微软页面上显示的步骤并成功连接到设备但是当尝试从特定的RX特性读取数据时,我在控制台中得到 System.ArgumentException 。我检查了特征上的标志,看起来READ标志返回false,只有NOTIFY标志为真。我有可能没有阅读正确的特征吗?我从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;

        }`

1 个答案:

答案 0 :(得分:2)

因为您在连接后正在阅读数据,所以可能无需阅读。

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

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

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

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

 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");
     }
  }

也没有必要让你的方法成为STATIC。我保留了原样的数据,因此将它与您的代码进行比较更容易。

希望这会对你有所帮助。