Subscription has a problem recognizing messages.
Hello, im exepriencing some issues in making the subscription work with my arduino.
I have an arduino sending incremental messages every second: "hello - 1" , "hello - 2" , "hello - 3" , etc...
I wrote a small ConnectionManager script and when i tried using the subscribe to characteristic command, it either didnt work at all, or didnt invoke the "CharacteristicChanged" whenever a message was recieved.
the thing is, the BleManager does recieve and log the messages live, and when i try using the ReadFromCharacteristic command to read "manually", it does work.
I might be missing something basic and if it will help ill share the code, but for now i couldnt get it to work so I wanted to ask here for assistance.
thanks in advance :)
Can you attach your ConnectionManager class. I'd like to take a look.
here is the current version:
using UnityEngine;
using Android.BLE;
using Android.BLE.Commands;
using TMPro;
using System.Text;
public class BLEConnectionManager : MonoBehaviour
{
public TextMeshProUGUI messageText;
public bool read = true;
public bool write = false;
public bool subscribe = false;
[Header("BLE Settings")]
public string targetDeviceName = "BLE messenger"; // Name of your Arduino BLE device
public string messageServiceUuid = "19B10000-E8F2-537E-4F6C-D104768A1214"; // your service UUID
public string messageCharacteristicUuid = "19B10001-E8F2-537E-4F6C-D104768A1214"; // your characteristic UUID
private string targetDeviceAddress = null;
private bool isConnected = false;
private DiscoverDevices discoverCommand;
private ConnectToDevice connectCommand;
private SubscribeToCharacteristic subscribeCommand;
private ReadFromCharacteristic readCommand;
private WriteToCharacteristic writeCommand;
private void Start()
{
// Ensure the BLE Manager is initialized
if (!BleManager.IsInitialized)
{
BleManager.Instance.Initialize();
}
// Start scanning for devices
Debug.Log("Starting BLE device discovery...");
BleManager.Instance.QueueCommand(discoverCommand = new DiscoverDevices(OnDeviceDiscovered, OnDiscoveryFinished));
}
private void OnDeviceDiscovered(string deviceAddress, string deviceName)
{
Debug.Log($"Discovered Device: {deviceName} - {deviceAddress}");
// Check if the discovered device matches the target device name
if (deviceName == targetDeviceName)
{
Debug.Log($"Target device found: {deviceName}");
targetDeviceAddress = deviceAddress;
// Stop scanning and connect to the device
discoverCommand.End();
ConnectToDevice();
}
}
private void OnDiscoveryFinished()
{
Debug.Log("Device discovery finished.");
if (targetDeviceAddress == null)
{
Debug.LogWarning("Target device not found during discovery.");
}
}
private void ConnectToDevice()
{
if (targetDeviceAddress == null)
{
Debug.LogError("Target device address is null. Cannot connect.");
return;
}
Debug.Log($"Connecting to device: {targetDeviceName} - {targetDeviceAddress}");
// Create the ConnectToDevice command and use it
connectCommand = new ConnectToDevice(targetDeviceAddress, OnDeviceConnected, OnDeviceDisconnected);
BleManager.Instance.QueueCommand(connectCommand);
}
private void OnDeviceConnected(string deviceAddress)
{
if (deviceAddress == targetDeviceAddress)
{
Debug.Log($"Connected to device: {targetDeviceName} - {deviceAddress}");
isConnected = true;
if (read)
{
// Start periodic reading
InvokeRepeating(nameof(ReadFromCharacteristic), 1f, 1f); // Start reading every second
}
if (write)
{
// Start periodic writing
InvokeRepeating(nameof(WriteTimeSinceStart), 1f, 1f);
}
if (subscribe)
{
// Subscribe to the characteristic after connecting
SubscribeToCharacteristic();
}
}
}
private void ReadFromCharacteristic()
{
if (!isConnected)
{
Debug.LogWarning("Device not connected. Skipping read.");
return;
}
readCommand = new ReadFromCharacteristic(
targetDeviceAddress,
messageServiceUuid,
messageCharacteristicUuid,
DecodeMessage,
true
);
BleManager.Instance.QueueCommand(readCommand);
}
private void DecodeMessage(byte[] value)
{
string message = System.Text.Encoding.UTF8.GetString(value);
Debug.Log($"Decoded message: {message}");
messageText.text = message;
}
private void WriteToCharacteristic(string data)
{
if (!isConnected)
{
Debug.LogWarning("Device not connected. Cannot write.");
return;
}
// Encode the data in Base64
string base64EncodedData = Convert.ToBase64String(Encoding.UTF8.GetBytes(data));
//Debug.Log($"Writing Base64-encoded data: {base64EncodedData}");
writeCommand = new WriteToCharacteristic(
targetDeviceAddress,
messageServiceUuid,
messageCharacteristicUuid,
base64EncodedData,
true);
BleManager.Instance.QueueCommand(writeCommand);
Debug.Log($"Write command queued, sending message: {data}");
}
private void SubscribeToCharacteristic()
{
if (string.IsNullOrEmpty(messageServiceUuid) || string.IsNullOrEmpty(messageCharacteristicUuid))
{
Debug.LogError("Service UUID or Characteristic UUID is not set. Cannot subscribe.");
return;
}
Debug.Log($"Subscribing to characteristic: {messageCharacteristicUuid} in service: {messageServiceUuid}");
// Create the SubscribeToCharacteristic command
subscribeCommand = new SubscribeToCharacteristic(
targetDeviceAddress,
messageServiceUuid,
messageCharacteristicUuid,
OnCharacteristicChanged,
customGatt: true
);
BleManager.Instance.QueueCommand(subscribeCommand);
Debug.Log("Subscription command queued.");
}
private void WriteTimeSinceStart()
{
WriteToCharacteristic("Time elapsed since app started: " + Time.time.ToString());
}
private void OnCharacteristicChanged(byte[] value)
{
Debug.Log($"Raw data received: {value}");
string message = System.Text.Encoding.UTF8.GetString(value);
Debug.Log($"Characteristic value changed: {message}");
// Process the incoming message from the BLE device here
}
private void OnDeviceDisconnected(string deviceAddress)
{
if (deviceAddress == targetDeviceAddress)
{
Debug.LogWarning($"Disconnected from device: {deviceAddress}");
isConnected = false;
// Stop periodic reading
CancelInvoke(nameof(ReadFromCharacteristic));
}
}
private void OnDestroy()
{
// Clean up resources on destruction
if (isConnected && connectCommand != null)
{
Debug.Log("Disconnecting from device...");
connectCommand.Disconnect(); // Use Disconnect from ConnectToDevice
}
// Stop periodic reading
CancelInvoke(nameof(ReadFromCharacteristic));
}
}
for me the issue was the ids are caps vs non caps
if (CustomGatt)
{
if (string.Equals(obj.Device, DeviceAddress, StringComparison.OrdinalIgnoreCase) &&
string.Equals(obj.Service, Service, StringComparison.OrdinalIgnoreCase) &&
string.Equals(obj.Characteristic, Characteristic, StringComparison.OrdinalIgnoreCase))
{
OnCharacteristicChanged?.Invoke(obj.GetByteMessage());
}
}