使用独特的服务协议使用 32feet.net 连接到 BTLE 设备

Posted

技术标签:

【中文标题】使用独特的服务协议使用 32feet.net 连接到 BTLE 设备【英文标题】:Connect to BTLE device using 32feet.net using unique service protocol 【发布时间】:2016-02-13 06:05:45 【问题描述】:

我有一个低功耗蓝牙 (BTLE) 设备,我需要将其连接到我的 PC。为此,我在桌面 WPF 应用程序中使用了 Windows API 参考。

蓝牙设备相当简单: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

用于 C# 的 Windows API 代码

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 命令,然后全部崩溃并出现错误。

在***和许多网站上搜索,我发现以上两个错误都无法解决。因此我的问题是:

上面的代码可以用 32Feet.net 重写吗?

在 2012 年,link 根本不可能使用 ble,但也许现在可以了?使用此答案link 中的扫描方法,当它未配对时,我可以找到我的 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”类型的异常。 附加信息:连接尝试失败,因为连接方在一段时间后没有正确响应,或者连接失败,因为连接的主机没有响应

可以在32feet.net中重写windows API代码吗,如果可以,如何进行?

注意:我尝试使用 windows 原生 .net 代码连接到 BT2.1 设备,但串口不稳定,头疼。有了 32feet.net,它现在可以在 SerialPort 上出色地工作,非常稳定并且每次都能连接!

【问题讨论】:

你有什么解决方案吗?我也在找一样的。 解决方法是使用windows 8+,并利用winRT API。搜索“如何在桌面 C# 应用程序中包含 winRT”之类的内容。包含 WinRT API 后,您可以使用它的蓝牙调用,它允许您连接到 BT 2.1 以及 BT4 设备。我有代码在某个地方,但现在没有时间。如果您需要代码,请发表评论,我会尽快发布。 是的,请张贴您可能的代码或链接。谢谢。 运气好能找到那个代码吗?我尝试了所说的方式,但在await GattDeviceService.FromIdAsync(device.Id) 中出现FileNotFound 错误 我有两台 ios 设备完美通信,但是当我尝试上面的代码(Windows 10 笔记本电脑到 iOS 设备)时,设备列表中总是有 0 个设备。 【参考方案1】:

我对此有类似的问题

信号量超时期限已过。 (来自 HRESULT 的异常:0x80070079)。

.net 4.7.1 解决了我的问题。我还需要确保我使用的蓝牙设备拥有最新的微软蓝牙驱动程序

当后台线程发生异常时,SerialPort 流不再终止进程。在使用中移除 USB 串行端口时可能会发生这种情况。此新行为由 Switch.System.IO.Ports.DoNotCatchSerialStreamThreadExceptions AppContext 开关控制。当面向 .NET 4.7 或更低版本时,此开关默认设置为 truetf get。 [428461,System.dll,错误]

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

更新:实际上它似乎是 2 个问题合二为一。 .net 错误和固件问题,设备永远不会重新打开蓝牙模块。

【讨论】:

以上是关于使用独特的服务协议使用 32feet.net 连接到 BTLE 设备的主要内容,如果未能解决你的问题,请参考以下文章

MQTT比TCP协议好在哪儿

ESP32学习笔记(33)——BLE GATT客户端发现服务和读写特征值

使用stm32开发板利用lwip协议做TCP客户端,怎样检测发出的数据是不是被PC服务端收到?

玩转 ESP32 + Arduino (十六) 通过mqtt协议连接阿里云

使用RDP协议连接windows服务器

基于ESP32搭建物联网服务器十二(使用MQTT协议与ESP32互动)