Skip to content

Commit 1b2fe4e

Browse files
committed
first commit BLE heart rate trainer code
1 parent 51519c0 commit 1b2fe4e

File tree

1 file changed

+167
-0
lines changed

1 file changed

+167
-0
lines changed
Lines changed: 167 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,167 @@
1+
"""
2+
Heart Rate Trainer
3+
Read heart rate data from a heart rate peripheral using the standard BLE
4+
Heart Rate service.
5+
Displays BPM value to Seven Segment FeatherWing
6+
Displays percentage of max heart rate on another 7Seg FeatherWing
7+
"""
8+
9+
import time
10+
import board
11+
12+
import adafruit_ble
13+
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
14+
from adafruit_ble.services.standard.device_info import DeviceInfoService
15+
from adafruit_ble_heart_rate import HeartRateService
16+
17+
from adafruit_ht16k33.segments import Seg7x4
18+
19+
from digitalio import DigitalInOut, Direction
20+
21+
# Feather on-board status LEDs setup
22+
red_led = DigitalInOut(board.RED_LED)
23+
red_led.direction = Direction.OUTPUT
24+
red_led.value = True
25+
26+
blue_led = DigitalInOut(board.BLUE_LED)
27+
blue_led.direction = Direction.OUTPUT
28+
blue_led.value = False
29+
30+
# target heart rate for interval training
31+
# Change this number depending on your max heart rate, usually figured
32+
# as (220 - your age).
33+
max_rate = 180
34+
35+
# Seven Segment FeatherWing setup
36+
i2c = board.I2C()
37+
display_A = Seg7x4(i2c, address=0x70) # this will be the BPM display
38+
display_A.brightness = 15
39+
display_A.fill(0) # Clear the display
40+
# Second display has A0 address jumpered
41+
display_B = Seg7x4(i2c, address=0x71) # this will be the % target display
42+
display_B.brightness = 15
43+
display_B.fill(0) # Clear the display
44+
45+
# display_A "b.P.M."
46+
display_A.set_digit_raw(0, 0b11111100)
47+
display_A.set_digit_raw(1, 0b11110011)
48+
display_A.set_digit_raw(2, 0b00110011)
49+
display_A.set_digit_raw(3, 0b10100111)
50+
# display_B "Prct"
51+
display_B.set_digit_raw(0, 0b01110011)
52+
display_B.set_digit_raw(1, 0b01010000)
53+
display_B.set_digit_raw(2, 0b01011000)
54+
display_B.set_digit_raw(3, 0b01000110)
55+
time.sleep(3)
56+
57+
# display_A "...."
58+
display_A.fill(0)
59+
for h in range(4):
60+
display_A.set_digit_raw(h, 0b10000000)
61+
# display_B show maximum heart rate value
62+
display_B.fill(0)
63+
display_B.print(max_rate)
64+
time.sleep(2)
65+
66+
# PyLint can't find BLERadio for some reason so special case it here.
67+
ble = adafruit_ble.BLERadio() # pylint: disable=no-member
68+
69+
hr_connection = None
70+
71+
def display_SCAN():
72+
display_A.fill(0)
73+
display_A.set_digit_raw(0, 0b01101101)
74+
display_A.set_digit_raw(1, 0b00111001)
75+
display_A.set_digit_raw(2, 0b01110111)
76+
display_A.set_digit_raw(3, 0b00110111)
77+
78+
79+
def display_bLE():
80+
display_B.fill(0)
81+
display_B.set_digit_raw(0, 0b00000000)
82+
display_B.set_digit_raw(1, 0b01111100)
83+
display_B.set_digit_raw(2, 0b00111000)
84+
display_B.set_digit_raw(3, 0b01111001)
85+
86+
# Start with a fresh connection.
87+
if ble.connected:
88+
display_SCAN()
89+
display_bLE()
90+
time.sleep(1)
91+
92+
for connection in ble.connections:
93+
if HeartRateService in connection:
94+
connection.disconnect()
95+
break
96+
97+
while True:
98+
print("Scanning...")
99+
red_led.value = True
100+
blue_led.value = False
101+
display_SCAN()
102+
display_bLE()
103+
time.sleep(1)
104+
105+
106+
for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=5):
107+
if HeartRateService in adv.services:
108+
print("found a HeartRateService advertisement")
109+
hr_connection = ble.connect(adv)
110+
# "...."
111+
for j in range(4):
112+
display_A.set_digit_raw(j, 0b10000000)
113+
display_B.set_digit_raw(j, 0b10000000)
114+
115+
#display_B.fill(0)
116+
time.sleep(2)
117+
print("Connected")
118+
blue_led.value = True
119+
red_led.value = False
120+
break
121+
122+
# Stop scanning whether or not we are connected.
123+
ble.stop_scan()
124+
print("Stopped scan")
125+
red_led.value = False
126+
blue_led.value = True
127+
time.sleep(0.5)
128+
129+
if hr_connection and hr_connection.connected:
130+
print("Fetch connection")
131+
if DeviceInfoService in hr_connection:
132+
dis = hr_connection[DeviceInfoService]
133+
try:
134+
manufacturer = dis.manufacturer
135+
except AttributeError:
136+
manufacturer = "(Manufacturer Not specified)"
137+
try:
138+
model_number = dis.model_number
139+
except AttributeError:
140+
model_number = "(Model number not specified)"
141+
print("Device:", manufacturer, model_number)
142+
else:
143+
print("No device information")
144+
hr_service = hr_connection[HeartRateService]
145+
print("Location:", hr_service.location)
146+
147+
while hr_connection.connected:
148+
values = hr_service.measurement_values
149+
print(values) # returns the full heart_rate data set
150+
if values:
151+
bpm = (values.heart_rate)
152+
if bpm is not 0:
153+
pct_target = (round(100*(bpm/max_rate)))
154+
display_A.fill(0) # clear the display
155+
display_B.fill(0)
156+
if values.heart_rate is 0:
157+
for k in range(4):
158+
display_A.set_digit_raw(k, 0b01000000)
159+
display_B.set_digit_raw(k, 0b01000000)
160+
else:
161+
display_A.fill(0)
162+
display_B.print(pct_target)
163+
time.sleep(0.1)
164+
display_A.print(bpm)
165+
166+
time.sleep(0.9)
167+
display_A.set_digit_raw(0, 0b00000000)

0 commit comments

Comments
 (0)