%% Collect Data from Fitness Monitoring Devices
% This example shows how to collect and plot data from fitness monitoring devices using Bluetooth® Low Energy communication.
%% Hardware Setup
% This example uses an Under Armour® heart rate monitor belt and a pair of Under Armour smart running shoes. Both devices support Bluetooth Low Energy communication.
%
%% Discover and Connect to Devices
% First, check that the Bluetooth Low Energy devices support connections by finding them in MATLAB. The blelist function scans nearby Bluetooth Low Energy peripheral devices that are advertising.

blelist

%
% After the devices are found in MATLAB, connect to them by calling ble. Specify the name of the device if the name is unique, or specify the device address.

belt = ble("UA E39 MODULE")
shoe = ble("UA Footpod 239AE2")

% Access the Characteristics property of the ble object belt. This device has the "Heart Rate" service which contains the "Heart Rate Measurement" characteristic.

belt.Characteristics

% Access the Characteristics property of the ble object shoe. This device has the "Running Speed and Cadence" service which contains the "RSC Measurement" characteristic.

shoe.Characteristics

%
%% Read Heart Rate Data
% Next, create an object for the "Heart Rate Measurement" characteristic by specifying its service and characteristic information.

hr = characteristic(belt, "heart rate", "heart rate measurement")

% Then read the current heart rate measurement from the device.

data = read(hr)

% According to the Heart Rate Service specification in the Bluetooth Low Energy Specifications List, the "Heart Rate Measurement" characteristic value contains a flag byte followed by one or many heart rate values. The format of the measurement value depends on the flag value. Convert the raw data to a heart rate in beats per minute (bpm).

flag = uint8(data(1));
% Get the first bit of the flag, which indicates the format of the heart rate value
heartRateValueFormat = bitget(flag, 1);
if heartRateValueFormat == 0
    % Heart rate format is uint8
    heartRate = data(2);
else
    % Heart rate format is uint16
    heartRate = double(typecast(uint8(data(2:3)), 'uint16'));
end
fprintf('Heart rate measurement: %d(bpm)\n', heartRate);

%
%% Read Running Speed and Cadence Data
% Similarly, create an object for the "RSC Measurement" characteristic by specifying its service and characteristic information.

rsc = characteristic(shoe, "running speed and cadence", "rsc measurement")

% Then read the current running speed and cadence value from the device.

data = read(rsc)

% According to the Running Speed and Cadence Service specification in the Bluetooth Low Energy Specifications List, the "RSC Measurement" characteristic value contains 2 bytes that represents the instantaneous speed and 1 byte that represents the instantaneous cadence. Convert the raw data to a running speed in meters per second (m/s) and to a cadence in steps per minute.

instantaneousSpeed = double(typecast(uint8(data(2:3)), 'uint16'))/256;
instantaneousCadence = data(4);
fprintf('Instantaneous speed: %.2f(m/s) and instantaneous cadence: %d(steps per minute)\n', instantaneousSpeed, instantaneousCadence);

%
%% Correlate Heart Rate and Running Speed
% After reading the heart rate and RSC data, track live data during a running session and correlate the two measurements to analyze fitness performance.
% To show the correlation of fitness data, first create two plots to create an animation by adding data points in a loop.

% Create a plot for running speed against heart rate
axSpeed = axes('XLim', [0, 5], 'YLim', [60, 220]);
xlabel(axSpeed, 'Running speed (m/s)');
ylabel(axSpeed, 'Heart rate (bpm)');
subplot(1, 2, 1, axSpeed);
hSpeed = animatedline(axSpeed, 'Marker', 'o', 'MarkerFaceColor', 'green');

% Create a plot for running cadence against heart rate
axCadence = axes('XLim', [0, 200], 'YLim', [60 220]);
xlabel(axCadence, 'Running cadence (steps per minute)');
ylabel(axCadence, 'Heart rate (bpm)');
subplot(1, 2, 2, axCadence);
hCadence = animatedline(axCadence, 'Marker', 'o', 'MarkerFaceColor', 'blue');

%
% Next, read device data in a loop and update the plot as the user progresses from walking to jogging to running.

for loop = 1:30
    % Get heart rate data
    data = read(hr);
    flag = uint8(data(1));
    heartRateValueFormat = bitget(flag, 1);
    if heartRateValueFormat == 0
        heartRate = data(2);
    else
        heartRate = double(typecast(uint8(data(2:3)), 'uint16'));
    end
    
    % Get running speed data
    data = read(rsc);
    instantaneousSpeed = double(typecast(uint8(data(2:3)), 'uint16'))/256;
    instantaneousCadence = data(4);
    
    % Update plot with new data
    addpoints(hSpeed, instantaneousSpeed, heartRate);
    addpoints(hCadence, instantaneousCadence, heartRate);
    drawnow;
end

%
% These plots generally show that higher running speed and cadence values correspond to an increased heart rate.
%% Disconnect from Device
% Clear the device objects when you are finished working with them.

clear belt shoe

% Copyright 2019 The MathWorks, Inc.