Search Unity

Clicker Battery By BlueTooth

Discussion in 'VR' started by rpas, Feb 14, 2017.

  1. rpas

    rpas

    Joined:
    Feb 11, 2016
    Posts:
    2
    Hi,
    I'm trying to read battery level from the clicker, but it seems, unsuccessfully...

    I'm using the microsoft example from here:
    https://docs.microsoft.com/pt-pt/windows/uwp/devices-sensors/gatt-scenarios

    and because I can run UWP async methods on Unity, I created a Task running on the background, reading the battery level every xxx minutes...

    var devices = await DeviceInformation.FindAllAsync(GattDeviceService.GetDeviceSelectorFromUuid(GattServiceUuids.Battery));

    var service = await GattDeviceService.FromIdAsync(devices[0].Id);

    var clickerCharacteristic = service.GetCharacteristics(GattCharacteristicUuids.BatteryLevel)[0];

    var BatteryLevel = await clickerCharacteristic.ReadValueAsync();

    byte levelData = Windows.Storage.Streams.DataReader.FromBuffer(BatteryLevel.Value).ReadByte();

    UpdateClickerBattery((double)levelData);

    I also enabled the Capability on the Manifest:

    <DeviceCapability Name="bluetooth.genericAttributeProfile">
    <Device Id="any">
    <Function Type="name:genericAccess" />
    </Device>
    </DeviceCapability>

    And always get the same value [ 71 ] .
    I tryed to charge the clicker, a still give 71 % of battery...

    I also already checked that the service is the "Clicker" service, because if I print the devices[0].Name it will return "Clicker"....

    Any help would be very appreciated...

    Cheers.


     
  2. Unity_Wesley

    Unity_Wesley

    Unity Technologies

    Joined:
    Sep 17, 2015
    Posts:
    558
    According to the doc's you need to get the updates from the bluetooth device.

    You might want to try this example:
    C#
    async void Initialize()
    {
    var batteryServices = await Windows.Devices.Enumeration
    .DeviceInformation.FindAllAsync(GattDeviceService
    .GetDeviceSelectorFromUuid(GattServiceUuids.Battery),
    null);

    if (batteryServices.Count > 0)
    {
    // Use the first Battery service on the system
    GattDeviceService batteryService = await GattDeviceService
    .FromIdAsync(batteryServices[0].Id);

    // Use the first Characteristic of that Service
    GattCharacteristic batteryLevelCharacteristic =
    batteryService.GetCharacteristics(
    GattCharacteristicUuids.BatteryLevel)[0];

    batteryLevelCharacteristic.ValueChanged += batteryLevelChanged;
    }
    else
    {
    statusTextBlock.Text = "No Battery services found !";
    }
    }

    void batteryLevelChanged(
    GattCharacteristic sender,
    GattValueChangedEventArgs eventArgs)
    {
    byte levelData = Windows.Storage.Streams.DataReader
    .FromBuffer(eventArgs.CharacteristicValue).ReadByte();

    double levelValue;

    if (sender.PresentationFormats.Count > 0)
    {
    levelValue = levelData *
    Math.Pow(10.0, sender.PresentationFormats[0].Exponent);
    }
    else
    {
    levelValue = (double)levelData;
    }

    batteryLevelTextBlock.Text = levelValue.ToString();
    }
     
  3. rpas

    rpas

    Joined:
    Feb 11, 2016
    Posts:
    2
    Thanks for your help,

    but I already try that....

    My callback " batteryLevelChanged" is never called...

    But I was guessing that the callback is not being called because I'm running in a thread , not in the Unity main thread...

    Because I can't ( don't now how to ) run async methods from the main thread, I'm lauching it in a separate thread...

    ClickerBatteryTask = Task.Factory.StartNew( () => GetClickerBatteryLevelForEver() );

    In this case my method " GetClickerBatteryLevelForEver " is the "Initialize" from the example.

    And the callback is never called....
    But maybe because the callback is defined on the main thread...

    I will try passing the object as argument of the thread, so see if the callback is called...

    Like This:

    ClickerBatteryTask= Task.Factory.StartNew( () => GetClickerBatteryLevelForEver(this) );

    And then :

    private async void GetClickerBatteryLevelForEver( PowerManager pm )
    {
    {.......}

    batteryLevelCharacteristic.ValueChanged += pm.batteryLevelChanged;

    {.......}
    }