Skip to content

Commit dadd025

Browse files
authored
Merge branch 'master' into master
2 parents 2258778 + 29b235e commit dadd025

File tree

33 files changed

+87990
-27
lines changed

33 files changed

+87990
-27
lines changed
Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
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.fill(0)
58+
for h in range(4):
59+
display_A.set_digit_raw(h, 0b10000000)
60+
# display_B show maximum heart rate value
61+
display_B.fill(0)
62+
display_B.print(max_rate)
63+
time.sleep(2)
64+
65+
# PyLint can't find BLERadio for some reason so special case it here.
66+
ble = adafruit_ble.BLERadio() # pylint: disable=no-member
67+
68+
hr_connection = None
69+
70+
def display_SCAN():
71+
display_A.fill(0)
72+
display_A.set_digit_raw(0, 0b01101101)
73+
display_A.set_digit_raw(1, 0b00111001)
74+
display_A.set_digit_raw(2, 0b01110111)
75+
display_A.set_digit_raw(3, 0b00110111)
76+
77+
78+
def display_bLE():
79+
display_B.fill(0)
80+
display_B.set_digit_raw(0, 0b00000000)
81+
display_B.set_digit_raw(1, 0b01111100)
82+
display_B.set_digit_raw(2, 0b00111000)
83+
display_B.set_digit_raw(3, 0b01111001)
84+
85+
def display_dots(): # "...."
86+
for j in range(4):
87+
display_A.set_digit_raw(j, 0b10000000)
88+
display_B.set_digit_raw(j, 0b10000000)
89+
90+
def display_dashes(): # "----"
91+
for k in range(4):
92+
display_A.set_digit_raw(k, 0b01000000)
93+
display_B.set_digit_raw(k, 0b01000000)
94+
95+
# Start with a fresh connection.
96+
if ble.connected:
97+
display_SCAN()
98+
display_bLE()
99+
time.sleep(1)
100+
101+
for connection in ble.connections:
102+
if HeartRateService in connection:
103+
connection.disconnect()
104+
break
105+
106+
while True:
107+
print("Scanning...")
108+
red_led.value = True
109+
blue_led.value = False
110+
display_SCAN()
111+
display_bLE()
112+
time.sleep(1)
113+
114+
115+
for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=5):
116+
if HeartRateService in adv.services:
117+
print("found a HeartRateService advertisement")
118+
hr_connection = ble.connect(adv)
119+
display_dots()
120+
time.sleep(2)
121+
print("Connected")
122+
blue_led.value = True
123+
red_led.value = False
124+
break
125+
126+
# Stop scanning whether or not we are connected.
127+
ble.stop_scan()
128+
print("Stopped scan")
129+
red_led.value = False
130+
blue_led.value = True
131+
time.sleep(0.5)
132+
133+
if hr_connection and hr_connection.connected:
134+
print("Fetch connection")
135+
if DeviceInfoService in hr_connection:
136+
dis = hr_connection[DeviceInfoService]
137+
try:
138+
manufacturer = dis.manufacturer
139+
except AttributeError:
140+
manufacturer = "(Manufacturer Not specified)"
141+
try:
142+
model_number = dis.model_number
143+
except AttributeError:
144+
model_number = "(Model number not specified)"
145+
print("Device:", manufacturer, model_number)
146+
else:
147+
print("No device information")
148+
hr_service = hr_connection[HeartRateService]
149+
print("Location:", hr_service.location)
150+
151+
while hr_connection.connected:
152+
values = hr_service.measurement_values
153+
print(values) # returns the full heart_rate data set
154+
if values:
155+
bpm = (values.heart_rate)
156+
if bpm is not 0:
157+
pct_target = (round(100*(bpm/max_rate)))
158+
display_A.fill(0) # clear the display
159+
display_B.fill(0)
160+
if values.heart_rate is 0:
161+
display_dashes()
162+
else:
163+
display_A.fill(0)
164+
display_B.print(pct_target)
165+
time.sleep(0.1)
166+
display_A.print(bpm)
167+
168+
time.sleep(0.9)
169+
display_A.set_digit_raw(0, 0b00000000)

BLE_Synth/cpb_amp_code.py

Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
'''BLE Synth
2+
File for the Circuit Playground Bluefruit
3+
Amp Portion'''
4+
from adafruit_circuitplayground.bluefruit import cpb
5+
from adafruit_led_animation.animation import Comet, AnimationGroup,\
6+
AnimationSequence
7+
import adafruit_led_animation.color as color
8+
from adafruit_ble import BLERadio
9+
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
10+
from adafruit_ble.services.nordic import UARTService
11+
from adafruit_bluefruit_connect.packet import Packet
12+
from adafruit_bluefruit_connect.color_packet import ColorPacket
13+
from adafruit_bluefruit_connect.button_packet import ButtonPacket
14+
15+
# easily call for NeoPixels to be off
16+
off = (0, 0, 0)
17+
# state to debounce on CPB end
18+
tone = False
19+
20+
# Setup for comet animation
21+
COMET_SPEED = 0.04 # Lower numbers increase the animation speed
22+
CPB_COMET_TAIL_LENGTH = 5 # The length of the comet on the Circuit Playground Bluefruit
23+
CPB_COMET_BOUNCE = False # Set to True to make the comet "bounce" the opposite direction on CPB
24+
25+
animations = AnimationSequence(
26+
AnimationGroup(
27+
Comet(cpb.pixels, COMET_SPEED, off, tail_length=CPB_COMET_TAIL_LENGTH,
28+
bounce=CPB_COMET_BOUNCE)))
29+
30+
# note frequencies
31+
C4 = 261.63
32+
Csharp4 = 277.18
33+
D4 = 293.66
34+
Dsharp4 = 311.13
35+
E4 = 329.63
36+
F4 = 349.23
37+
Fsharp4 = 369.99
38+
G4 = 392
39+
Gsharp4 = 415.3
40+
A4 = 440
41+
Asharp4 = 466.16
42+
B4 = 493.88
43+
44+
# note array
45+
note = [C4, Csharp4, D4, Dsharp4, E4, F4,
46+
Fsharp4, G4, Gsharp4, A4, Asharp4, B4]
47+
48+
# colors to recieve from color packet & for neopixels
49+
color_C = color.RED
50+
color_Csharp = color.ORANGE
51+
color_D = color.YELLOW
52+
color_Dsharp = color.GREEN
53+
color_E = color.TEAL
54+
color_F = color.CYAN
55+
color_Fsharp = color.BLUE
56+
color_G = color.PURPLE
57+
color_Gsharp = color.MAGENTA
58+
color_A = color.GOLD
59+
color_Asharp = color.PINK
60+
color_B = color.WHITE
61+
62+
# color array
63+
color = [color_C, color_Csharp, color_D, color_Dsharp, color_E,
64+
color_F, color_Fsharp, color_G, color_Gsharp, color_A,
65+
color_Asharp, color_B]
66+
67+
# Setup BLE connection
68+
ble = BLERadio()
69+
uart = UARTService()
70+
advertisement = ProvideServicesAdvertisement(uart)
71+
72+
while True:
73+
# connect via BLE
74+
ble.start_advertising(advertisement) # Start advertising.
75+
was_connected = False
76+
while not was_connected or ble.connected:
77+
if ble.connected: # If BLE is connected...
78+
was_connected = True
79+
# start animations
80+
animations.animate()
81+
# look for packets
82+
if uart.in_waiting:
83+
try:
84+
packet = Packet.from_stream(uart) # Create the packet object.
85+
except ValueError:
86+
continue
87+
# if it's a color packet:
88+
if isinstance(packet, ColorPacket):
89+
for i in range(12):
90+
colors = color[i]
91+
notes = note[i]
92+
# if the packet matches one of our colors:
93+
if packet.color == colors and not tone:
94+
# animate with that color
95+
animations.color = colors
96+
# play matching note
97+
cpb.start_tone(notes)
98+
tone = True
99+
# if it's a button packet aka feather's button has been released:
100+
elif isinstance(packet, ButtonPacket) and packet.pressed:
101+
if packet.button == ButtonPacket.RIGHT and tone:
102+
tone = False
103+
# stop playing the note
104+
cpb.stop_tone()
105+
# turn off the neopixels but keep animation active
106+
animations.color = off

0 commit comments

Comments
 (0)