# Circuit Playground Bluefruit BLE Heart Rate Pendant with CircuitPython

## Overview

https://www.youtube.com/watch?v=mI9duf38umI

Are you going to a dance party soon? Or maybe a speed dating night? Would you like to wear your heart out?

In this project, you can visibly show off your heart rate in the form of a pulsing pendant. A [Circuit Playground Bluefruit (CPB)](https://www.adafruit.com/product/4333) connects to a heart rate monitor to display the heartbeat of the wearer. Using the [CircuitPython](https://learn.adafruit.com/welcome-to-circuitpython/what-is-circuitpython?gclid=Cj0KCQiAraSPBhDuARIsAM3Js4oHxGfR5IdK9bZ12SXEZp9qrwaa981nFmrd01hEQFAQF_p4jm6f2tcaAvV9EALw_wcB) programming language, the CPB blinks with red [NeoPixels](https://learn.adafruit.com/adafruit-circuit-playground-bluefruit/circuitpython-neopixel) to display the heart rate.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/107/886/medium800/wearables_Heart_Necklace_Shoot_ORIG_251.jpg?1642610576)

Info: 

## Parts
## Heart Rate Monitor

You'll need a heart rate monitor that supports Bluetooth Low Energy (BLE). I'm using the&nbsp;[Scosche RHYTHM+](https://www.scosche.com/rhythm-plus-heart-rate-monitor-armband)&nbsp;but you should be able to use any monitor that uses the Bluetooth SIG Heart Rate service standard.

These work by flashing green (and sometimes yellow) LEDs against your skin and then measuring the reflected light that returns. The color changes/darkens during the pulse of your heart thanks to all that blood sloshing around!

![wearables_image.png](https://cdn-learn.adafruit.com/assets/assets/000/107/854/medium640/wearables_image.png?1642448592)

![](https://cdn-learn.adafruit.com/assets/assets/000/107/883/medium800/wearables_Heart_Necklace_Shoot_ORIG_257.jpg?1642610321)

### Circuit Playground Bluefruit - Bluetooth® Low Energy

[Circuit Playground Bluefruit - Bluetooth® Low Energy](https://www.adafruit.com/product/4333)
 **Circuit Playground Bluefruit** is our third board in the Circuit Playground series, another step towards a perfect introduction to electronics and programming. We've taken the popular Circuit Playground Express and made it even better! Now the main chip is an nRF52840...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4333)
[Related Guides to the Product](https://learn.adafruit.com/products/4333/guides)
![shot of a Black woman's neon-green manicured hand holding up a Circuit Playground Bluefruit glowing rainbow LEDs.](https://cdn-shop.adafruit.com/640x480/4333-11.jpg)

## Power

Option 1: you can use a small Lithium Ion Polymer or "Lipo" battery and affix it to the back of the CPB.

### Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh

[Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh](https://www.adafruit.com/product/4236)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 420mAh for a total of about 1.55 Wh. If you need a larger (or smaller!) battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4236)
[Related Guides to the Product](https://learn.adafruit.com/products/4236/guides)
![Lithium Ion Polymer Battery 3.7v 420mAh with JST 2-PH connector and short cable](https://cdn-shop.adafruit.com/640x480/4236-04.jpg)

Option 2: If you want to avoid lipos, you can use x3 AAA batteries with a battery back to get the same 3.7V to power the CPB.

### 3 x AAA Battery Holder with On/Off Switch and 2-Pin JST

[3 x AAA Battery Holder with On/Off Switch and 2-Pin JST](https://www.adafruit.com/product/727)
This battery holder connects 3 AAA batteries together in series for powering all kinds of projects. We spec'd these out because the box is slim, and 3 AAA's add up to about 3.3-4.5V, a very similar range to Lithium Ion/polymer (Li-Ion) batteries and have an on-off switch. That makes...

In Stock
[Buy Now](https://www.adafruit.com/product/727)
[Related Guides to the Product](https://learn.adafruit.com/products/727/guides)
![Front angled shot of 3 x AAA battery holder with on-off switch and 2-pin JST PH connector.](https://cdn-shop.adafruit.com/640x480/727-07.jpg)

### Alkaline AAA batteries - 3 pack

[Alkaline AAA batteries - 3 pack](https://www.adafruit.com/product/3520)
Battery power for your portable project! These batteries are good quality at a good price, and work fantastic with any of the kits or projects in the shop that use AAA's. This is a pack of **3 AAA batteries**.  
  
These batteries are Alkaline (MnO2) chemistry, with a...

In Stock
[Buy Now](https://www.adafruit.com/product/3520)
[Related Guides to the Product](https://learn.adafruit.com/products/3520/guides)
![Angled shot of 3 PKcell AAA batteries. ](https://cdn-shop.adafruit.com/640x480/3520-00.jpg)

## Optional Enclosure

There's a great case for the CPB that also works for the Circuit Playground Express (CPX). It is not required for this project but helps to make the NeoPixels a little more glowy and provides protection for the electronics.

### Adafruit Circuit Playground Express or Bluefruit Enclosure

[Adafruit Circuit Playground Express or Bluefruit Enclosure](https://www.adafruit.com/product/3915)
We've got nice cases for many of our beloved boards, but the [Circuit Playground Express](https://www.adafruit.com/product/3333)&nbsp;and [Circuit Playground&nbsp;Bluefruit](https://www.adafruit.com/product/4333) has been left out of couture enclosure...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3915)
[Related Guides to the Product](https://learn.adafruit.com/products/3915/guides)
![Top down view of a clear acrylic Adafruit Circuit Playground Express or Bluefruit Enclosure.](https://cdn-shop.adafruit.com/product-videos/640x480/3915-06.jpg)

## Other materials

- A lanyard or string for the pendant.
- double-sided tape for the battery.

Warning: 

# Circuit Playground Bluefruit BLE Heart Rate Pendant with CircuitPython

## Understanding BLE 

![](https://cdn-learn.adafruit.com/assets/assets/000/086/706/medium800/leds_512px-BluetoothLogo.svg.png?1578443885)

## BLE Basics

To understand how we communicate between the MagicLight Bulb and the Circuit Playground Bluefruit (CPB), it's first important to get an overview of how Bluetooth Low Energy (BLE) works in general.

The nRF52840 chip on the CPB uses Bluetooth Low Energy, or BLE. BLE is a wireless communication protocol used by many devices, including mobile devices. You can communicate between your CPB and peripherals such as the Magic Light, mobile devices, and even other CPB boards!

There are a few terms and concepts commonly used in BLE with which you may want to familiarize yourself. This will help you understand what your code is doing when you're using CircuitPython and BLE.

Two major concepts to know about are the two modes of BLE devices:

- Broadcasting mode (also called **GAP** for **G** eneric **A** ccess **P** rofile)
- Connected device mode (also called **GATT** for **G** eneric **ATT** ribute Profile).

**GAP** mode deals with broadcasting peripheral advertisements, such as "_I'm a device named LEDBlue-19592CBC_", as well as advertising information necessary to establish a dedicated device connection if desired. The peripheral may also be advertising available services.

**GATT** mode deals with communications and attribute transfer between two devices once they are connected, such as between a heart monitor and a phone, or between your CPB and the Magic Light.

![](https://cdn-learn.adafruit.com/assets/assets/000/086/833/medium800/leds_ble_modes.jpg?1578680670)

## Bluetooth LE Terms

### GAP Mode

#### Device Roles:

- **Peripheral** - The low-power device that broadcasts advertisements. Examples of peripherals include: heart rate monitor, smart watch, fitness tracker, iBeacon, and the Magic Light. The CPB can also work as a peripheral.
- **Central** - The host "computer" that observes advertisements being broadcast by the Peripherals. This is often a mobile device such as a phone, tablet, desktop or laptop, but the CPB can also act as a central (which it will in this project).

#### Terms:

- **Advertising** - Information sent by the peripheral before a dedicated connection has been established. **All** nearby Centrals can observe these advertisements. When a peripheral device advertises, it may be transmitting the name of the device, describing its capabilities, and/or some other piece of data. Central can look for advertising peripherals to connect to, and use that information to determine each peripheral's capabilities (or Services offered, more on that below).

### GATT Mode

#### Device Roles:

- **Server -** In connected mode, a device may take on a new role as a **Server** , providing a Service available to clients. It can now send and receive data packets as requested by the Client device to which it now has a connection.
- **Client -** In connected mode, a device may also take on a new role as **Client** that can send requests to one or more of a Server's available Services to send and receive data packets.

Primary: 

#### Terms:

- **Profile -** A pre-defined collection of **Services** that a BLE device can provide. For example, the Heart Rate Profile, or the Cycling Sensor (bike computer) Profile. These Profiles are defined by the Bluetooth Special Interest Group (SIG). For devices that don't fit into one of the pre-defined Profiles, the manufacturer creates their own Profile. For example, there is not a "Smart Bulb" profile, so the Magic Light manufacturer has created their own unique one.
- **Service** - A function the Server provides. For example, a heart rate monitor armband may have separate Services for **Device Information** , **Battery Service** , and **Heart Rate** itself. Each Service is comprised of collections&nbsp;of information called **Characteristics**. In the case of the Heart Rate Service, the two Characteristics are **Heart Rate Measurement** and **Body Sensor Location.** &nbsp;The peripheral advertises its services.&nbsp;
- **Characteristic -** A Characteristic is a container for the value, or attribute, of a piece of data along with any associated metadata, such as a human-readable name. A characteristic may be readable, writable, or both. For example, the Heart Rate Measurement Characteristic can be served up to the Client device and will report the heart rate measurement as a number, as well as the unit string "bpm" for beats-per-minute. The Magic Light Server has a Characteristic for the RGB value of the bulb which can be written to by the Central to change the color. Characteristics each have a Universal Unique Identifier (UUID) which is a 16-bit or 128-bit ID.
- **Packet** - Data transmitted by a device. BLE devices and host computers transmit and receive data in small bursts called packets.

[This guide](https://learn.adafruit.com/introduction-to-bluetooth-low-energy/introduction) is another good introduction to the concepts of BLE, including GAP, GATT, Profiles, Services, and Characteristics.

# Circuit Playground Bluefruit BLE Heart Rate Pendant with CircuitPython

## Heart Rate Service

The Bluetooth Special Interest Group has a standardized GATT ( **G** eneritt **ATT** ribute Profile) for heart rate monitors called the Heart Rate profile. (You can see a list of all the [GATT services here](https://www.bluetooth.com/specifications/gatt/services/).)

This defines the commands and data that can be exchanged between the heart rate sensor device and the client device such as a phone, tablet, or BLE capable microcontroller (like we'll use in our project).

If you want to see how the Bluetooth SIG defines a GATT, such as the Heart Rate Service, you can look at the official [XML file here](https://www.bluetooth.com/wp-content/uploads/Sitecore-Media-Library/Gatt/Xml/Services/org.bluetooth.service.heart_rate.xml).

Even better, run that URL through a code beautifier, such as codebeatify.org for a more human-readable version.

![](https://cdn-learn.adafruit.com/assets/assets/000/087/910/medium800/circuitpython_hrs_xml.png?1580487960)

## Heart Rate Characteristics

The Heart Rate service defines a three characteristics that can be served from the heart rate monitor (HRM) to a connected device.

### Heart Rate Measurement

The most important for most needs is the Heart Rate Measurement Values characteristic which serves up the following information:

- **Heart rate** , in beats per minute (BPM)
- **Contact** -- if the device is in contact with the body or not
- **Energy Expended** , in kilojoules
- **RR Intervals** in 1024ths of seconds -- this is the measurement of intervals between beats

Warning: 

### Body Sensor Location

Heart rate monitors will also include a characteristic for the intended location of the monitor on the body. This is built into the sensor firmware, not something that the device is determining on the fly! Standard values include:

- **Wrist**
- **Chest**
- **Finger**
- **Hand**
- **Ear Lobe**
- **Foot**
- **Other**

### Heart Rate Control Point

If the HRM includes the Energy Expended feature, the heart rate control point characteristic is used to allow the client device to write control points to the HRM.

## nRF Connect View

We can use the nRF Connect app from Nordic on [iOS](https://apps.apple.com/us/app/nrf-connect/id1054362403) and [Android](https://play.google.com/store/apps/details?id=no.nordicsemi.android.mcp&hl=en_US) to connect to a heart rate monitor and look at the service, characteristics, and data.

When we first connect to the device, we can see some data advertised including the device name, available services, connection parameters, manufacturer name, revision number, and more.

![](https://cdn-learn.adafruit.com/assets/assets/000/087/913/medium800/circuitpython_Screenshot_20200131-083207_nRF_Connect.jpg?1580489752)

In this image we can see the HRM device (RHYTHM+) has been connected, and the Heart Rate Measurement characteristic is reporting its data.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/087/911/medium800/circuitpython_Screenshot_20200131-083028_nRF_Connect.jpg?1580489351)

If we request a read of the Body Sensor Location characteristic, we receive it as shown here:

![](https://cdn-learn.adafruit.com/assets/assets/000/087/912/medium800/circuitpython_Screenshot_20200131-083015_nRF_Connect.jpg?1580489566)

# Circuit Playground Bluefruit BLE Heart Rate Pendant with CircuitPython

## CircuitPython on Circuit Playground Bluefruit

# Install or Update CircuitPython

Follow this quick step-by-step to install or update CircuitPython on your Circuit Playground Bluefruit.

[Download the latest version of CircuitPython for this board via circuitpython.org](https://circuitpython.org/board/circuitplayground_bluefruit/)
 **Click the link above and download the latest UF2 file**

Download and save it to your Desktop (or wherever is handy)

![adafruit_products_CPB_Download_UF2.png](https://cdn-learn.adafruit.com/assets/assets/000/080/530/medium640/adafruit_products_CPB_Download_UF2.png?1567715178)

Plug your Circuit Playground Bluefruit into your computer using a known-good data-capable USB cable.

**A lot of people end up using charge-only USB cables and it is very frustrating! So make sure you have a USB cable you know is good for data sync.**

Double-click the small **Reset** button in the middle of the CPB (indicated by the red arrow in the image). The ten NeoPixel LEDs will all turn red, and then will all turn green. If they turn all red and stay red, check the USB cable, try another USB port, etc. The little red LED next to the USB connector will pulse red - this is ok!

If double-clicking doesn't work the first time, try again. Sometimes it can take a few tries to get the rhythm right!

(If double-clicking doesn't do it, try a single-click!)

![adafruit_products_CPB_Front_Reset_Button_Arrow.jpg](https://cdn-learn.adafruit.com/assets/assets/000/080/532/medium640/adafruit_products_CPB_Front_Reset_Button_Arrow.jpg?1567715535)

You will see a new disk drive appear called **CPLAYBTBOOT**.

&nbsp;

&nbsp;

&nbsp;

Drag the **adafruit\_circuitpython\_etc.uf2** file to **CPLAYBTBOOT.**

![adafruit_products_CPB_CPLAYBTBOOT.png](https://cdn-learn.adafruit.com/assets/assets/000/080/533/medium640/adafruit_products_CPB_CPLAYBTBOOT.png?1567715858)

![adafruit_products_CBP_drag_UF2.png](https://cdn-learn.adafruit.com/assets/assets/000/080/534/medium640/adafruit_products_CBP_drag_UF2.png?1567715871)

The LEDs will turn red. Then, the **CPLAYBTBOOT** drive will disappear and a new disk drive called **CIRCUITPY** will appear.

That's it, you're done! :)

![adafruit_products_CBP_CIRCUITPY.png](https://cdn-learn.adafruit.com/assets/assets/000/080/535/medium640/adafruit_products_CBP_CIRCUITPY.png?1567716034)

# Circuit Playground Bluefruit BLE Heart Rate Pendant with CircuitPython

## Code the Heart Rate Display in CircuitPython

## Code Quickstart
If you'd just like to get the code working fast, click "Download Project Bundle" from the code below, copy the files over to your **CIRCUITPY** drive and verify the file system looks the same as here. Turn on your heart rate monitor and the program should be working!

![wearables_Screen_Shot_2022-01-17_at_3.13.20_PM.png](https://cdn-learn.adafruit.com/assets/assets/000/107/908/medium640/wearables_Screen_Shot_2022-01-17_at_3.13.20_PM.png?1642716232)

## Text Editor

If you'd like to edit the code, Adafruit recommends using the Mu editor. You can get more info in&nbsp;[this guide](https://learn.adafruit.com/welcome-to-circuitpython/installing-mu-editor).

Alternatively, you can use any text editor that saves files.

## Code.py

If you'd like to see the messages printed in the REPL, your CPB isn't working as intended, or you'd just like to dig into the code consider the following:

Copy the code shown below, paste it into Mu. Plug your CPB into your computer via a known good USB cable. In your operating system's file explorer/finder, you should see a new flash drive named&nbsp; **CIRCUITPY**. Save the code from Mu to the Feather's&nbsp; **CIRCUITPY** &nbsp;drive as **code.py**.&nbsp;

https://github.com/adafruit/Adafruit_Learning_System_Guides/blob/main/CPB_heart_rate_display/code.py

## Code Explainer
The code is doing several important things here.

First, the necessary libraries are loaded such as `board`, `time` and `neopixel`. Additionally, a slew of various **BLE**  **support** libraries are loaded.

```auto
import time
import board
import neopixel
import adafruit_ble
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
from adafruit_ble.services.standard.device_info import DeviceInfoService
from adafruit_ble_heart_rate import HeartRateService
from digitalio import DigitalInOut, Direction
```

## LED and NeoPixels Set Up

Next, the on board status LED is set up.

Then the NeoPixels are initialized and a special `color_chase` function is defined then called. This has a nice effect of red leads "circling" the board when the CPB boots up.&nbsp;

```auto
#on-board status LED setup
red_led = DigitalInOut(board.D13)
red_led.direction = Direction.OUTPUT
red_led.value = True

#NeoPixel code
pixels = neopixel.NeoPixel(board.NEOPIXEL, 10, brightness=0.2, auto_write=False)
RED = (255, 0, 0)
LIGHTRED = (20, 0, 0)

def color_chase(color, wait):
    for i in range(10):
        pixels[i] = color
        time.sleep(wait)
        pixels.show()
    time.sleep(0.5)

# animation to show initialization of program
color_chase(RED, 0.1)  # Increase the number to slow down the color chase
```

## Defining BPM and Connecting to a BLE Device

Next, an example `bpm` (**Beats Per Minute)** level is defined which will be changed immediately when a new bpm is detected.

We scan for a BLE device with the Heart Rate Service being advertised and set the status LED to match.

When we connect, the LED turns off and we stop scanning.

```auto
#starting bpm value
bpm = 60

# PyLint can't find BLERadio for some reason so special case it here.
ble = adafruit_ble.BLERadio()    # pylint: disable=no-member

hr_connection = None

# Start with a fresh connection.
if ble.connected:
    time.sleep(1)

    for connection in ble.connections:
        if HeartRateService in connection:
            connection.disconnect()
        break
        
while True:
    print("Scanning...")
    red_led.value = True
    time.sleep(1)

    for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=5):
        if HeartRateService in adv.services:
            print("found a HeartRateService advertisement")
            hr_connection = ble.connect(adv)
            time.sleep(2)
            print("Connected")
            red_led.value = False
            break

    # Stop scanning whether or not we are connected.
    ble.stop_scan()
    print("Stopped scan")
    red_led.value = False
    time.sleep(0.5)
```

## Device Info

With the heart rate monitor connected, the code requests info that is displayed in the Mu REPL, if your CPB is connected to your computer over USB. This is purely informational for curiosity and debug purposes.

```auto
if hr_connection and hr_connection.connected:
        print("Fetch connection")
        if DeviceInfoService in hr_connection:
            dis = hr_connection[DeviceInfoService]
            try:
                manufacturer = dis.manufacturer
            except AttributeError:
                manufacturer = "(Manufacturer Not specified)"
            try:
                model_number = dis.model_number
            except AttributeError:
                model_number = "(Model number not specified)"
            print("Device:", manufacturer, model_number)
        else:
            print("No device information")
        hr_service = hr_connection[HeartRateService]
        print("Location:", hr_service.location)
```

## Heart Rate and NeoPixels

Now this is "the heart" of the program! This is the code that loops over and over while the devices are connected.

First, we cast the heart rate service's measurement characteristic attributes that are sent as&nbsp;`values`, and then we cast the heart rate value itself as&nbsp;`bpm`

We'll check at first for non-zero bpm readings, as the heart rate monitor sends a few zeros at first, and we'll ignore them so nobody gets too worried, and just print dashes to the REPL.

## Calculating and Displaying the Heart Rate

Next, in order to convert the BPM into blinky heartbeats, we have to do a couple of calculations. I used the code from [this Hackaday project by Dillon Nichols](https://hackaday.io/project/161052-blink-an-led-to-your-heart-rate) to do the calculations.

The general idea is that each heartbeat consists of two parts, [a ventricular diastole, and a ventricular systole](https://en.wikipedia.org/wiki/Cardiac_cycle)\*.

From the below diagram, the&nbsp; **ventricular diastole&nbsp;** is the start of the cycle and is when the heart fills up with blood. The&nbsp; **ventricular systole** &nbsp;is the 2nd phase where the blood vigorously pumps and ejects the blood into the rest of the body.&nbsp;

&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/107/910/medium800/wearables_2027_Phases_of_the_Cardiac_Cycle.jpg?1642717322 https://en.wikipedia.org/wiki/Cardiac_cycle#/media/File:2027_Phases_of_the_Cardiac_Cycle.jpg)

## How long does each part last?

In terms of time, in general, the diastole is roughly 5/8s of the total cycle and the systole is about 3/8. So if one heartbeat took 1 second (60 BPM), the diastole would last about 0.625s (5/8) and the systole would like about 0.375s (3/8)

![wearables_Wiggers_Diagram_2.svg.png](https://cdn-learn.adafruit.com/assets/assets/000/107/909/medium640/wearables_Wiggers_Diagram_2.svg.png?1642717253)

A more nuanced explanation via [Wikipedia](https://en.wikipedia.org/wiki/Cardiac_cycle):

> At the start of the cycle, during&nbsp;[_ventricular diastole_–early](https://en.wikipedia.org/wiki/Diastole#Role_in_cardiac_cycle "Diastole"), the heart relaxes and expands while receiving blood into both ventricles through both atria; then, near the end of&nbsp;[_ventricular diastole_–late](https://en.wikipedia.org/wiki/Diastole#Role_in_cardiac_cycle "Diastole"), the two atria begin to contract ([_atrial systole_](https://en.wikipedia.org/wiki/Systole#Atrial_systole "Systole")), and each atrium pumps blood into the ventricle below it.<sup id="cite_ref-3" class="reference"><a href="https://en.wikipedia.org/wiki/Cardiac_cycle#cite_note-3">[3]</a></sup>&nbsp;During&nbsp;[_ventricular systole_](https://en.wikipedia.org/wiki/Systole#Ventricular_systole_and_Wiggers_diagram "Systole")&nbsp;the ventricles are contracting and vigorously pulsing (or ejecting) two separated blood supplies from the heart—one to the lungs and one to all other body organs and systems—while the two atria are relaxed ([_atrial diastole_](https://en.wikipedia.org/wiki/Diastole#Role_in_cardiac_cycle "Diastole")). This precise coordination ensures that blood is efficiently collected and circulated throughout the body.<sup id="cite_ref-4" class="reference"><a href="https://en.wikipedia.org/wiki/Cardiac_cycle#cite_note-4">[4]</a></sup>

Primary: 

So with this in mind, we now need to find the time for the diastole and systole for a given BPM. These times will then be given to the NeoPixels to turn them on and off. The diastole will be the time the NeoPixels are dimmed (longer) and the systole will be the time they are brightened (shorter).

## The Calculations

First, we convert BPM to beats per second. Then we find the period, which is the length of time for one heartbeat. Next, we multiply that by **3/8 or 0.375&nbsp;** to calculate the **systole time**. Lastly, the **diastole** is just the **period** - **the systole**.

Now we can take these values and tell the NeoPixels to brighten for the length of the systole and dim for the length of the diastole. How cool!

```auto
while hr_connection.connected:
            values = hr_service.measurement_values
            print(values)  # returns the full heart_rate data set
            if values:
                bpm = (values.heart_rate)
                if values.heart_rate == 0:
                    print("-")
                else:
                    time.sleep(0.1)
                    print(bpm)
            if bpm != 0: # prevent from divide by zero
                #find interval time between beats
                bps = bpm / 60
                period = 1 / bps
                time_on = 0.375 * period
                time_off = period - time_on

                # Blink leds at the given BPM
                pixels.fill(RED)
                pixels.show()
                time.sleep(time_on)
                pixels.fill(LIGHTRED)
                pixels.show()
                time.sleep(time_off)
```

# Circuit Playground Bluefruit BLE Heart Rate Pendant with CircuitPython

## Heart Rate Pendant in Action

![](https://cdn-learn.adafruit.com/assets/assets/000/107/889/medium800/wearables_Heart_Necklace_Shoot_ORIG_186_1.jpg?1642611095)

## The Lanyard

You may use any **non-conductive&nbsp;** material for the lanyard if you choose to string it through the holes of the CPB as shown in this guide. Yarn, hemp, twine, and plastic are all great materials that are easy to string through the CPB holes and tie into a necklace for easy wearing.

If you wish to use a conductive material for the lanyard such as a metal chain, you must ensure the material does not touch the CPB or you risk shorting the circuit and causing the CPB the malfunction or worse. One idea is you could use hot glue to glue the chain to the CPB plastic case. Be sure to use Kapton tape over the CPB pinholes to avoid a short.

Warning: 

## The Case

You may want to enclose the CPB but it is not required. If you use the Adafruit Circuit Playground case, follow these steps to make sure the case fits properly:

- Place the CPB on top of the bottom piece of the case.
- Place the top of the case over the CPB, making sure the pins on the CPB align with the pins labeled on the case.
- Make sure to align the switch on the CPB with the case's switch.&nbsp;
- Firmly press both the top and bottom of the case. You should feel a click as the case is snapped into place.
- If the case is not firmly snapped into place, try applying pressure to the case on the JST plug side as well as the USB micro b side.

![](https://cdn-learn.adafruit.com/assets/assets/000/107/888/medium800/wearables_Heart_Necklace_Shoot_ORIG_289.jpg?1642610746)

## Power

You can use either a Lipo battery or a AAA battery pack with x3 AAA batteries to power the CPB and make it mobile. Just use some double-sided tape to affix the power source to the back of the CPB case (or the CPB itself if you are omitting the case).

![](https://cdn-learn.adafruit.com/assets/assets/000/107/890/medium800thumb/wearables_wear_it_gif.jpg?1642611288)

That's it! Now go out there and show off your neat heart beat. Wear it loud, wear it proud.

## Inspiration and Attribution

This project was inspired by [Sidney San Martín](https://s4y.us/)'s [Heart Rate Collar build](https://blog.adafruit.com/2021/12/23/portable-bluetooth-heart-collar-nrf-bluetooth-polarglobal/). Additionally, it uses a similar concept from [Becky Stern's Heart Rate Badge guide.](https://learn.adafruit.com/heart-rate-badge) John Park's [CircuitPython BLE Heart Rate Zone Trainer Display](https://learn.adafruit.com/circuitpython-ble-heart-rate-monitor-gizmo), was a huge help for the BLE connection code.&nbsp;

![](https://cdn-learn.adafruit.com/assets/assets/000/107/905/medium800/wearables_image.png?1642708252)

![](https://cdn-learn.adafruit.com/assets/assets/000/107/906/medium800/wearables_image.png?1642708265)

https://www.youtube.com/watch?v=1j6aqB6q6_4


## Featured Products

### Adafruit Circuit Playground Express or Bluefruit Enclosure

[Adafruit Circuit Playground Express or Bluefruit Enclosure](https://www.adafruit.com/product/3915)
We've got nice cases for many of our beloved boards, but the [Circuit Playground Express](https://www.adafruit.com/product/3333)&nbsp;and [Circuit Playground&nbsp;Bluefruit](https://www.adafruit.com/product/4333) has been left out of couture enclosure...

Out of Stock
[Buy Now](https://www.adafruit.com/product/3915)
[Related Guides to the Product](https://learn.adafruit.com/products/3915/guides)
### Circuit Playground Bluefruit - Bluetooth® Low Energy

[Circuit Playground Bluefruit - Bluetooth® Low Energy](https://www.adafruit.com/product/4333)
 **Circuit Playground Bluefruit** is our third board in the Circuit Playground series, another step towards a perfect introduction to electronics and programming. We've taken the popular Circuit Playground Express and made it even better! Now the main chip is an nRF52840...

Out of Stock
[Buy Now](https://www.adafruit.com/product/4333)
[Related Guides to the Product](https://learn.adafruit.com/products/4333/guides)
### Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh

[Lithium Ion Polymer Battery with Short Cable - 3.7V 420mAh](https://www.adafruit.com/product/4236)
Lithium-ion polymer (also known as 'lipo' or 'lipoly') batteries are thin, light, and powerful. The output ranges from 4.2V when completely charged to 3.7V. This battery has a capacity of 420mAh for a total of about 1.55 Wh. If you need a larger (or smaller!) battery, <a...></a...>

In Stock
[Buy Now](https://www.adafruit.com/product/4236)
[Related Guides to the Product](https://learn.adafruit.com/products/4236/guides)
### 3 x AAA Battery Holder with On/Off Switch and 2-Pin JST

[3 x AAA Battery Holder with On/Off Switch and 2-Pin JST](https://www.adafruit.com/product/727)
This battery holder connects 3 AAA batteries together in series for powering all kinds of projects. We spec'd these out because the box is slim, and 3 AAA's add up to about 3.3-4.5V, a very similar range to Lithium Ion/polymer (Li-Ion) batteries and have an on-off switch. That makes...

In Stock
[Buy Now](https://www.adafruit.com/product/727)
[Related Guides to the Product](https://learn.adafruit.com/products/727/guides)
### Alkaline AAA batteries - 3 pack

[Alkaline AAA batteries - 3 pack](https://www.adafruit.com/product/3520)
Battery power for your portable project! These batteries are good quality at a good price, and work fantastic with any of the kits or projects in the shop that use AAA's. This is a pack of **3 AAA batteries**.  
  
These batteries are Alkaline (MnO2) chemistry, with a...

In Stock
[Buy Now](https://www.adafruit.com/product/3520)
[Related Guides to the Product](https://learn.adafruit.com/products/3520/guides)

## Related Guides

- [Adafruit Circuit Playground Bluefruit](https://learn.adafruit.com/adafruit-circuit-playground-bluefruit.md)
- [Wirelessly Code your Bluetooth Device with CircuitPython](https://learn.adafruit.com/wirelessly-code-your-bluetooth-device-with-circuitpython.md)
- [CircuitPython BLE Advertising Beacons](https://learn.adafruit.com/circuitpython-ble-advertising-beacons.md)
- [PyLeap device enabled - In Rainbows](https://learn.adafruit.com/pyleap-device-enabled-in-rainbows.md)
- [Bluefruit LE Connect for iOS and Android](https://learn.adafruit.com/bluefruit-le-connect.md)
- [Bluefruit Playground Hide and Seek](https://learn.adafruit.com/hide-n-seek-bluefruit-ornament.md)
- [Cyberpunk Santa Eye](https://learn.adafruit.com/cyberpunk-santa-eye.md)
- [PyLeap WAV Playback for Circuit Playground Bluefruit](https://learn.adafruit.com/pyleap-wav-playback-for-cpb.md)
- [Flapping Halloween Vampire Bat](https://learn.adafruit.com/flapping-halloween-vampire-bat.md)
- [Remote Control Candy Dispenser Ghost](https://learn.adafruit.com/ble-claw.md)
- [PyLeap App](https://learn.adafruit.com/pyleap-app.md)
- [Neopixel Crystal Chandelier with CircuitPython Animations and Speed Control](https://learn.adafruit.com/neopixel-crystal-chandelier-with-circuitpython-animations-and-speed-control.md)
- [Circuit Playground Bluetooth Cauldron](https://learn.adafruit.com/cpx-cauldron.md)
- [Sound Reactive Sunflower Baby Crib Mobile with Bluetooth Control](https://learn.adafruit.com/sound-reactive-sunflower-baby-crib-mobile-with-bluetooth-control.md)
- [Multi-tasking with CircuitPython](https://learn.adafruit.com/multi-tasking-with-circuitpython.md)
- [MakeCode Course for Circuit Playground Express](https://learn.adafruit.com/makecode-circuit-playground-express-course.md)
