I have a bluetooth low energy (BTLE) device, which I need to connect to my PC. To do so, I use the windows API reference in a desktop WPF app.
The bluetooth device is rather simple: 1 service, 2 characteristics (one read/notify, one to write to).
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 code for 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
Well, it works, kinda... It is unstable as hell, most of the time it generates errors that can't be solved:
Line: BLEData_ReadNotify.WriteClientCharacteri... produces There is no user session key for the specified logon session. (Exception from HRESULT: 0x80070572)
and The semaphore timeout period has expired. (Exception from HRESULT: 0x80070079). This second error is less common and appears when the script first does not receive anything, then via a timer it tries to send the RUN command again, then all crashed and the error apears.
Searching on stackoverflow and many sites, I found that both above errors are impossible to solve. Hence my question:
Can the above code be rewritten using 32Feet.net?
In 2012 it was not possible link to use ble at all, but perhaps now it is? Using the scanning method in this answer link, I CAN find my BLE device when it it NOT paired.
so, I tried some code
// 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();
but I am stranded at the line localClient.Connect with the error: An exception of type 'System.Net.Sockets.SocketException' occurred. Additional information: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond
Can the windows API code be rewritten in 32feet.net, ifso, how to proceed?
Note: I tried to connect to a BT2.1 device using windows native .net code, but the serial port is unstable and a pain in the head. With 32feet.net it now works splendidly over SerialPort, very stable and it connect each time!
I had simular issue with this relating to
the semaphore timeout period has expired. (Exception from HRESULT: 0x80070079).
My issue was resolved with .net 4.7.1. Also I needed to make sure I had the latest microsoft bluetooth driver for the bluetooth device i was using
SerialPort streams no longer terminate the process when exceptions occur on the background thread. This can happen when removing a USB serial port while in use. This new behavior is controlled by the Switch.System.IO.Ports.DoNotCatchSerialStreamThreadExceptions AppContext switch. This switch is set to truetf get by default when targeting .NET 4.7 or below. [428461, System.dll, Bug]
Update: Actually it appears to be 2 issues in one. .net bug and a firmware issue where the device was never turning back on the bluetooth module.
User contributions licensed under CC BY-SA 3.0