BLE в Windows. C sharp.

В настоящей статье рассмотрим как использовать в своих приложениях на С 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);
                        }));
                }
             }          
        }  

Результат выполнения данного кода представлен на рисунке ниже:

Пример на C Sharp сканирования BLE устройств

Сканирование показало 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, чтение сервиса и характеристик

Чтение и запись в характеристику 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.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest
0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии