Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/sorting/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 仅针对写入后的第一次更改执行BLE特征更改回调_C#_Bluetooth_Notifications_Bluetooth Lowenergy_Gatt - Fatal编程技术网

C# 仅针对写入后的第一次更改执行BLE特征更改回调

C# 仅针对写入后的第一次更改执行BLE特征更改回调,c#,bluetooth,notifications,bluetooth-lowenergy,gatt,C#,Bluetooth,Notifications,Bluetooth Lowenergy,Gatt,我尝试使用典型方法订阅BLE特征通知: stCharacteristic = stService.GetCharacteristics(stCharacteristicGUID)[0]; await stCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); stCharacteristic.

我尝试使用典型方法订阅BLE特征通知:

stCharacteristic = stService.GetCharacteristics(stCharacteristicGUID)[0];
await stCharacteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
stCharacteristic.ValueChanged += stData_ValueChanged;
回调函数还有标准形式:

async void stData_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
    var values = (await sender.ReadValueAsync()).Value.ToArray();
}
问题是,当BLE设备更改特征值时,并不总是调用回调。当我向特征写入内容,设备在响应中写入内容时,调用回调。但是,如果设备本身写入特征,则不会调用回调。有趣的是数据没有丢失。当我再次写一些东西时,我会收到几个回调调用,同时会收到BLE设备发送的所有数据。换句话说,它看起来像是Windows或.NET Framework缓存后续传入的数据,直到写入。在只写之后,第一个特性更改会触发回调

  • 传入数据-无回调
  • 发送数据
  • 传入数据-两次回调
  • 发送数据
  • 传入数据-一次回调
  • 传入数据
  • 传入数据
  • 传入数据
  • 发送数据-三次回调

Windows 10,VS2015

您不必读取ValueChanged回调中的值。该值已存在于GattValueChangedEventArgs中


除此之外,您的处理程序应该直接调用,而不是在写入之后调用。您能看到您的设备是否在通知之间断开/连接吗?

原来是Windows 10的问题。在Windows10.0.15063和更新版本上,比如10.0.16251,情况更糟——根本没有回调。幸运的是,有一个简单的解决方法,需要添加两个注册表项。以下是.reg文件:

Windows Registry Editor Version 5.00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\{C6BFD646-3DF0-4DE5-B7AF-5FFFACB844A5}]
"AccessPermission"=hex:01,00,04,80,9c,00,00,00,ac,00,00,00,00,00,00,00,14,00,\
  00,00,02,00,88,00,06,00,00,00,00,00,14,00,07,00,00,00,01,01,00,00,00,00,00,\
  05,0a,00,00,00,00,00,14,00,03,00,00,00,01,01,00,00,00,00,00,05,12,00,00,00,\
  00,00,18,00,07,00,00,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00,00,\
  00,18,00,03,00,00,00,01,02,00,00,00,00,00,0f,02,00,00,00,01,00,00,00,00,00,\
  14,00,03,00,00,00,01,01,00,00,00,00,00,05,13,00,00,00,00,00,14,00,03,00,00,\
  00,01,01,00,00,00,00,00,05,14,00,00,00,01,02,00,00,00,00,00,05,20,00,00,00,\
  20,02,00,00,01,02,00,00,00,00,00,05,20,00,00,00,20,02,00,00

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\AppID\YOURAPP.exe]
"AppID"="{C6BFD646-3DF0-4DE5-B7AF-5FFFACB844A5}"
将YOURAPP.exe更改为您的exe文件名。GUID可以更改或保持原样。应用此.reg文件后,每次都会立即调用回调,并且收到的通知非常好


在写下这个答案的时候,微软正在研究一个永久的修复方案。解决方法和讨论在这里:

是的,你是对的,我可以从args获取数据,我相信它更优雅。设备未断开连接。我可以在设备的日志中看到它。此外,如果存在断开连接,我将无法向characteristic进行写入。与此同时,我观察到了一件有趣的事情。设备可以发送大于特征大小(20字节)的数据包。在这种情况下,它将数据包分成20字节的块。我一个接一个地得到所有的块,没有任何问题。因此,回调不仅针对第一个块执行。当回调立即触发时,写入后似乎有一个时间窗口。