Clear Filters
Clear Filters

How to subscribe to multiple BLE characteristics that have the same service and characteristic UUID

30 views (last 30 days)
I am trying to figure out how to subscribe to multiple temperature sensors from a BLE device. My goal is to read all 8 temperature sensors at 1Hz. The BLE device has an environmental sensing service, here are what it's characteristics look like.
"ServiceName" "ServiceUUID" "CharacteristicName" "CharacteristicUUID" "Attributes"
"Generic Attribute" "1801" "Service Changed" "2A05" "Indicate"
"Generic Attribute" "1801" "Custom" "2B29" 1x2 string
"Generic Attribute" "1801" "Custom" "2B2A" "Read"
"Generic Access" "1800" "Device Name" "2A00" "Read"
"Generic Access" "1800" "Appearance" "2A01" "Read"
"Generic Access" "1800" "Peripheral Preferred Connection Parameters" "2A04" "Read"
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Temperature" "2A6E" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
"Environmental Sensing" "181A" "Humidity" "2A6F" 1x2 string
The 1x2 string is
"Read" "Notify"
The line that I am using works when there is one temperature sensor but not when there are multiple. The line is
characteristic(sensor, "Environmental Sensing", "Temperature")
When I call this line when there are multiple sensors present I get the following error Failed to discover descriptors. If device is disconnected, then clear existing ble object and recreate it. The BLE device is a nRF52 based chip that I wrote the code for with Zephyr. If there is something wrong with how I made the GATT then I can go fix it to work with Matlab better. The descriptors have a characteristic user data field that gives a name for each temperature sensor as Sensor X where X is 0-7. I have confirmed hat the device is not the issue and is programmed correctly by testing it nRF connect.
Update:
Stepping through the code I found the error coming from how the ble message is being given to the transport. It is passing a vector and not a scalar that it seems like it is expecting. For example in Characteristic.m line 315,
methods(Access = {?matlabshared.blelib.Descriptor, ?matlabshared.blelib.read.characteristic.Interface, ?matlabshared.blelib.write.characteristic.Interface})
function output = execute(obj, cmd, varargin)
peripheral = obj.getParent;
% Supress warning that might be thrown in get.Connected
ws = warning('off', 'MATLAB:ble:ble:deviceDisconnected');
c = onCleanup(@() cleanup(ws));
if ~peripheral.Connected
matlabshared.blelib.internal.localizedError('MATLAB:ble:ble:failToExecuteDeviceDisconnected');
end
output = peripheral.execute(cmd, obj.ServiceIndex, obj.CharacteristicIndex, varargin{:});
function cleanup(ws)
warning(ws.state, 'MATLAB:ble:ble:deviceDisconnected');
end
end
end
For the line
output = peripheral.execute(cmd, obj.ServiceIndex, obj.CharacteristicIndex, varargin{:});
the arguments are
cmd = DISCOVER_DESCRIPTORS
obj.ServiceIndex = 3
obj.CharacteristicIndex = [1;2;3;4;5;6;7;8]
It seems like obj.CharacteristicIndex should be just a number to get it to work.
It seems like the source of the issue starts in ble.m line 411 when
cinfo.Index = find(subtable.CharacteristicUUID == uuid);
returns a column vector instead of a scalar
function cinfo = validateCharacteristic(obj, sinfo, input)
% Check if input is a valid characteristic name or UUID supported
% on the peripheral and return index of the characteristic for
% the specified service
% Validate data type
info = matlabshared.blelib.internal.ServicesCharacteristicsDescriptorsInfo.getInstance;
uuid = info.getCharacteristicUUID(sinfo.UUID, input);
uuid = info.getShortestUUID(uuid);
% Find portion of the table that has the same ServiceUUID
subtable = obj.Characteristics(obj.Characteristics.ServiceUUID == obj.Services.ServiceUUID(sinfo.Index), :);
try
uuid = validatestring(uuid, subtable.CharacteristicUUID);
catch e
if strcmpi(e.identifier,'MATLAB:ambiguousStringChoice')
throwAsCaller(e);
else
matlabshared.blelib.internal.localizedError('MATLAB:ble:ble:unsupportedCharacteristic');
end
end
cinfo = info.getCharacteristicInfoByUUID(sinfo.UUID, uuid);
cinfo.Index = find(subtable.CharacteristicUUID == uuid);
cinfo.Attributes = subtable.Attributes{cinfo.Index};
end
end
It looks like edits to the files are locked so I can't quite write a new version of the functions to try and handle the case of multiple entries.

Accepted Answer

Graham
Graham on 24 Apr 2024
Matlab support gave the following response.
After investigating with the developers, unfortunately, it is not possible to subscribe to multiple characteristics with the same name and UUID. We understand that this is a limitation in MATLAB BLE.
I have submitted an enhancement request on your behalf to allow for subscribing to multiple characteristic definitions with the same service and UUID. The development team will consider the enhancement request for a future release.
I sincerely apologize that no workarounds exist at this time, and I would like to thank you for bringing this limitation to our attention. For internal purposes, I am closing this case for now. Please feel free to reach out in case you have any further questions. I am happy to reopen the case to ensure your queries are answered.
It looks like it can't be done as of April 2024. If it does get fixed someone could post an update in the future.

More Answers (1)

Shubham
Shubham on 24 Apr 2024
Edited: Shubham on 24 Apr 2024
Hey Graham,
I understand that you wish to subscribe to multiple temperature sensors from a BLE device. You are able to subscribe to a single temperature sensor but you fail to do so with multiple temperature sensors sharing same service name and characteristic UUID.
Since you were able to subscribe to a single temperature sensor, I believe you can use the device address in this case for subscribing to the service. Please refer to the following documentation which connects to the ble device by address, retrieves its characteristic values and subscribe to it: https://www.mathworks.com/help/matlab/import_export/log-BLE-using-callback-example.html
I hope this helps!

Products


Release

R2023b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!