Hello everyone.

The Mixed Reality Forums here are no longer being used or maintained.

There are a few other places we would like to direct you to for support, both from Microsoft and from the community.

The first way we want to connect with you is our mixed reality developer program, which you can sign up for at https://aka.ms/IWantMR.

For technical questions, please use Stack Overflow, and tag your questions using either hololens or windows-mixed-reality.

If you want to join in discussions, please do so in the HoloDevelopers Slack, which you can join by going to https://aka.ms/holodevelopers, or in our Microsoft Tech Communities forums at https://techcommunity.microsoft.com/t5/mixed-reality/ct-p/MicrosoftMixedReality.

And always feel free to hit us up on Twitter @MxdRealityDev.
Options

iBeacon, Beacons, Hololens

Ok so here is the breakdown.

1) Find and download the .NET 4 Windows.Devices.Bluetooth DLL
2) In Unity, create the Assets > Plugins > WSA folder and place that DLL in it. When you check the import settings of this DLL, it can be set to 'Any Platform' and it will say 'Native' as the Type, which is fine.
3) Next, add the DLL I attached to this comment to the Assets > Plugins folder. When you check the import settings of this DLL, you can check it just for WSAPlayer, SDK = UWP, Scripting = Dot Net, and you will see it Managed as a 4.x assembly.
4) So lets look at some code on the Unity side now. Everything you do to "reference" the DLL, you are going to need to wrap in #if !UNITY_EDITOR because you dont want it to compile.

#if !UNITY_EDITOR
using HoloBeaconScanner;
#endif

Next under Start() on your script we can place:

#if !UNITY_EDITOR
        Scanner beaconScanner = new Scanner();
        Scanner.ScannedBeaconEventHandler += BeaconFound;
        beaconScanner.StartScanning();
#endif

There is also a .StopScanning() function if you make your var global.

And once you are scanning you can just set the even handler to catch that Beacon info:

 public void BeaconFound(string str)
    {
        try
        {
            char[] delimiterChars = { '*' };
            string[] components = str.Split(delimiterChars, StringSplitOptions.RemoveEmptyEntries);
            if (components[1] != "0")
            {
                Debug.Log("[BEACON DETECTOR] : FOUND : " + str.ToString());
            }
        }
        catch(Exception ex)
        {
            //Log error or something else.
        }
    }

So the beacon data comes back as a delimited string. I will update it with a JSON package, but right now it is delimited by a *.

Components are as follows:
0 = UUID
1 = Major
2 = Minor
3 = TxPower
4 = Raw Signal Strength in DBm

If the Holo does not find a beacon or encounters an error, it will return:

0000000-0000-0000-0000-0000000000000000

So keep that in mind, and hence why I check for Component 1 to be 0 and ignore it.

I hope this helps someone out there and hope it keeps advancing the Hololens Experience! I will try to keep the DLL up to date! Thanks!

Comments

  • Options

    Hi @MattFedoCSG
    Thank you for the documentation.
    I'm trying to get GPS information from android in my unity application on the Hololens.
    Can your plugins help me?
    And do you have some sample of the entirely bluetooth connection?

    Thank you!

  • Options
    DaZa, this was merely implementing Bluetooth for low power devices. If you need to send your Hololens GPS info, I would consider creating a socket connection over a network and try that first. Then work on integrating dedicated Bluetooth data passing.
  • Options

    @MattFedoCSG thanks for sharing this! Can you point me in the right direction to put your scanner into a continuous scanning mode? I'm probably doing something wrong, but I can only get exactly 1 successful 'read', then it seems to just stop working.

  • Options

    @MattFedoCSG nevermind =) I managed to handroll some native WSA bits that are working for me.

    • HoloLens has native access to BLE broadcasting via Windows.Devices.Bluetooth.Advertisement
    • Leverage UnityEngine.WSA.Application.InvokeOnAppThread to handle the received data and pass to Unity to handle the data, otherwise you'll crash

    Here is some code I hope may help others. It's very imperfect and incomplete for fully handling the beacon data, but I'll tackle that next and update this post if I remember!:

    Usings:

    #if !UNITY_EDITOR
    using Windows.Devices.Bluetooth.Advertisement;
    using Windows.Storage.Streams;
    #endif
    

    Global scanner:

    #if !UNITY_EDITOR    
        BluetoothLEAdvertisementWatcher scanner;
    #endif
    

    Setup:

    #if !UNITY_EDITOR
    
            scanner = new BluetoothLEAdvertisementWatcher
                {
                    ScanningMode = BluetoothLEScanningMode.Passive
                };
    
            ////setup filter to only catch ibeacon for now
            var manufacturerData = new BluetoothLEManufacturerData()
            {
                CompanyId =  0x004C //Hexidecimal for 76 which is Apple, use Use 0x015D for 349 for the stickers
            };
    
            //boilerplate code to write the filter data
            var writer = new DataWriter();
            writer.WriteUInt16(0x0215);
            writer.WriteUInt64(0xB9407F30F5F8466E); //First half of your beacons' UUID, this is the Estimote out of the box UUID
            writer.WriteUInt64(0xAFF925556B57FE6D); //Second half of your beacons' UUID, this is the Estimote out of the box UUID
            manufacturerData.Data = writer.DetachBuffer();
            scanner.AdvertisementFilter.Advertisement.ManufacturerData.Clear();
            scanner.AdvertisementFilter.Advertisement.ManufacturerData.Add(manufacturerData);
    
            ////set some thresholds
            //scanner.SignalStrengthFilter.InRangeThresholdInDBm = -50;
            //scanner.SignalStrengthFilter.OutOfRangeThresholdInDBm = -100;
            scanner.SignalStrengthFilter.OutOfRangeTimeout = TimeSpan.FromMilliseconds(2000);
    
            //setup callbacks
                scanner.Received += OnBeaconFound;
           // scanner.Stopped += OnScannerStopped;
    
            scanner.Start();
    
    #endif
    

    Receiving broadcasts:

        #if !UNITY_EDITOR
    
            private void OnBeaconFound(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
            {
    
                try
                {
                    UnityEngine.WSA.Application.InvokeOnAppThread (() =>
                    {
                        hitCount++;
                        InstructionText.text = "OnBeaconFound " + hitCount.ToString();
    
                        var foundBeacon = new FoundBeacon()
                        {
                            RSSI = args.RawSignalStrengthInDBm.ToString()
                        };
    
                        UUIDText.text = foundBeacon.RSSI;
    
                        foundBeacon.Major = args.AdvertisementType.ToString();
    
                        //check for manufacturer data section
                        var beaconDataString = string.Empty;
    
                        var beaconDataSections = args.Advertisement.ManufacturerData;
                        if (beaconDataSections.Count > 0)
                        {
                            //print first data section for now
                            var beaconData = beaconDataSections[0];
                            var beaconDataBytes = new byte[beaconData.Data.Length];
                            using (var reader = DataReader.FromBuffer(beaconData.Data))
                            {
                                reader.ReadBytes(beaconDataBytes);
                            }
    
                            beaconDataString = BitConverter.ToString(beaconDataBytes);
    
                            foundBeacon.TxPower = beaconDataString;
                        }
    
                   }, true );
                }
                catch (Exception ex)
                {
                    UUIDText.text = ex.Message;
                }
            }    
        #endif
    
  • Options

    Could I ask, what BLE device you are connecting too?

  • Options

    @MattFedoCSG can you please share the project as it is not working for me on hololens 1

Sign In or Register to comment.