BLE Heartrate monitor

My guess is that x is the data pointed to by service 180d and char 2a37

x[0], x[1] and x[2] are the first three bytes (?) of the data.

The heart rate is x[1] plus (if x[0] is 1) x[2] processed by whatever << 8 does.

I honestly just copied from koans yaml…

Sure! x is a vector of bytes with the raw data read from the characteristic 2A37. Then x[0] is the first byte, x[1] is the second byte, and so on.

If you read the specification of the Heart Rate Service , you’ll see that the Heart Rate Measurement characteristic has a specific format. The first byte has some flags (see section 3.1.1.1), with bit 0 the “Heart Rate Value Format bit”:

The Heart Rate Value Format bit (bit 0 of the Flags field) indicates if the data format of
the Heart Rate Measurement Value field is in a format of UINT8 or UINT16.
When the Heart Rate Value format is sent in a UINT8 format, the Heart Rate Value
Format bit shall be set to 0. When the Heart Rate Value format is sent in a UINT16
format, the Heart Rate Value Format bit shall be set to 1.

With x[0] & 1 (because 20 = 1) I test whether the rightmost bit (bit 0) of this byte is set to 1.

The second byte read from the characteristic is a byte with the heart rate, and if the Heart Rate Value Format bit is 1, the third byte is the next byte of the heart rate.

If the heart rate is measured with two bytes, x[2] has to be shifted 8 bits to the left, which is what x[2] << 8 does. The result is a 16-bit integer value constructed from the two bytes, with x[2] the leftmost byte and x[1] the rightmost byte.

On page 133 of the GATT Specification Supplement you can find a more structured depiction of the characteristic:

By the way, this forum thread inspired me to write a blog post a while ago about connecting to BLE devices with ESPHome. You’ll find some more background here:

3 Likes

Well you certainly improved my understanding, so thank you.

Thank you for the fantastic explanation! I will definitely be able to utilize your code for one of my projects.

Still working as of ESPhome 2023.7!

Just connected this with a plug to turn on my Zwift fan based on a heart rate threshold, giving me a chance to warm up before it starts

3 Likes