В настоящей статье рассмотрим как использовать в своих приложениях на С Sharp BLE в Windows. Напишем небольшую программу по сканированию BLE устройств. Подключимся к сервису и прочитаем его характеристики.
Подключение библиотеки BLE
Для того, что бы иметь возможность работать с BLE в windows, в разделе using подключите следующее пространство имен
using Windows.Devices.Bluetooth.Advertisement;
using Windows.Devices.Bluetooth;
ВНИМАНИЕ! Данное пространство имен можно использовать только в Windows 10 и выше.
Сканирование BLE в Windows
Рассмотрим пример кода на C Sharp по сканированию BLE устройств.
private BluetoothLEAdvertisementWatcher _watcher;
private Dictionary<ulong, BluetoothLEDevice> _devices;
private BluetoothLEDevice dev;
private List<String> AdressBLE = new List<String>();
private void btnSearchBLE_Click(object sender, EventArgs e)
{
listDevice.Items.Clear();
AdressBLE.Clear();
_devices.Clear();
if (_watcher == null)
_watcher = new BluetoothLEAdvertisementWatcher();
_watcher.Stop();
_watcher.SignalStrengthFilter.InRangeThresholdInDBm = -110;
_watcher.SignalStrengthFilter.OutOfRangeThresholdInDBm = -110;
_watcher.ScanningMode = BluetoothLEScanningMode.Active;
_watcher.Received += Wather_Recived;
_watcher.Start();
}
private async void Wather_Recived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{
dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
if (dev != null)
{
if (!_devices.ContainsKey(args.BluetoothAddress))
{
_devices.Add(args.BluetoothAddress, dev);
listDevice.Invoke(new Action(() =>
{
String Name = "";
String Addrr = dev.BluetoothAddress.ToString();
AdressBLE.Add(Addrr);
if (dev.Name == null)
Name = "None";
else
Name = dev.Name;
int item = listDevice.Items.IndexOf(Addrr + " " + Name);
if (item == -1)
listDevice.Items.Add(dev.BluetoothAddress + " " + Name);
}));
}
}
}
Результат выполнения данного кода представлен на рисунке ниже:

Сканирование показало 5 устройств поддерживающих BLE.
Подключение к BLE в Windows
Подключение к BLE в Windows приведено в следующем коде:
private async void btnConnectBLE_Click(object sender, EventArgs e)
{
trView.Nodes.Clear();
// Подключаемся к устройству по адресу
dev = await BluetoothLEDevice.FromBluetoothAddressAsync(Convert.ToUInt64(AdressBLE.ElementAt(IndexBLENow)));
if (dev != null)
{
//получаем все возможные сервисы
var servisesResult = await dev.GetGattServicesAsync();
if (servisesResult.Status == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success)
{
// Проходим по всем сервисам и получаем характеристики
var services = servisesResult.Services;
for (int j = 0; j < services.Count;j++)
{
var service = services[j];
trView.Nodes.Add($"Служба - {service.Uuid}");
var characteristicsResult = await service.GetCharacteristicsAsync();
if (characteristicsResult.Status == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success)
{
var characteristics = characteristicsResult.Characteristics;
var characteristic = characteristics[0];
for (int i = 0; i < characteristics.Count; i++)
{
trView.Nodes[trView.Nodes.Count - 1].Nodes.Add($"Характеристика - {characteristic.Uuid}");
}
characteristic.Service.Dispose();
}
service.Session.Dispose();
}
}
}else MessageBox.Show("Не могу подключить устройство!");
}
После подключения, мы получаем все сервисы данного устройства, а так же их характеристики. Ниже приведен рисунок с результатом работы данного кода.

Чтение и запись в характеристику BLE
Прочитать и записать можно в характеристику, если она имеет модификатор записи и чтения. Если не знать протокола обмена с устройством, то наши попытки записи прибор проигнорирует. Ниже приведен код для записи в характеристику с нужным номером сервиса.
private void frMain_Load(object sender, EventArgs e)
{
_devices = new Dictionary<ulong, BluetoothLEDevice>();
}
private async void btnSendtxt_Click(object sender, EventArgs e)
{
String guu = value;
if (guu.Contains("Характеристика"))
{
guu = guu.Replace("Характеристика - ", "");
String GuuiServis = "000000ff-0000-1000-8000-00805f9b34fb";
if (dev != null)
dev.Dispose();
dev = await BluetoothLEDevice.FromBluetoothAddressAsync(Convert.ToUInt64(AdressBLE.ElementAt(IndexBLENow)));
if (dev != null)
{
var servisesResult = await dev.GetGattServicesForUuidAsync(Guid.Parse(GuuiServis));
if (servisesResult.Status == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success)
{
var services = servisesResult.Services;
var service = services[0];
try
{
var characteristicsResult = await service.GetCharacteristicsForUuidAsync(Guid.Parse(guu));
if (characteristicsResult.Status == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success)
{
var characteristics = characteristicsResult.Characteristics;
for (int i = 0; i < characteristics.Count; i++)
{
var characteristic = characteristics[i];
if (characteristic.Uuid == Guid.Parse(guu))
{
var property = characteristic.CharacteristicProperties;
String Data = tbSendTxt.Text;
byte[] input = new byte[Data.Length];
input = Encoding.Default.GetBytes(Data);
var writer = new DataWriter();
writer.WriteBytes(input);
var result = await characteristic.WriteValueAsync(writer.DetachBuffer());
}
}
}
service.Dispose();
}
catch
{
}
}
}
}
}
Так же приведем пример кода для чтения характеристики:
if (dev != null)
{
var servisesResult = await dev.GetGattServicesForUuidAsync(Guid.Parse(GuuiServis));
if (servisesResult.Status == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success)
{
var services = servisesResult.Services;
var service = services[0];
try
{
//var characteristicsResult = await service.GetCharacteristicsForUuidAsync(Guid.Parse(guu));
var characteristicsResult = await service.GetCharacteristicsAsync();
if (characteristicsResult.Status == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success)
{
var characteristics = characteristicsResult.Characteristics;
for (int i = 0; i < characteristics.Count; i++)
{
var characteristic = characteristics[i];
if (characteristic.Uuid == Guid.Parse(guu))
{
var result = await characteristic.ReadValueAsync(BluetoothCacheMode.Uncached);
if (result.Status == Windows.Devices.Bluetooth.GenericAttributeProfile.GattCommunicationStatus.Success)
{
var val = DataReader.FromBuffer(result.Value);
byte[] input = new byte[val.UnconsumedBufferLength];
val.ReadBytes(input);
label1.Text = "Значение характеристики: " + System.Text.Encoding.ASCII.GetString(input);
}
characteristic.Service.Dispose();
}
}
}
service.Session.Dispose();
characteristicsResult = null;
servisesResult = null;
}
catch
{
}
}
}
}
ВНИМАНИЕ! Обратите внимание на модификатор BluetoothCacheMode.Uncached. Если данные изменяются постоянно, то необходимо его использовать. С другим модификатором данные не будут обновляться.
У меня не получилось добиться высокой скорости взаимодействия с устройством через BLE. Скорее всего, это из-за того, что я постоянно переподключаюсь к устройству. Что занимает время. К сожалению данная библиотека не работает в системах ниже Windows 10.



