velorexe / unity-android-bluetooth-low-energy Goto Github PK
View Code? Open in Web Editor NEWA Unity Android plugin to support basic Bluetooth Low Energy interactions.
License: The Unlicense
A Unity Android plugin to support basic Bluetooth Low Energy interactions.
License: The Unlicense
Hi there,
Nice stuff and the educational material helps understand what's going on. I first tried the Unity classes and Java plugin (as-is) with a simple test app running on my phone (Pixel 7/Android 13) - that worked great to scan, connect and subscribe to a ESP32 device that sends back bike wheel rotation data (Cycling Speed and Cadence characteristic profile). However, using the same test app code to run in VR on a Quest 2 (Android 12) gets errors trying to connect, as shown in the following logcat:
Digging around Google for the meaning of an "unsupported transport for background connection" turned up only one conversation that suggested the Java call to connectGatt might need a fourth parameter to specifically set the transport type as BLUETOOTH_LE rather than a default on some Android 12 devices:
Original:
device.connectGatt(UnityPlayer.currentActivity.getApplicationContext(), true, service.gattCallback);
Suggestion:
device.connectGatt(UnityPlayer.currentActivity.getApplicationContext(), true, service.gattCallback, BluetoothDevice.TRANSPORT_LE);
(also, Android 12 on Quest 2 no longer requires the LOCATION permissions on the manifest which are prohibited by Meta.)
Recompiling the Java plugin with this change does allow connections on the Quest 2, which seems good for this particular case. But I don't have experience with the Bluetooth API to be sure this is definitively the right way to fix this.
Hello @Velorexe,
I am trying to use your library on the quest (android 10). so far I have some progress with:
-scanning for devices (success)
-connecting to a device (and its services and characteristics) (success)
but during the subscribe to a characteristic I am now running into the issue that the service UUID and characteristic UUID is now accepted, but on line 384 in UnityAndroidBLE.java it crashes with a null pointer exception.
apparently the gattDescriptor is most likely not existent.
Checking all the values of the services and characteristics i get seem to be valid, though i do seem to get some empty services (which i skip) when connecting.
As far as I can see in the code, everything should be nicely setup in the library.
Forgive the ugly code as I am first exploring the use of the library, but its not to dissimilar to the original example it is based on. (it is hardwired to find a BLE device called martijn)
Any help would be appreciated as I get the feeling I need to setup something more?
`
using UnityEngine;
using Android.BLE;
using Android.BLE.Commands;
using UnityEngine.Android;
using System.Collections.Generic;
using System.Linq;
using System;
public class CharacteristicInfo
{
public bool IsSubscribed;
public string Characteristic;
public string Service;
}
public class ExampleBleInteractor : MonoBehaviour
{
[SerializeField]
private GameObject _deviceButton;
[SerializeField]
private Transform _deviceList;
[SerializeField]
private int _scanTime = 3;
private float _scanTimer = 0f;
private bool _isScanning = false;
private string m_Martijn = "Martijn";
private string m_Device = "";
private bool m_MartijnFound = false;
private bool m_ConnectCommandSent = false;
List<CharacteristicInfo> m_Chars= new List<CharacteristicInfo>();
public void ScanForDevices()
{
if (!_isScanning)
{
_isScanning = true;
BleManager.Instance.QueueCommand(new DiscoverDevices(OnDeviceFound, _scanTime * 1000));
}
}
private void Update()
{
if(_isScanning)
{
Debug.LogWarning("scanning");
_scanTimer += Time.deltaTime;
if(_scanTimer > _scanTime)
{
_scanTimer = 0f;
_isScanning = false;
}
}
else
{
if (m_MartijnFound == false)
{
Debug.LogWarning("starting scanning for devices");
ScanForDevices();
}
else if (m_ConnectCommandSent == false)
{
Debug.LogWarning("starting to connect to device");
BleManager.Instance.QueueCommand(new ConnectToDevice(m_Device, OnDeviceConnected, OnDisconnected, OnServiceDiscovered, OnCharacteristicDiscovered));
m_ConnectCommandSent = true;
}
else if (m_Chars.Count > 0)
{
for (int i = 0; i < m_Chars.Count; i++)
{
if (m_Chars[i].IsSubscribed == false)
{
m_Chars[i].IsSubscribed = true;
Debug.LogWarning($"we try to register for data! address {m_Chars[i].Service} char {m_Chars[i].Characteristic}");
BleManager.Instance.QueueCommand(new SubscribeToCharacteristic(m_Device,
m_Chars[i].Service,
m_Chars[i].Characteristic,
OnDataFound,
true));
}
}
}
}
}
private void OnDataFound(byte[] value)
{
Debug.LogWarning($"we got data!");
}
private void OnDeviceFound(string device, string name)
{
if (m_MartijnFound == false)
{
Debug.LogWarning($"we found {name} and {device}");
if ((name == null) || (name.Length == 0) )
{
Debug.LogWarning("name is null");
return;
}
if ((m_MartijnFound == false) &&
(m_Martijn.CompareTo(name) == 0))
{
DeviceButton button = Instantiate(_deviceButton, _deviceList).GetComponent<DeviceButton>();
button.Show(name, device);
m_Device = device;
m_MartijnFound = true;
}
}
}
private void OnDeviceConnected(string device)
{
DeviceButton button = Instantiate(_deviceButton, _deviceList).GetComponent<DeviceButton>();
button.Show("we got device connected", device);
Debug.LogWarning($"we got device connected");
}
private void OnDisconnected(string device)
{
Debug.LogWarning($"we got device disconnected");
}
private void OnServiceDiscovered(string deviceAddress, string serviceAddress)
{
Debug.LogWarning($"we got service {serviceAddress}!");
if (serviceAddress.Length != 0)
{
Debug.LogWarning($"we got service {serviceAddress}!");
}
}
private void OnCharacteristicDiscovered(string deviceAddress, string serviceAddress, string characteristicAddress)
{
Debug.LogWarning($"we got charasteristic {characteristicAddress} for service {serviceAddress}!");
if (characteristicAddress.Length != 0)
{
DeviceButton button = Instantiate(_deviceButton, _deviceList).GetComponent<DeviceButton>();
button.Show($"we got charasteristic {characteristicAddress} for service {serviceAddress}!", deviceAddress);
m_Chars.Add(new CharacteristicInfo() { Characteristic= characteristicAddress, IsSubscribed = false , Service = serviceAddress});
}
}
}
`
The error is as follows :
`
2022/12/06 11:02:31.268 8621 8643 Warn Unity we got charasteristic 00002a19-0000-1000-8000-00805f9b34fb for service 0000180f-0000-1000-8000-00805f9b34fb!
2022/12/06 11:02:31.270 8621 8643 Warn Unity {
2022/12/06 11:02:31.270 8621 8643 Warn Unity "device": "F0:6A:69:EA:13:1C",
2022/12/06 11:02:31.270 8621 8643 Warn Unity "name": "",
2022/12/06 11:02:31.270 8621 8643 Warn Unity "service": "",
2022/12/06 11:02:31.270 8621 8643 Warn Unity "characteristic": "",
2022/12/06 11:02:31.270 8621 8643 Warn Unity "command": "DeviceConnected",
2022/12/06 11:02:31.270 8621 8643 Warn Unity "hasError": false,
2022/12/06 11:02:31.270 8621 8643 Warn Unity "errorMessage": ""
2022/12/06 11:02:31.270 8621 8643 Warn Unity }
2022/12/06 11:02:31.270 8621 8643 Warn Unity command received for F0:6A:69:EA:13:1C : DeviceConnected
2022/12/06 11:02:31.271 8621 8643 Warn Unity we got device connected
2022/12/06 11:02:31.288 8621 8643 Warn Unity we try to register for data! address 00001800-0000-1000-8000-00805f9b34fb char 00002a00-0000-1000-8000-00805f9b34fb
2022/12/06 11:02:31.288 8621 8643 Warn Unity Queueing Command: SubscribeToCharacteristic
2022/12/06 11:02:31.289 8621 8643 Warn Unity sending command subscribeToCustomGattCharacteristic
2022/12/06 11:02:31.289 8621 8643 Warn Unity Calling Command: subscribeToCustomGattCharacteristic
2022/12/06 11:02:31.306 8621 8639 Debug BluetoothGatt onConnectionUpdated() - Device=F0:6A:69:EA:13:1C interval=36 latency=0 timeout=500 status=0
2022/12/06 11:02:31.363 8621 8643 Error Unity AndroidJavaException: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothGattDescriptor.setValue(byte[])' on a null object reference
2022/12/06 11:02:31.363 8621 8643 Error Unity java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.bluetooth.BluetoothGattDescriptor.setValue(byte[])' on a null object reference
2022/12/06 11:02:31.363 8621 8643 Error Unity at com.velorexe.unityandroidble.UnityAndroidBLE.subscribeToCustomGattCharacteristic(UnityAndroidBLE.java:384)
2022/12/06 11:02:31.363 8621 8643 Error Unity at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
2022/12/06 11:02:31.363 8621 8643 Error Unity at com.unity3d.player.UnityPlayer.access$300(Unknown Source:0)
2022/12/06 11:02:31.363 8621 8643 Error Unity at com.unity3d.player.UnityPlayer$e$1.handleMessage(Unknown Source:95)
2022/12/06 11:02:31.363 8621 8643 Error Unity at android.os.Handler.dispatchMessage(Handler.java:105)
2022/12/06 11:02:31.363 8621 8643 Error Unity at android.os.Looper.loop(Looper.java:227)
2022/12/06 11:02:31.363 8621 8643 Error Unity at com.unity3d.player.UnityPlayer$e.run(Unknown Source:20)
2022/12/06 11:02:31.363 8621 8643 Error Unity at UnityEngine.AndroidJNISafe.CheckException () [0x00096] in <2929d00977a149fa8e08bd559a24d9de>:0
2022/12/06 11:02:31.363 8621 8643 Error Unity at UnityEngine.AndroidJNISafe.CallVoidMethod (System.IntPtr obj, System.IntPtr methodID, UnityEngine.jval
2022/12/06 11:02:31.399 8621 8643 Warn Unity we try to register for data! address 00001800-0000-1000-8000-00805f9b34fb char 00002a01-0000-1000-8000-00805f9b34fb
`
I'm not sure if this is related to issue #38 because I don't have a Java error. However it seams that the write to characteristic command is not working.
I can connect to the device (an echelon bike) and receive notification but when sending the initialization sequence, the bike does not react. (The same initialization sequence is working fine with a Nodejs setup)
I tried byte array
byte[] init3 = { 0xF0, 0xB0, 0x01, 0x01, 0xA2 };
I tried encoding a String
string init3 = "\xF0\xB0\x01\x01\xA2";
or even like this
string init3 = "\u00F0\u00B0\u0001\u0001\u00A2";
I understand that passing byte arrays to Android JNI is not simple, and utf8 encoding is being used instead.
But has anyone succeeded in sending commands that contain control characters and NULLs ?
const string SERVICE_UUID = "0bf669f1-45f2-11e7-9598-0800200c9a66";
const string COMMAND_UUID = "0bf669f2-45f2-11e7-9598-0800200c9a66";
_writeToCharacteristic = new WriteToCharacteristic(_deviceUuid, SERVICE_UUID, COMMAND_UUID, init3 , true);
BleManager.Instance.QueueCommand(_writeToCharacteristic);
Im getting this error trying to write a characteristic:
2024/02/25 20:57:35.323 12452 12474 Error Unity AndroidJavaException: java.lang.IllegalArgumentException: Invalid UUID string: 000025e1362d-af97-42c1-92e1-41739cc194e6-0000-1000-8000-00805f9b34fb
2024/02/25 20:57:35.323 12452 12474 Error Unity java.lang.IllegalArgumentException: Invalid UUID string: 000025e1362d-af97-42c1-92e1-41739cc194e6-0000-1000-8000-00805f9b34fb
2024/02/25 20:57:35.323 12452 12474 Error Unity at java.util.UUID.fromStringJava8(UUID.java:276)
2024/02/25 20:57:35.323 12452 12474 Error Unity at java.util.UUID.fromString(UUID.java:223)
2024/02/25 20:57:35.323 12452 12474 Error Unity at com.velorexe.unityandroidble.UnityAndroidBLE.writeToGattCharacteristic(UnityAndroidBLE.java:511)
2024/02/25 20:57:35.323 12452 12474 Error Unity at com.unity3d.player.UnityPlayer.nativeRender(Native Method)
2024/02/25 20:57:35.323 12452 12474 Error Unity at com.unity3d.player.UnityPlayer.-$$Nest$mnativeRender(Unknown Source:0)
2024/02/25 20:57:35.323 12452 12474 Error Unity at com.unity3d.player.UnityPlayer$F$a.handleMessage(Unknown Source:122)
2024/02/25 20:57:35.323 12452 12474 Error Unity at android.os.Handler.dispatchMessage(Handler.java:102)
2024/02/25 20:57:35.323 12452 12474 Error Unity at android.os.Looper.loopOnce(Looper.java:230)
2024/02/25 20:57:35.323 12452 12474 Error Unity at android.os.Looper.loop(Looper.java:319)
2024/02/25 20:57:35.323 12452 12474 Error Unity at com.unity3d.player.UnityPlayer$F.run(Unknown Source:24)
2024/02/25 20:57:35.323 12452 12474 Error Unity at UnityEngine.AndroidJNISafe.CheckException () [0x00096] in <c5ca39a6c98646d4a8b61716838ca615>:0
2024/02/25 20:57:35.323 12452 12474 Error Unity at UnityEngine.AndroidJNISafe.
My class:
public class BLEDeviceController : MonoBehaviour
{
private const string ServiceUuid = "25e1362d-af97-42c1-92e1-41739cc194e6";
private const string CharacteristicUuid = "2a7b25d1-cf73-4b3d-bd95-3a44c1646d1c";
//...
private void SendMovementCommand(string command)
{
if (command == _lastCommand &&
Time.time < _nextRepeatedCommandSend)
{
return;
}
_lastCommand = command;
_nextRepeatedCommandSend = Time.time + repeatedCommandThrottling;
var bleCommand = new WriteToCharacteristic(_deviceUuid, ServiceUuid, CharacteristicUuid, command);
BleManager.Instance.QueueCommand(bleCommand);
}
}
What is that base64 data encoding? Why is that being used?
I' m click scan button but nothing became
The software lists all Bluetooth devices.
Is there a way to have it only list devices that support a specific Gatt Service and/or Characteristic?
One of my concerns has been that the Android Library exists as a separate repository for this project, yet they are tightly coupled with explicit API calls and no version checks for this dependency. with no submodule, it's hard to tell which version of the java Library source code goes with which version of the Unity project source code.
As of Unity 2022.2 You can now optionally include Android Libraries directly into a Project, and Unity will add it to the Gradle file.
https://docs.unity3d.com/2022.2/Documentation/Manual/android-library-project-and-aar-plugins-introducing.html
https://docs.unity3d.com/2022.2/Documentation/Manual/AndroidAARPlugins.html
We could add the Library as a submodule, which then pairs specific versions of the android library with it's corresponding Unity Package ( if the move to Packages goes ahead as I hope ).
For releases we can switch to android archive or jar file. But this new Unity feature allows us to switch between the two easily.
How do you access the data from the subscribed characteristic? I can see the data in Logcat but I haven't figured out how to access it within the program. I've tried overriding Command Received in the ReadFromCharacteristic class but that method was never called.
Hi, I am was testing this plugin and tried to connect with a BLE sensor. But it's not properly connecting and not reading the characteristic values. I have tested with your temperature characteristic and then tested with Heart rate service UUID and characteristic code, but same result. I have attached the screenshot from device.
Screen shot 1
Screen shot 2
Here is the console log
Warning log
Error log
Hello. I would like to use this to create an app to send and recive data to an arduino with a bluetooth module. the example is able to pair, but how to send and recive data?
Hi, trying to use your library.
But can't get the subscribed data.
Here is the sample code:
public void SubscribeService()
{
if(!_isSubscribed)
{
_subscribeToCharacteristic = new SubscribeToCharacteristic(_deviceUuid, serviceId, readCharacteristicId, OnDataReceive, true);
BleManager.Instance.QueueCommand(_subscribeToCharacteristic);
_isSubscribed = true;
}
}
Before that, I scan the devices, connect to the one I need. After that, I sign up for a characteristic.
At the same time, in Android Logcat I can see that data is coming in, but the callback function is never called (OnDataReceive)
Quick description: providing Service or Characteristic UUIDs containing capital letters for Commands such as ReadFromCharacteristic, will result in call backs not firing.
I appreciate that there's several easy solutions to this. In fact I'm more than happy to do this fix. However as I've still got forked pull requests waiting, I don't want to start piling up pull requests that won't see the light of day.
@Velorexe, this is an awesome project, don't let it die because you don't have the time to maintain it. I'd really love to help take on some of the load maintaining this project. You would still have final say about fixes, and future features. But at least this way we don't get stuck.
Happy to talk more about it
Hi, I hope that you are doing well.
I am fairly new to unity and I am working on a project which establishes a BLE connection between a device and an android based application and I am using this repo to achieve this goal. So far, it was very helpful.
I am just having a hard time to catch errors in case of connection failure between a device and an android based application and I have noticed that with this library, I am not able to catch any errors related to connection to a device. In fact , if I try to connect to a device and turn off the device during the connection phase, the lib is unable to catch it. Therefore, it is very difficult to treat cases of error connections.
Unless I missed something , is there a way to treat the previously explained cases with your code ?
Sorry if the question is not clear enough !
Hello @Velorexe,
First of all, thank you for this repo, I'm new to both Unity and BLE and since I'm working on a project where I need to establish a BLE communication between a device and an android based application, it is really helpful.
I'm having some hard time trying to subscribe to my device characteristic using your example. The services and characteristics related to my issue are defined as follow :
private string UUID_PROCESSING_SERVICE = "c2890001-ca9a-11eb-b8bc-0242ac130003";
private string UUID_CHARACTERISTIC_PROCESSING = "c2890002-ca9a-11eb-b8bc-0242ac130003";
private string UUID_BATTERY_SERVICE = "0000180f-0000-1000-8000-00805f9b34fb";
private string UUID_CHARACTERISTIC_BATTERY_LEVEL = "00002a19-0000-1000-8000-00805f9b34fb";
I don't have any issue subscribing to the battery characteristic using:
BleManager.Instance.QueueCommand(new SubscribeToCharacteristic(_deviceUuid, UUID_BATTERY_SERVICE.Get16BitUuid(), UUID_CHARACTERISTIC_BATTERY_LEVEL.Get16BitUuid());
However, when I try to subscribe to the processing characteristic using the following code :
BleManager.Instance.QueueCommand(new SubscribeToCharacteristic(_deviceUuid, UUID_PROCESSING_SERVICE, UUID_CHARACTERISTIC_PROCESSING);
I have the following error :
AndroidJavaException: java.lang.IllegalArgumentException: Invalid UUID string: 0000c2890001-ca9a-11eb-b8bc-0242ac130003-0000-1000-8000-00805f9b34fb
Is there a way to use 128 bits UUID within your code (it doesn't work either using Get16BitUuid()) ? Am I missing something ?
Sorry for the inconvenience and if the question isn't clear !
I think in the BleManager's OnBleMessageReceived when the parallel Stack is cleared of consumed items the list should either be iterated over in reverse, or i decremented whenever an item is removed:
// Run through the parallel stack, remove the commands that have consumed the BleObject
for (int i = _parallelStack.Count - 1; i >= 0; i--)
{
if (_parrallelStack[i].CommandReceived(obj))
{
_parrallelStack[i].End();
_parrallelStack.RemoveAt(i);
}
}
or
// Run through the parallel stack, remove the commands that have consumed the BleObject
for (int i = 0; i < _parrallelStack.Count; i++)
{
if (_parrallelStack[i].CommandReceived(obj))
{
_parrallelStack[i].End();
_parrallelStack.RemoveAt(i);
i--;
}
}
I spent an hour debugging before noticing the latest commit
I think this might help future users🙏
Branch refactor/project-overhaul
Commit 811b3250
In BleDevice.cs, RequestMtuSize() sends the wrong task:
/// <summary>
/// Request the <see cref="BleDevice"/>'s MTU Size to be bigger or smaller.
/// <para>[Calls: <see href="https://developer.android.com/reference/android/bluetooth/BluetoothGatt#requestMtu(int)"/>]</para>
/// </summary>
/// <param name="mtuSize">The requested size that the MTU buffer should be.</param>
/// <param name="onMtuSizeChanged">A callback that returns the MTU size that the <see cref="BleDevice"/> has after your request.</param>
public void RequestMtuSize(int mtuSize, OnMtuSizeChanged onMtuSizeChanged = null)
{
_onMtuSizeChanged = onMtuSizeChanged;
BleTask task = new BleTask("changeMtuSize", MacAddress, mtuSize); /// NEW
/// OLD BleTask task = new BleTask("requestMtuSize", MacAddress, mtuSize);
BleManager.Instance.SendTask(task, this);
}
The path for unity.jar in build.grade:
implementation files('F:\\Projects\\UnityAndroidBLE\\app\\libs\\unity.jar')
is not universal. it should be
implementation files('libs/unity.jar)'
Hello @Velorexe
I used an Android device to connect to the ble Bluetooth module. Once the module is connected, I subscribe to the module's UUID for sending and receiving data. Then disconnect the module and connect the module to subscribe to the module's UUID. The next problem is that the UUID that receives the data is subscribed, but cannot receive the data sent by the module, and the same is true for the send
Hi, I'm getting this warning in the android log when I attempt to connect to a device listed after scanning for devices. Why might this be - the scan command looks like it populates the list based on the discovered devices?
"BluetoothDevice hasn't been discovered yet"
Also, if I want to read and write characteristics, should I move from main to the overhaul branch?
Hi, I am running your project on my device and found this issue
Exception: AndroidJavaException: java.lang.SecurityException: Need android.permission.BLUETOOTH_SCAN permission for android.content.AttributionSource@4d29c837: GattService registerScanner
And as I was investigating more, I found that on Android 11+ plus devices, this problem is happening because of the permission security change and I also found the solution.
But here are some codes which you will have to add inside the jar files. So if you add those and update your project, I will be grateful and it can help a lot of us.
Hello,
I want to use this package as it seems very cool and useful! But when I build to android and run there is no interface to scan for devices and connect and read/write. I only see an empty scene. I noticed there is a BLE manager, but its not obvious how I am supposed to get started connecting to a device.
Do I need to create a BLE Object and attach that script to a game object? Then what do I need to change for this to work?
It would be nice if the example scene had a fake sensor or something to represent a device we would try to connect to, and then I can just change the UUID's for my device.
Thanks!
Hey! I was testing the implementation and it seems that the provided manifest is missing the bluetooth scan permission:
2024/02/25 20:08:31.653 25093 25117 Error Unity AndroidJavaException: java.lang.SecurityException: Need android.permission.BLUETOOTH_SCAN permission for AttributionSource { uid = 10867, packageName = com.sawce.catbotcontroller, attributionTag = null, token = android.os.BinderProxy@cb6860c, next = null }: GattService registerScanner
Hi
I have downloaded the package from releases tab dated March 20 2023.
I tried to build and run successfully. I am able to upload the .apk file to the android phone which has version 13.
App is running in the mobile but when clicked on scan, no devices are listed out. Screenshot of it is also attached here.
Unity version - 2022.3.25f1
API level - tried multiple levels - 22,32,33(which is my Android mobile's version)
Any help is appreciated.
I am trying to bring "Unity-Android-Bluetooth-Low-Energy" up to a newer version of Unity (preferably 2022.3.20f1) and the question I have is:
How much is the "unity.jar" in the "Unity-Android-Bluetooth-Low-Energy-Java-Library" repository tied to 2019.4.16f1?
On a related note, I have three versions of the unity editor and none of them have a "unity.jar". Where would one find it if one needed a newer version?
Hi, I'm trying to use your asset and it works perfectly. The only issue is that I want to subscribe to multiple characteristics but I only get the notifications for the first one. Is there any way I can solve this?
Thanks in advance!
This is my code:
using UnityEngine;
using Android.BLE;
using Android.BLE.Commands;
using UnityEngine.Android;
using System.Text;
public class BleCommunication : MonoBehaviour
{
private SubscribeToCharacteristic subscribePitch;
private SubscribeToCharacteristic subscribeYaw;
private SubscribeToCharacteristic subscribeRoll;
private SubscribeToCharacteristic subscribePosX;
private SubscribeToCharacteristic subscribePosY;
private SubscribeToCharacteristic subscribePosZ;
private float pitch;
private float yaw;
private float roll;
private float posX;
private float posY;
private float posZ;
private bool connected = false;
private bool subscribed = false;
[SerializeField]
private int _scanTime = 1000000;
private float _scanTimer = 0f;
private bool _isScanning = false;
public void Start()
{
if (!_isScanning)
{
_isScanning = true;
BleManager.Instance.QueueCommand(new DiscoverDevices(OnDeviceFound, _scanTime * 1000));
}
}
private void Update()
{
if (_isScanning)
{
Debug.Log("Scanning");
_scanTimer += Time.deltaTime;
if (_scanTimer > _scanTime)
{
_scanTimer = 0f;
_isScanning = false;
}
}
}
private void OnDeviceFound(string name, string device)
{
if(name == "05:C0:CB:A6:2F:77")
{
_isScanning = false;
BleManager.Instance.QueueCommand(new ConnectToDevice("05:C0:CB:A6:2F:77", OnConnected));
}
}
private void OnConnected(string uid)
{
connected = true;
Debug.Log("Connected");
Subscribe();
}
private void Subscribe()
{
subscribePitch = new SubscribeToCharacteristic("05:C0:CB:A6:2F:77", "181a", "2a5d", (byte[] value) =>
{
pitch = System.BitConverter.ToSingle(value, 0);
Debug.Log("Pitch: " + pitch);
});
subscribeYaw = new SubscribeToCharacteristic("05:C0:CB:A6:2F:77", "181a", "2a5c", (byte[] value) =>
{
yaw = System.BitConverter.ToSingle(value, 0);
Debug.Log("Yaw: " + yaw);
});
subscribeRoll = new SubscribeToCharacteristic("05:C0:CB:A6:2F:77", "181a", "2a5b", (byte[] value) =>
{
roll = System.BitConverter.ToSingle(value, 0);
Debug.Log("Roll: " + roll);
});
subscribePosX = new SubscribeToCharacteristic("05:C0:CB:A6:2F:77", "181a", "2a60", (byte[] value) =>
{
posX = System.BitConverter.ToSingle(value, 0);
Debug.Log("PosX: " + posX);
});
subscribePosY = new SubscribeToCharacteristic("05:C0:CB:A6:2F:77", "181a", "2a61", (byte[] value) =>
{
posY = System.BitConverter.ToSingle(value, 0);
Debug.Log("PosY: " + posY);
});
subscribePosZ = new SubscribeToCharacteristic("05:C0:CB:A6:2F:77", "181a", "2a62", (byte[] value) =>
{
posZ = System.BitConverter.ToSingle(value, 0);
Debug.Log("PosZ: " + posZ);
});
BleManager.Instance.QueueCommand(subscribeYaw);
BleManager.Instance.QueueCommand(subscribePitch);
BleManager.Instance.QueueCommand(subscribeRoll);
BleManager.Instance.QueueCommand(subscribePosX);
BleManager.Instance.QueueCommand(subscribePosY);
BleManager.Instance.QueueCommand(subscribePosZ);
subscribed = true;
}
I'm using the latest alpha version and noticed that if I call SearchForDevicesWithFilter and a device is found, the call to the function no longer works.
Below is a simplified version of the code I ran. Could I ask you to do a quick check and note what I did wrong here if you see anything?
public class DeviceA: MonoBehaviour
{
public string DeviceAddress;
Coroutine scanningRoutine = null;
public void StartScanning()
{
scanningRoutine = StartCoroutine(ScanForDevices());
}
IEnumerator ScanForDevices()
{
int scanDuration = 5;
while (true)
{
BleManager.Instance.SearchForDevicesWithFilter(
scanDuration * 1000,
OnDeviceFound,
deviceMac: DeviceAddress
);
yield return new WaitForSeconds(scanDuration + 0.1f);
}
}
private void OnDeviceFound(BleDevice device)
{
// does nothing with the device and simply restart the scan
StopCoroutine(scanningRoutine);
scanningRoutine = null;
StartScanning();
}
}
Hello,
first of all a big thank you for your efforts, just what I needed!
There is only one issue I'm facing: Whenever I change scene in Unity, the BLE stuff doesn't work anymore, and for each command, I get a NullPointerException when calling the library through the BLEManager.
My scenario:
In this scenario, the following works just fine:
In Scene 2, I discover and connect to my device, and afterwards I do a READ/SUBSCRIBE.
In this scenario, what does not work is:
In Scene 1, I try to do a READ/SUBSCRIBE command. As a result, I get a NullPointerException when doing Call to the bleLibrary in the Ble Manager. I also checked that none of the parameters are null, they are not.
I already tried:
Hi,
I might be missing something really obvious here, but so far I couldn’t figure it out.
I have set up an example scene in one unity project, where everything works fine. After I had some issues with another project, I added the same scene to that project for testing. There, I don’t see any BLE related errors in the logs, but for some reason no devices are discovered.
Both projects have the same Unity version, use your latest alpha release, run on the same device (an Oculus Quest), I added the same AndroidManifest-Patch-Script to both (for the BLE permissions). I even checked the project settings if I could find anything differences that might cause this. I really have no more ideas at the moment.
Any suggestions what else to check or what might cause this? I’d be very grateful for everything ^^.
I’m currently using the refactored version of your project and noticed there is no Disconnect()
method anymore. I also couldn’t find a method for it in the Java code.
Is there currently an option to initiate a disconnect?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.