Подключитесь к устройству BTLE с помощью 32feet.net, используя уникальный сервисный протокол.

У меня есть устройство Bluetooth с низким энергопотреблением (BTLE), которое мне нужно подключить к компьютеру. Для этого я использую справочник Windows API в настольном приложении WPF.

Устройство bluetooth достаточно простое: 1 служба, 2 характеристики (одна для чтения/уведомления, одна для записи).

To make below code work, add the following references to the WPF (for windows 10):
C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETCore\v4.5\System.Runtime.WindowsRuntime.dll
C:\Program Files (x86)\Windows Kits\10\UnionMetadata\Windows.winmd

Код Windows API для C#

public GattDeviceService BLEService;
public GattCharacteristic BLEData_ReadNotify;
public GattCharacteristic BLEData_Write;
private static readonly Guid Guid_service = new Guid("25FB9E91-1616-448D-B5A3-F70A64BDA73A");
public static readonly Guid Characteristics_ReadNotify = new Guid("C3FBC9E2-676B-9FB5-3749-2F471DCF07B2");
public static readonly Guid Characteristics_Write = new Guid("D6AF9B3C-FE92-1CB2-F74B-7AFB7DE57E6D");


// Find all BTLE devices that have the service Guid: Guid_service
public void findandconnect() { 
    var BTLEdeviceList = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(Guid_service));
    // lets assume at least one device is found, store it's id.
    id = BTLEdeviceList[0].id;

    // Connect to the SERVICE of the device
    BLEService = await GattDeviceService.FromIdAsync(id);

    // Get the first "ReadNotify" characteristics of that service
    BLEData_ReadNotify = BLEService.GetCharacteristics(Characteristics_ReadNotify).First();
    // If that value changes, update an event
    BLEData_ReadNotify.ValueChanged += BLEData_ValueChanged;

    // Also get the first "write" characteristics of that service
    BLEData_Write = BLEService.GetCharacteristics(Characteristics_Write).First();
    // and tell that characteristics to NOTIFY me if the BTLE device has an update.
    await BLEData_ReadNotify.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);
    // Successfully connected

    // Send the command "RUN\r" to the write characteristics, to let it start to execute the program
    byte[] buffer = Encoding.ASCII.GetBytes("RUN" + "\r");
    IBuffer ibuffer = buffer.AsBuffer();
    // Sending "RUN"
    await BLEData_Write.WriteValueAsync(ibuffer);
}
// And here should be some event function for the ValueChanged

Ну, вроде как работает... Он чертовски нестабилен, большую часть времени выдает неразрешимые ошибки:

Строка: BLEData_ReadNotify.WriteClientCharacteri... выдает Нет ключа сеанса пользователя для указанного сеанса входа в систему. (Исключение из HRESULT: 0x80070572)

и Период ожидания семафора истек. (Исключение из HRESULT: 0x80070079). Эта вторая ошибка встречается реже и появляется, когда скрипт сначала ничего не получает, потом через таймер пытается снова отправить команду RUN, потом все крашится и появляется ошибка.

Поискав в stackoverflow и на многих сайтах, я обнаружил, что обе вышеуказанные ошибки решить невозможно. Отсюда мой вопрос:

Можно ли переписать приведенный выше код с помощью 32Feet.net?

В 2012 году это было невозможно #13438440">ссылка на использование ble вообще, но, возможно, теперь это так? Используя метод сканирования в этом ответе ссылка, я МОГУ найти свое устройство BLE, когда оно НЕ сопряжено.

Итак, я попробовал код

// mac is mac address of local bluetooth device
Guid Guid_service = new Guid("25FB9E91-1616-448D-B5A3-F70A64BDA73A");
localEndpoint = new BluetoothEndPoint(myRadio.LocalAddress, Guid_service);
// client is used to manage connections
localClient = new BluetoothClient(localEndpoint);

BluetoothAddress a = new BluetoothAddress(new byte[] { 180, 99, 76, 86, 31, 21 });
Guid Guid_service = new Guid("25FB9E91-1616-448D-B5A3-F70A64BDA73A");
localClient.Connect(a, Guid_service);

NetworkStream stream = localClient.GetStream();

но я застрял на строке localClient.Connect с ошибкой: Произошло исключение типа «System.Net.Sockets.SocketException». Дополнительная информация: Попытка подключения не удалась, так как подключенная сторона не ответила должным образом через некоторое время, или не удалось установить подключение, поскольку подключенный узел не ответил

Можно ли переписать код Windows API в 32feet.net, если да, то как это сделать?

Примечание. Я пытался подключиться к устройству BT2.1 с помощью собственного кода .net для Windows, но последовательный порт нестабилен и вызывает головную боль. С 32feet.net теперь он прекрасно работает через SerialPort, очень стабильно и каждый раз подключается!


person Jeffrey    schedule 12.11.2015    source источник
comment
Любое решение, которое вы получили для этого? Я тоже ищу такой же.   -  person Bit_Pulse    schedule 15.02.2017
comment
Решение состоит в том, чтобы использовать Windows 8+ и использовать WinRT API. Найдите что-нибудь вроде того, как включить winRT в настольное приложение C#. После включения WinRT API вы можете использовать его вызовы Bluetooth, что позволяет подключаться к устройствам BT 2.1, а также к устройствам BT4. У меня где-то валяется код, но сейчас нет времени. Комментарий, если вам нужен код, и я опубликую его как можно скорее.   -  person Jeffrey    schedule 15.02.2017
comment
Да, чувак, пожалуйста, опубликуй код или ссылку, которая когда-либо возможна для тебя. Спасибо.   -  person Bit_Pulse    schedule 15.02.2017
comment
не повезло найти этот код? Я пробовал так, как сказал, но получаю ошибку FileNotFound в await GattDeviceService.FromIdAsync(device.Id)   -  person Bit_Pulse    schedule 16.02.2017
comment
У меня есть два устройства iOS, которые безупречно обмениваются данными, но когда я пробую приведенный выше код (ноутбук с Windows 10 на устройство iOS), я всегда получаю 0 устройств в списке устройств.   -  person Paul    schedule 12.12.2017


Ответы (1)


У меня была аналогичная проблема с этим, связанным с

время ожидания семафора истекло. (Исключение из HRESULT: 0x80070079).

Моя проблема была решена с помощью .net 4.7.1. Также мне нужно было убедиться, что у меня установлена ​​последняя версия драйвера Microsoft Bluetooth для устройства Bluetooth, которое я использовал.

Потоки SerialPort больше не завершают процесс при возникновении исключений в фоновом потоке. Это может произойти при отключении последовательного порта USB во время использования. Это новое поведение управляется переключателем AppContext Switch.System.IO.Ports.DoNotCatchSerialStreamThreadExceptions. Для этого переключателя установлено значение truetf get по умолчанию при использовании .NET 4.7 или более ранней версии. [428461, System.dll, ошибка]

https://github.com/Microsoft/dotnet/blob/0745983093568027ff931672d9db021e3e120b5b/releases/net471/dotnet471-changes.md

Обновление: на самом деле это две проблемы в одной. Ошибка .net и проблема с прошивкой, из-за которой устройство никогда не включало модуль Bluetooth.

person nate_weldon    schedule 30.10.2017