Main Content

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
ans=14×5 table
    Index           Name                           Address                    RSSI    Advertisement
    _____    ___________________    ______________________________________    ____    _____________

      1      ""                     "21996E3A-8F31-496D-B332-79D03B759BC7"    -65     [1×1 struct] 
      2      ""                     "12377421-4EA3-4F77-9365-EFD580C34DE9"    -66     [1×1 struct] 
      3      "UA E39 MODULE"        "8206F662-BA4A-483F-A908-516FF506BFB0"    -67     [1×1 struct] 
      4      ""                     "CF65AD36-2146-4CA1-BCEA-FED47F6195CA"    -76     [1×1 struct] 
      5      "UA Footpod 239AE2"    "CF7B1A17-4104-4D7B-AE70-1837CAE9C9D0"    -78     [1×1 struct] 
      6      ""                     "67A1A92A-5F1C-4AF8-857A-99F194E9A5F8"    -82     [1×1 struct] 
      7      ""                     "5609D68D-0EED-41D7-BE19-F3ACAA119C7A"    -84     [1×1 struct] 
      8      ""                     "5A17DF46-6F71-4DAC-AF0D-0F28E3911187"    -85     [1×1 struct] 
      9      ""                     "9675A0FA-0394-468B-B908-040696E1C5BC"    -88     [1×1 struct] 
     10      ""                     "61540D17-C2DD-41D4-B107-E2E7374B11F4"    -88     [1×1 struct] 
     11      ""                     "C2A5CCC3-CA6C-4688-AAE9-A5BE039561F9"    -92     [1×1 struct] 
     12      ""                     "AF5E1195-4088-4A4B-ADA5-0BD3C91BFE62"    -93     [1×1 struct] 
     13      ""                     "83C69EFB-0FAD-4A35-B167-79C51A1F245D"    -94     [1×1 struct] 
     14      ""                     "993276FD-07EC-433D-85E1-E144B289B648"    -95     [1×1 struct] 

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")
belt = 
  ble with properties:

               Name: "UA E39 MODULE"
            Address: "8206F662-BA4A-483F-A908-516FF506BFB0"
          Connected: 1
           Services: [4×2 table]
    Characteristics: [22×5 table]

Show services and characteristics
shoe = ble("UA Footpod 239AE2")
shoe = 
  ble with properties:

               Name: "UA Footpod 239AE2"
            Address: "CF7B1A17-4104-4D7B-AE70-1837CAE9C9D0"
          Connected: 1
           Services: [8×2 table]
    Characteristics: [39×5 table]

Show services and characteristics

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
ans=22×5 table
        ServiceName                      ServiceUUID                                   CharacteristicName                                CharacteristicUUID               Attributes 
    ____________________    ______________________________________    _____________________________________________________    ______________________________________    ____________

    "Heart Rate"            "180D"                                    "Heart Rate Measurement"                                 "2A37"                                    {["Notify"]}
    "Heart Rate"            "180D"                                    "Body Sensor Location"                                   "2A38"                                    {["Read"  ]}
    "Heart Rate"            "180D"                                    "Heart Rate Control Point"                               "2A39"                                    {["Write" ]}
    "Battery Service"       "180F"                                    "Battery Level"                                          "2A19"                                    {1×2 string}
    "Device Information"    "180A"                                    "System ID"                                              "2A23"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "Model Number String"                                    "2A24"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "Serial Number String"                                   "2A25"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "Firmware Revision String"                               "2A26"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "Hardware Revision String"                               "2A27"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "Software Revision String"                               "2A28"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "Manufacturer Name String"                               "2A29"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "IEEE 11073-20601 Regulatory Certification Data List"    "2A2A"                                    {["Read"  ]}
    "Device Information"    "180A"                                    "PnP ID"                                                 "2A50"                                    {["Read"  ]}
    "Custom"                "21A51000-4C86-11E2-BCFD-0800200C9A66"    "Custom"                                                 "21A51011-4C86-11E2-BCFD-0800200C9A66"    {1×2 string}
    "Custom"                "21A51000-4C86-11E2-BCFD-0800200C9A66"    "Custom"                                                 "21A51021-4C86-11E2-BCFD-0800200C9A66"    {1×2 string}
    "Custom"                "21A51000-4C86-11E2-BCFD-0800200C9A66"    "Custom"                                                 "21A51022-4C86-11E2-BCFD-0800200C9A66"    {["Write" ]}
      ⋮

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
ans=39×5 table
            ServiceName                         ServiceUUID                                   CharacteristicName                                CharacteristicUUID               Attributes 
    ___________________________    ______________________________________    _____________________________________________________    ______________________________________    ____________

    "Device Information"           "180A"                                    "System ID"                                              "2A23"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "Model Number String"                                    "2A24"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "Serial Number String"                                   "2A25"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "Firmware Revision String"                               "2A26"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "Hardware Revision String"                               "2A27"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "Software Revision String"                               "2A28"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "Manufacturer Name String"                               "2A29"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "IEEE 11073-20601 Regulatory Certification Data List"    "2A2A"                                    {["Read"  ]}
    "Device Information"           "180A"                                    "PnP ID"                                                 "2A50"                                    {["Read"  ]}
    "Battery Service"              "180F"                                    "Battery Level"                                          "2A19"                                    {1×2 string}
    "Running Speed and Cadence"    "1814"                                    "RSC Measurement"                                        "2A53"                                    {["Notify"]}
    "Running Speed and Cadence"    "1814"                                    "RSC Feature"                                            "2A54"                                    {["Read"  ]}
    "Running Speed and Cadence"    "1814"                                    "SC Control Point"                                       "2A55"                                    {1×2 string}
    "Custom"                       "21A54000-4C86-11E2-BCFD-0800200C9A66"    "Custom"                                                 "21A54001-4C86-11E2-BCFD-0800200C9A66"    {1×2 string}
    "Custom"                       "21A54000-4C86-11E2-BCFD-0800200C9A66"    "Custom"                                                 "21A54002-4C86-11E2-BCFD-0800200C9A66"    {1×2 string}
    "Custom"                       "21A54000-4C86-11E2-BCFD-0800200C9A66"    "Custom"                                                 "21A54003-4C86-11E2-BCFD-0800200C9A66"    {1×3 string}
      ⋮

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")
hr = 
  Characteristic with properties:

             Name: "Heart Rate Measurement"
             UUID: "2A37"
       Attributes: "Notify"
      Descriptors: [1x3 table]
 DataAvailableFcn: []

Show descriptors

Then read the current heart rate measurement from the device.

data = read(hr)
data = 1×4

    22    96    73     3

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);
Heart rate measurement: 96(bpm)

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")
rsc = 
  Characteristic with properties:

             Name: "RSC Measurement"
             UUID: "2A53"
       Attributes: "Notify"
      Descriptors: [1x3 table]
 DataAvailableFcn: []

Show descriptors

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

data = read(rsc)
data = 1×10

     3     0     0     0     0     0    84    57     0     0

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);
Instantaneous speed: 0.00(m/s) and instantaneous cadence: 0(steps per minute)

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