inthehand / 32feet

Personal Area Networking for .NET. Open source and professionally supported
https://inthehand.com/components/32feet/
MIT License
814 stars 205 forks source link

BluetoothLE - Need some Help #290

Open wagenheimer opened 1 year ago

wagenheimer commented 1 year ago

Hi I'm developing a WPF application that accesses some BluetoothLE scales, but I'm having some difficulties making it work.

await gatt.ConnectAsync();
var gattServices = await Device.Gatt.GetPrimaryServicesAsync();
var service = gattServices.Where(s => s.Uuid.ToString() == CelmiUUID.Service.SERVICO_INFORMACOES).FirstOrDefault();
var characteristic = await service.GetCharacteristicAsync(BluetoothUuid.GetCharacteristic(CelmiUUID.Characteristic.PESO));
var value = await characteristic.ReadValueAsync();

Now if I check.... "value" is null, but characteristic.Value has some value on it. How this is possible?

The device returns a byte[4] image

BitConverter.ToSingle(value) gives me 474.699982 that is wrong.

Even if I change the weight, it always seems to return the same value, even if I disconnect and reconnect again.

Is there any advice of what can be wrong?

wagenheimer commented 1 year ago

It seems something related to Thread. It worked now for some time, but after testing more now I can't make it work anymore. The most strange is that when not working after calling value = await characteristic.ReadValueAsync(); value is always null and characteristic.Value always returns the same "random" value.... each device (I have 4) there is a different but constant random value.

wagenheimer commented 1 year ago

Some more info:

291 seems to be related.

When the device name are appearing as "Plat. Celmi" on the Advertisements everything works as expected here!

When the devices are showing the correct names, then it will not work anymore here.

Do you have any idea what might be going on?

BleScanner on Android and my Xamarin Android App (Using Shiny) always show the correct device names and always connect and read values normally.

wagenheimer commented 1 year ago

"Plat. Celmi" text is located on : "Device Name" - Characteristic = 00002a18-0000-1000-8000-00805f9b34fb

peterfoot commented 1 year ago

Characteristic 2a18 is Glucose measurement. What Service uuid are you connecting to?

What version of Windows are you running on? did the services changed event fire - I've seen some cases where the device changes the services so the characteristics have underlying handles which point to completely different characteristics. It happens a lot with devices which change which services they make public (iPhone is a particular pain in this regard).

wagenheimer commented 1 year ago

I'm using Windows 11.

image

The weighting info I got from a custom service/characteristic. Service - 97d8ccb6-b6b6-4bc8-a7ba-5b4ecb9e4f62 Characteristic - 875607c1-1f96-449c-b4d5-14dab172d5e6

peterfoot commented 1 year ago

Are you performing the ReadValueAsync on the UI thread?

wagenheimer commented 1 year ago

I'm calling it inside a Task. But adding a Breakpoint on

var value = await characteristic.ReadValueAsync();

image

peterfoot commented 1 year ago

does the characteristic not support notification? Calling in a tight loop like this is going to be problematic and also not power friendly.

wagenheimer commented 1 year ago

Yes, it supports notifications... but I end up running into the same problem, the notification only works when I connect to it when the name appears as "Plat. Celmi", when I connect when it is showing the correct name "BLE TX R2 P1...", the notification also doesn't work.

wagenheimer commented 1 year ago

@peterfoot Any idea of what else I can try?

I'm thinking that it really could be a problem with threads.

When connecting for the first time, on the device with the correct full name, this happens when I breakpoint this code on the ProcessaValor line:

var value = await characteristic.ReadValueAsync();
ProcessaValor("PESO", characteristic.Value);

value is null characteristic.Value has some value, but a wrong value.

wagenheimer commented 1 year ago

I upgraded it from dotNet6 to dotNet 7 and I was able to get some more info:

 async Task<byte[]> PlatformReadValue()
        {
            var result = await _characteristic.ReadValueAsync(Windows.Devices.Bluetooth.BluetoothCacheMode.Uncached).AsTask().ConfigureAwait(false);

            if(result.Status == Uap.GattCommunicationStatus.Success)

result.Status == Unreachable

wagenheimer commented 1 year ago

I tested it on another computer (a notebook) and I was able to connect to all my devices successfully.

My main PC has an MSI PRO-Z690-A-WIFI Motherboard, with the latest Updated Bluetooth drivers from Intel 02/08/2023

image

It's a Bluetooth 5.2 adapter. It may be some Bluetooth 5.2 incompatibility with my devices. It is very strange and doesn't make any sense, but it doesn't seem to be a software issue.

I disabled the Intel Bluetooth Adapter and installed a Realtek Bluetooth 5.0 dongle and I could also connect and read values from all my devices successfully.