Skip to content

Commit e6f01ec

Browse files
authored
Merge pull request adafruit#1105 from adafruit/ble_buzzy_box
Adding code for BLE Buzzy Box
2 parents d2f4fb1 + 7d59b0e commit e6f01ec

File tree

1 file changed

+179
-0
lines changed

1 file changed

+179
-0
lines changed

BLE_Buzzy_Box/code.py

Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
import time
2+
import board
3+
import busio
4+
import neopixel
5+
import adafruit_drv2605
6+
import adafruit_ble
7+
from adafruit_ble.advertising.standard import SolicitServicesAdvertisement
8+
from adafruit_ble.services.standard import CurrentTimeService
9+
from adafruit_ble_apple_notification_center import AppleNotificationCenterService
10+
from digitalio import DigitalInOut, Direction
11+
12+
# setup for onboard NeoPixel
13+
pixel_pin = board.NEOPIXEL
14+
num_pixels = 1
15+
16+
pixel = neopixel.NeoPixel(pixel_pin, num_pixels, brightness=0.3, auto_write=False)
17+
18+
# setup for haptic motor driver
19+
i2c = busio.I2C(board.SCL, board.SDA)
20+
drv = adafruit_drv2605.DRV2605(i2c)
21+
22+
# onboard blue LED
23+
blue_led = DigitalInOut(board.BLUE_LED)
24+
blue_led.direction = Direction.OUTPUT
25+
26+
# setup for BLE
27+
ble = adafruit_ble.BLERadio()
28+
if ble.connected:
29+
for c in ble.connections:
30+
c.disconnect()
31+
32+
advertisement = SolicitServicesAdvertisement()
33+
34+
# adds ANCS and current time services for BLE to advertise
35+
advertisement.solicited_services.append(AppleNotificationCenterService)
36+
advertisement.solicited_services.append(CurrentTimeService)
37+
38+
# state machines
39+
current_notification = None # tracks the current notification from ANCS
40+
current_notifications = {} # array to hold all current notifications from ANCS
41+
cleared = False # state to track if notifications have been cleared from ANCS
42+
notification_service = None # holds the array of active notifications from ANCS
43+
all_ids = [] # array to hold all of the ids from ANCS
44+
hour = 0 # used to track when it is on the hour for the mindfulness reminder
45+
mindful = False # state used to track if it is time for mindfulness
46+
vibration = 16 # vibration effect being used for the haptic motor
47+
blue = (0, 0, 255) # color blue for the NeoPixel
48+
purple = (255, 0, 255) # color purple for the NeoPixel
49+
red = (255, 0, 0) # color red for the NeoPixel
50+
clear = (0, 0, 0) # allows for NeoPixel to be turned 'off'
51+
52+
# function for blinking NeoPixel
53+
# blinks: # of blinks
54+
# speed: how fast/slow blinks
55+
# color1: first color
56+
# color2: second color
57+
def blink_pixel(blinks, speed, color1, color2):
58+
for _ in range(0, blinks):
59+
pixel.fill(color1)
60+
pixel.show()
61+
time.sleep(speed)
62+
pixel.fill(color2)
63+
pixel.show()
64+
time.sleep(speed)
65+
66+
# function for haptic motor vibration
67+
# num_zzz: # of times vibrates
68+
# effect: type of vibration
69+
# delay: time between vibrations
70+
def vibe(num_zzz, effect, delay):
71+
drv.sequence[0] = adafruit_drv2605.Effect(effect)
72+
for _ in range(0, num_zzz):
73+
drv.play() # play the effect
74+
time.sleep(delay) # for 0.5 seconds
75+
drv.stop()
76+
77+
# start BLE
78+
ble.start_advertising(advertisement)
79+
80+
while True:
81+
82+
blue_led.value = False
83+
print("Waiting for connection")
84+
85+
# NeoPixel is red when not connected to BLE
86+
while not ble.connected:
87+
blue_led.value = False
88+
pixel.fill(red)
89+
pixel.show()
90+
91+
print("Connected")
92+
93+
while ble.connected:
94+
blue_led.value = True # blue LED is on when connected
95+
all_ids.clear()
96+
for connection in ble.connections:
97+
if not connection.paired:
98+
# pairs to phone
99+
connection.pair()
100+
print("paired")
101+
# allows connection to CurrentTimeService
102+
cts = connection[CurrentTimeService]
103+
notification_service = connection[AppleNotificationCenterService]
104+
# grabs notifications from ANCS
105+
current_notifications = notification_service.active_notifications
106+
107+
for notif_id in current_notifications:
108+
# adds notifications into array
109+
notification = current_notifications[notif_id]
110+
all_ids.append(notif_id)
111+
112+
if current_notification and current_notification.removed:
113+
# Stop showing the latest and show that there are no new notifications.
114+
current_notification = None
115+
pixel.fill(clear)
116+
pixel.show()
117+
118+
if not current_notification and not all_ids and not cleared:
119+
# updates cleared state for notification
120+
cleared = True
121+
# turns off NeoPixel when notifications are clear
122+
pixel.fill(clear)
123+
pixel.show()
124+
125+
elif all_ids:
126+
cleared = False
127+
if current_notification and current_notification.id in all_ids:
128+
index = all_ids.index(current_notification.id)
129+
else:
130+
index = len(all_ids) - 1
131+
notif_id = all_ids[index]
132+
# if there is a notification:
133+
if not current_notification or current_notification.id != notif_id:
134+
current_notification = current_notifications[notif_id]
135+
# parses notification info into a string
136+
category = str(notification).split(" ", 1)[0]
137+
# haptic motor vibrates
138+
vibe(2, vibration, 0.5)
139+
# all info for notification is printed to REPL
140+
print('-'*36)
141+
print("Msg #%d - Category %s" % (notification.id, category))
142+
print("From app:", notification.app_id)
143+
if notification.title:
144+
print("Title:", notification.title)
145+
if notification.subtitle:
146+
print("Subtitle:", notification.subtitle)
147+
if notification.message:
148+
print("Message:", notification.message)
149+
# NeoPixel blinks and then stays on until cleared
150+
blink_pixel(2, 0.5, purple, clear)
151+
pixel.fill(purple)
152+
pixel.show()
153+
# if it's on the hour:
154+
if cts.current_time[4] == hour and not mindful:
155+
print(cts.current_time[4])
156+
print("mindful time")
157+
# haptic motor vibrates
158+
vibe(5, vibration, 1)
159+
# NeoPixel blinks and then stays on
160+
blink_pixel(5, 1, blue, clear)
161+
mindful = True
162+
pixel.fill(blue)
163+
pixel.show()
164+
print("hour = ", hour)
165+
# if it's no longer on the hour:
166+
if cts.current_time[4] == (hour + 1) and mindful:
167+
# NeoPixel turns off
168+
mindful = False
169+
pixel.fill(clear)
170+
pixel.show()
171+
print("mindful time over")
172+
173+
# if BLE becomes disconnected then blue LED turns off
174+
# and BLE begins advertising again to reconnect
175+
print("Disconnected")
176+
blue_led.value = False
177+
print()
178+
ble.start_advertising(advertisement)
179+
notification_service = None

0 commit comments

Comments
 (0)