我想通过在 Visual Studio 2017 中使用通用 Windows 平台 C# 中的 ValueChanged 回调,继续从我的 BLE 4.0 设备中读取特征/设置值更改的事件处理程序。
我遵循了这些站点的一些教程:Damian Blog 的 Windows Universal with BLE、Bluetooth Gatt 的 Git Hub、Bluetooth Generic Attribute Profile - Heart Rate Service和Dr. Jukka 的 BLE 移动博客。他们所有人都在使用 ValueChanged,我试图遵循他们的做法。
不幸的是,我在使用 ValueChanged 回调时收到以下错误,而不是触发 ValueChanged。
System.ArgumentException: 'Value does not fall within the expected range.'
这行代码正在产生错误:
characteristic.ValueChanged += Oncharacteristic_ValueChanged;
这是我的源代码的更多详细信息:
注意:我为我的加密狗使用 COM 7,我的程序可以发现 BLE 的设备名称,并且可以发现服务和特征的 Uuid。
public List<string> serviceList = new List<string>();
public List<string> characteristicList = new List<string>();
public BluetoothLEDevice myDevice { get; set; }
public MainPage()
{
this.InitializeComponent();
}
private async void Page_Loaded(object sender, RoutedEventArgs e)
{
// Find the com port
string selector = SerialDevice.GetDeviceSelector("COM7");
DeviceInformationCollection devices = await DeviceInformation.FindAllAsync(selector);
if (devices.Count > 0)
{
var dialog = new MessageDialog("Com Device found");
await dialog.ShowAsync();
DeviceInformation deviceInfo = devices[0];
SerialDevice serialDevice = await SerialDevice.FromIdAsync(deviceInfo.Id);
serialDevice.BaudRate = 9600;
serialDevice.DataBits = 8;
serialDevice.StopBits = SerialStopBitCount.One;
serialDevice.Parity = SerialParity.None;
}
else
{
MessageDialog popup = new MessageDialog("Sorry, no device found.");
await popup.ShowAsync();
}
// After com port is found, search for device
foreach (DeviceInformation di in await DeviceInformation.FindAllAsync(BluetoothLEDevice.GetDeviceSelector()))
{
BluetoothLEDevice bleDevice = await BluetoothLEDevice.FromIdAsync(di.Id);
// Display BLE device name
var dialogBleDeviceName = new MessageDialog("BLE Device Name " + bleDevice.Name);
await dialogBleDeviceName.ShowAsync();
myDevice = bleDevice;
}
// Check device connection
myDevice.ConnectionStatusChanged += OnConnectionStatusChanged;
foreach (var service in myDevice.GattServices)
{
serviceList.Add(service.Uuid.ToString());
// Verify if service is discovered by displaying a popup
MessageDialog serviceUuidPopUp = new MessageDialog("Adding Service Uuid to list " + service.Uuid.ToString() );
await serviceUuidPopUp.ShowAsync();
foreach (var characteristic in service.GetAllCharacteristics())
{
var characteristicUuid = characteristic.Uuid.ToString().ToLowerInvariant();
characteristicList.Add(characteristicUuid);
// Verify if characteristic is discovered by displaying a popup
MessageDialog charUuidPopUp = new MessageDialog("Adding characteristic Uuid to list " + characteristicUuid);
await charUuidPopUp.ShowAsync();
// set value changed event handlers for characteristics
characteristic.ValueChanged += Oncharacteristic_ValueChanged;
}
}
}
private void OnConnectionStatusChanged(BluetoothLEDevice sender, object args)
{
if (sender.ConnectionStatus == BluetoothConnectionStatus.Connected)
{
System.Diagnostics.Debug.WriteLine("Connected");
}
else
{
System.Diagnostics.Debug.WriteLine("Disconnected");
}
}
private void Oncharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
{
byte[] data = new byte[args.CharacteristicValue.Length];
DataReader.FromBuffer(
args.CharacteristicValue).ReadBytes(data);
string text = Encoding.UTF8.GetString(data, 0, data.Length);
}
更新 1 我尝试在设置值更改事件处理程序之前检查特性属性,方法是按照rudi belt 在 SO 上给出的答案。
if (characteristic.CharacteristicProperties == (GattCharacteristicProperties.Read | GattCharacteristicProperties.Notify))
{
characteristic.ValueChanged += Oncharacteristic_ValueChanged;
}
不幸的是,这个 IF 语句没有被执行。
更新 2 我试图删除Oncharacteristic_ValueChanged方法中的所有代码。但它仍然给我同样的错误
System.ArgumentException: 'Value does not fall within the expected range.'
我花了很多时间试图解决这个问题。如果有人可以帮助我,我将非常高兴。谢谢!