Kodeco Forums

Core Bluetooth Tutorial for iOS: Heart Rate Monitor

In this Core Bluetooth tutorial, you’ll learn how to discover, connect to, and retrieve data from compatible devices like a chest-worn heart rate sensor.


This is a companion discussion topic for the original entry at https://www.raywenderlich.com/231-core-bluetooth-tutorial-for-ios-heart-rate-monitor

Thanks, this is great tutorial.

I’m looking forward to see more advance core bluetooth tutorials like save and read data from bluetooth device (NFC, etc.)
Do you think is it something you would consider to do in the future on RW website?

Thanks.

Hi @grzehotnik - Glad you like the tutorial! The RayWenderlich team determines what tutorials to write based on interest, so its possible we will do more Bluetooth tutorials if the team sees enough interest. In the meantime, there is an iBeacon tutorial and an Arduino Bluetooth tutorial that you can take a look at to learn more about using Bluetooth with iOS.

Thank you for an excellent tutorial!!!
I am following you until the private func hearthRate(), the last return and the <<8? Could you expand on that issue?
Now, if I want to extract the RR value(time between each hearthbeat), what would that function look like?
I could of course copy Rene Van Mils snippet:
http://www.vanmil.org/heart-rate-variability-and-brain-waves/
, but then I would not follow your elegant way of “attacking” the problem!

@jawwad Can you please help with this when you get a chance? Thank you - much appreciated! :]

Hi @toms,

So regarding the <<8, if the heart rate value is a 16-bit number, it will be present in the 2nd and 3rd bytes. Let’s say the 2nd byte has a value of 1, and the 3rd byte has a value of 5. The value of the 2nd bit has to be multiplied by 256 and then has to be added to the 3rd bit to give you the heart rate, which would be 256 + 5 = 261. Shifting the number by 8 bits to the left is the same as multiplying by 256.

Here is another way to look at it. Assume here are the first 3 bytes separated by dashes:
00000001-00000001-00000101

So the 2nd and 3rd bytes are the following:
00000001-00000101

If you take the value of the 2nd byte by itself it represents a 1, but within a 16 bit number it represents 256. Since we are reading the bytes individually, as 8-bit numbers, instead of collectively within a 16-bit number, we have to multiply the first byte by 256 ourselves. Does that make sense?

In order to extract the RR value, according to the spec you first have to determine if the Energy Expended field (C3) is present by looking at bit number 3 of the first byte. If it’s not present then RR value will be in the next two bytes after the heart rate, but if it is present, you’d skip over the next two bytes and get the value from the following two bytes.

Hope that helps.

Certainly does!!!
Thank you very much!!!
Toms

You may want to also checkout the Swift Pod/SPM BluetoothMessageProtocol, it has all of the Decodes pretty much all BLE Characteristics…

Thank you!!! EXCACTLY what I needed!!! Together with jawwads answer, I should (in theory) be well armed with knowledge for an adventure into the bluetooth world.
Bluetooth 5 HR measurement sensor anyone?
Respiration Rate, Temperature, Blood Pressure (cuff less) Bluetooth 5 sensors?

So I have a question. Would the app have to be open in order to get the data or would it just stay in the background until the device was close and automatically hook up via Bluetooth?
Thanks
Mark

Or, is it even possible to have an app that automatically connects every time?

Hi @coley396 - There is a Core Bluetooth background mode that you can enable. I haven’t experimented with using Bluetooth in the background but you can take a look at this page from Apple which has more info.

This tutorial is extremely helpful in order to learn and understand the Bluetooth frameworks.

I’ve noticed that it says in a note at the top that it was originally created in objective-c and I wondered if there is any way to see the objective-c tutorial?

Thanks.

@abextornsmith Only the tutorial’s Swift version is available on the website.

I am trying to connect this example with the ble of the pcb that I am developing.

Designate

When I scanned,
I can not scan.

let maestroServiceCBUUID = CBUUID(string:“05EC9AB8-5E94-8D71-C2DD-8CCBBDDFC744”)

If scanForPeripherals withServices is not specified as maestroCBUUID, it is searched when it is set to nil.

centralManager.scanForPeripherals(withServices:[maestroServiceCBUUID])

What settings did I make wrong?

@jawwad Can you please help with this when you get a chance? Thank you - much appreciated! :]

Hi @stevelee - I don’t fully understand the question, but I also haven’t done any work with custom Bluetooth boards so I don’t have an idea of what the problem might be. Sorry that I couldn’t be of more help.

@stevelee I had a similar issue.

The services you provide to the scan function should also exist in your advertisementData under the key
CBAdvertisementDataServiceUUIDsKey

let advertisedServiceUUIDs = [ CBUUI(string: xxxx) ]
peripheralManager.startAdvertising([
    CBAdvertisementDataServiceUUIDsKey: advertisedServiceUUIDs,
])

You don’t need to add all of your services here, just at least one that you can uniquely identify.
Hope that helps.

Hi @shapsuk - Thanks for chiming in on @stevelee’s question!

1 Like

Hi All

Its great tutorial, I have one question here if any one can help me. I was wondering suppose when the heart beat goes beyond danger value, I wanted to update user via vibrating that device. Suppose someone is wearing a BLE device which provides these characteristics, so how I can vibrate that BLE device after some danger point.

Thanks