Hello World pour recevoir des données d'un appareil Bluetooth (BLE) via C #

Bon après-midi

Il y a quelques semaines, j'ai été confronté au problème qu'il n'y a tout simplement pas d'article normal et moderne sur la première réception de données avec Bluetooth . Et j'ai dû le bricoler pour comprendre par où commencer et comment le faire. Et pour que les gens ne répètent pas mes erreurs, voici un court essai sur la façon de procéder.



Mais d'abord, quelques mots pathétiques, pour lesquels cela est généralement nécessaire. Le monde moderne est de plus en plus plongé dans l'idéologie de l'Internet des objets. Maintenant, tout interagit, un réfrigérateur avec une cuisinière, un fer à repasser avec un aspirateur, etc. Beaucoup de bruit a été soulevé en raison de l'ECG dans l'Apple Watch, mais les tensiomètres modernes, les moniteurs de fréquence cardiaque et les thermomètres ont depuis longtemps été en mesure de transmettre des données via Bluetooth. Et tout cela doit en quelque sorte être connecté à un seul réseau. Et l'élément clé de ce réseau est, quoi qu'on en dise, un ordinateur. À cet égard, la tâche s'est posée de recevoir des données d'un appareil spécifique via Bluetooth.

Pour commencer, ce que nous avions déjà et ce qui a exacerbé la recherche d'une solution. Et nous avions une application écrite en .Net Core . L'essence de l'application est sans importance, pour simplifier, nous supposerons que nous avons juste une console sur .Net Core . Eh bien, l'appareil s'appellera la lettre N.

Les premières tentatives pour trouver quelque chose qui fonctionne avec Bluetooth via C # mèneront à la bibliothèque 32feet .

Dans les packages NuGet, cela ressemble à 32feet.NET .

Et elle, d'ailleurs, dans sa dernière édition de produit, trouve même des appareils Bluetooth, mais pas la norme BLE [comme il s'est avéré beaucoup plus tard]. Par exemple, le même OnePlus 5T a été recherché de manière stable, mais le périphérique N nécessaire ne l' est pas. Parallèlement à cela, la réponse officielle de l'auteur a été trouvée que sa bibliothèque n'interagit pas en principe avec BLE, et il n'y a aucun intérêt à essayer. Bien qu'il existe une version préliminaire d' InTheHand.Devices.Bluetooth sur Github qui devrait prendre en charge BLE, tout a tellement changé et il n'y a aucune documentation du tout qu'il n'a même pas fonctionné pour compiler le projet avec des idées tirées de 32feet.NET .

De nouvelles recherches m'ont conduit à des solutions plus standard, à savoir la plateforme Windows universelle ( UWP ). En développant cette plate-forme, Microsoft , embrassé par l'idée de polyvalence et d'une seule application pour un ordinateur et un téléphone, a essayé et fait l'interaction avec Bluetooth. Et ici, tout fonctionne bien, mais ... Nous avons un projet sur .Net Core ... Et il n'y a rien à faire.

Je dois dire tout de suite que nous n'avons pas pu trouver de solutions pour l'interaction des bibliothèques UWP avec .Net Core et le projet a dû être basculé vers 4.7.1. , l'avantage n'est pas difficile. Bien qu'il y ait eu des réflexions sur la façon de laisser le projet sur .Net Core et, par exemple, de créer un service Windows séparé avec transfert de données via des canaux nommés (tube nommé) ou de monter un service WCF et d'établir une interaction avec lui, mais dans notre cas, cela n'avait pas de sens.



Donc au final on a avant le départ:

  • Projet sur 4.7.1.
  • Win10 a été mis à jour vers la version 10.0.17134 Build 17134.

Vous devez d'abord connecter quelques bibliothèques avec des stylos, à savoir

  • «Windows de la plateforme Windows universelle»
    C: \ Program Files (x86) \ Kits Windows \ 10 \ UnionMetadata \ 10.0.17134.0 \ Windows.winmd
  • "System.Runtime.WindowsRuntime"
    C: \ Program Files (x86) \ Reference Assemblies \ Microsoft \ Framework \ .NETCore \ v4.5 \ System.Runtime.WindowsRuntime.dll

Et en fait tout, le travail avec l'appareil lui-même passe sans problème par la documentation.
Interagissez avec BLE via la classe BluetoothLEAdvertisementWatcher
Mais nous ne devons pas oublier que sans l'API de l'appareil lui-même, quelque chose de sensé ne fonctionne pas.

Voici mon exemple de code sur la façon d'obtenir des données à partir d'un appareil.

Ce code est conçu pour garantir que l'appareil a déjà été ajouté (connecté).

public class BluetoothObserver { BluetoothLEAdvertisementWatcher Watcher { get; set; } public void Start() { Watcher = new BluetoothLEAdvertisementWatcher() { ScanningMode = BluetoothLEScanningMode.Active }; Watcher.Received += Watcher_Received; Watcher.Stopped += Watcher_Stopped; Watcher.Start(); } private bool isFindDevice { get; set; } = false; private async void Watcher_Received(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args) { if (isFindDevice) return; if (args.Advertisement.LocalName.Contains("deviceName")) { isFindDevice = true; BluetoothLEDevice bluetoothLeDevice = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress); GattDeviceServicesResult result = await bluetoothLeDevice.GetGattServicesAsync(); if (result.Status == GattCommunicationStatus.Success) { var services = result.Services; foreach (var service in services) { if (!service.Uuid.ToString().StartsWith("serviceName")) { continue; } GattCharacteristicsResult characteristicsResult = await service.GetCharacteristicsAsync(); if (characteristicsResult.Status == GattCommunicationStatus.Success) { var characteristics = characteristicsResult.Characteristics; foreach (var characteristic in characteristics) { if (!characteristic.Uuid.ToString().StartsWith("characteristicName")) { continue; } GattCharacteristicProperties properties = characteristic.CharacteristicProperties; if (properties.HasFlag(GattCharacteristicProperties.Indicate)) { characteristic.ValueChanged += Characteristic_ValueChanged; GattWriteResult status = await characteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(GattClientCharacteristicConfigurationDescriptorValue.Indicate); return; } if (properties.HasFlag(GattCharacteristicProperties.Read)) { GattReadResult gattResult = await characteristic.ReadValueAsync(); if (gattResult.Status == GattCommunicationStatus.Success) { var reader = DataReader.FromBuffer(gattResult.Value); byte[] input = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(input); // input } } } } } } } } private void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) { var reader = DataReader.FromBuffer(args.CharacteristicValue); byte[] input = new byte[reader.UnconsumedBufferLength]; reader.ReadBytes(input); // input } private void Watcher_Stopped(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementWatcherStoppedEventArgs args) { ; } } 

Merci de votre attention.

Source: https://habr.com/ru/post/fr423893/


All Articles