Speeding up BLE packet collection?

7 views (last 30 days)
Taylor
Taylor on 7 Mar 2025
Answered: Jack on 7 Mar 2025
I'm trying to use Matlab to collect data from a custom BLE device. The device is sending a packet of 8 bytes at 125 Hz.
I'm able to connect to the device and recieve packets, but I'm not able to consistently meet the speeds of the device. Generally, I'm only getting packets at ~25 Hz. Using a python script, and hardware triggers, I know the device is sending at a rate of 125 Hz (I'd like to get even faster than that, but 125 Hz is the current target).
I've set a callback function to grab data on notify. Then toggle this callback function when needed. Currently using a waitbar to enable/ stop collection, as I need to be able to start/stop data on command- the tests I'm running don't have a specified time limit.
To connect to the device I'm using the following section of code:
%% Connect To Device
clear all;
global Data Timestamps;
MyDAQ = blelist("Name", "MT4", 'Timeout', 5);
MyDAQAdd = MyDAQ(:,3);
MyDAQAdd = string(table2array((MyDAQAdd)));
b = ble(MyDAQAdd);
b.Characteristics;
V_Ref = 1.4;
R_Ref = 5000;
VpBit = 0.000046008;
max_data_length = 10000;
FileNames = "Test";
FolderPath = "C:\Users\dradd\Desktop\Temp";
disp("Device Found");
c1 = characteristic(b, "0749b706-43ba-4cd9-9ea6-85bf0fc0b87e", "8e34967a-0ad7-4f8b-8b44-276b295eb3fd");
subscribe(c1, "notification");
% Initialize data and timestamp arrays
Data = zeros(max_data_length, 16);
Timestamps = datetime.empty(max_data_length, 0)';
function saveData(src, ~)
persistent datacount;
if isempty(datacount)
datacount = 0;
%global Data Timestamps;
%Data = zeros(10000, 16);
%Timestamps = datetime.empty(10000, 0);
end
[data, timestamp] = read(src, 'latest');
%timestamp.Format = 'MM/dd/uuuu HH:mm:ss.SSSS';
datacount = datacount + 1;
% Append data and timestamp to arrays
if (datacount == 100)
disp('100!');
datacount = 0;
end
%Data(datacount,:) = data;
%Timestamps(datacount) = timestamp;
end
Then run this to collect data:
%% Data Collection
hWaitbar = waitbar(0, 'Test 1', 'Name', 'Logging Data','CreateCancelBtn','delete(gcbf)');
c1.DataAvailableFcn = @(src, event) saveData(src, event);]
while (1)
if ~ishandle(hWaitbar)
disp('Stopped by user');
c1.DataAvailableFcn = @(src,event)[];
close all;
break;
end
pause(1);
end
%unsubscribe(c1);
disp('Done');

Answers (1)

Jack
Jack on 7 Mar 2025
Hey Taylor,
You're likely hitting a bottleneck in how MATLAB handles BLE notifications. By default, MATLAB's BLE communication can be slower due to overhead in event handling. Here are a few things you can try to speed it up:
% Increase buffer size and reduce processing overhead
b = ble(MyDAQAdd, 'Timeout', 10);
c1 = characteristic(b, "0749b706-43ba-4cd9-9ea6-85bf0fc0b87e", "8e34967a-0ad7-4f8b-8b44-276b295eb3fd");
subscribe(c1, "notification", 'BufferSize', 1000);
% Optimize callback function
function saveData(src, ~)
persistent datacount Data Timestamps;
if isempty(datacount)
datacount = 0;
Data = zeros(10000, 16);
Timestamps = datetime.empty(10000, 0)';
end
[data, timestamp] = read(src, 'latest');
datacount = datacount + 1;
Data(datacount, :) = data;
Timestamps(datacount) = timestamp;
if mod(datacount, 100) == 0
disp("Received 100 packets");
end
end
% Start data collection
c1.DataAvailableFcn = @saveData;
pause(10); % Run for a test period
c1.DataAvailableFcn = [];
What This Does
  • Increases buffer size to reduce packet loss.
  • Minimizes overhead by reducing global variable access.
  • Uses mod(datacount, 100) == 0 to display updates without excessive console output.
This should help improve your data rate. Follow me so you can message me anytime with future MATLAB questions.

Products


Release

R2024a

Community Treasure Hunt

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

Start Hunting!