Skip to content

Commit c98be11

Browse files
authored
Merge pull request adafruit#1181 from adafruit/TheKitty-patch-2
Code for Restroom Keys Guide
2 parents 93e7b91 + 1d99c03 commit c98be11

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

Bluetooth_Restroom_Keys/README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
## Code for the Adafruit Learning System guide Bluetooth Restroom Key Proximity Tracker
2+
3+
See this guide at https://learn.adafruit.com/bluetooth-restroom-key-proximity-tracker/
4+

Bluetooth_Restroom_Keys/code.py

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
"""Bluetooth Key Tracker."""
2+
from adafruit_ble import BLERadio
3+
from adafruit_led_animation.animation import Pulse, Solid
4+
import adafruit_led_animation.color as color
5+
from analogio import AnalogIn
6+
from array import array
7+
from audiobusio import I2SOut
8+
from audiocore import RawSample, WaveFile
9+
from board import BATTERY, D5, D6, D9, NEOPIXEL, RX, TX
10+
from digitalio import DigitalInOut, Direction, Pull
11+
from math import pi, sin
12+
from neopixel import NeoPixel
13+
from time import sleep
14+
15+
battery = AnalogIn(BATTERY)
16+
17+
ble = BLERadio()
18+
hit_status = [color.RED, color.ORANGE, color.AMBER, color.GREEN]
19+
20+
pixel = NeoPixel(NEOPIXEL, 1)
21+
pulse = Pulse(pixel,
22+
speed=0.01,
23+
color=color.PURPLE, # Use CYAN for Male Key
24+
period=3,
25+
min_intensity=0.0,
26+
max_intensity=0.5)
27+
28+
solid = Solid(pixel, color.GREEN)
29+
30+
reed_switch = DigitalInOut(D5)
31+
reed_switch.direction = Direction.INPUT
32+
reed_switch.pull = Pull.UP
33+
34+
amp_enable = DigitalInOut(D6)
35+
amp_enable.direction = Direction.OUTPUT
36+
amp_enable.value = False
37+
38+
39+
def play_tone():
40+
"""Generate tone and transmit to I2S amp."""
41+
length = 4000 // 440
42+
sine_wave = array("H", [0] * length)
43+
for i in range(length):
44+
sine_wave[i] = int(sin(pi * 2 * i / 18) * (2 ** 15) + 2 ** 15)
45+
46+
sample = RawSample(sine_wave, sample_rate=8000)
47+
i2s = I2SOut(TX, RX, D9)
48+
i2s.play(sample, loop=True)
49+
sleep(1)
50+
i2s.stop()
51+
sample.deinit()
52+
i2s.deinit()
53+
54+
55+
def play_message():
56+
"""Play recorded WAV message and transmit to I2S amp."""
57+
with open("d1.wav", "rb") as file:
58+
wave = WaveFile(file)
59+
i2s = I2SOut(TX, RX, D9)
60+
i2s.play(wave)
61+
while i2s.playing:
62+
pass
63+
wave.deinit()
64+
i2s.deinit()
65+
66+
67+
boundary_violations = 0
68+
69+
while True:
70+
if reed_switch.value: # Not Docked
71+
hits = 0
72+
try:
73+
advertisements = ble.start_scan(timeout=3)
74+
for advertisement in advertisements:
75+
addr = advertisement.address
76+
if (advertisement.scan_response and
77+
addr.type == addr.RANDOM_STATIC):
78+
if advertisement.complete_name == '<Your 1st beacon name here>':
79+
hits |= 0b001
80+
elif advertisement.complete_name == '<Your 2nd beacon name here>':
81+
hits |= 0b010
82+
elif advertisement.complete_name == '<Your 3rd beacon name here>':
83+
hits |= 0b100
84+
except Exception as e:
85+
print(repr(e))
86+
hit_count = len([ones for ones in bin(hits) if ones == '1'])
87+
solid.color = hit_status[hit_count]
88+
solid.animate()
89+
sleep(1)
90+
if hit_count == 0:
91+
if boundary_violations % 60 == 0: # Play message every 60 cycles
92+
amp_enable.value = True
93+
sleep(1)
94+
play_tone()
95+
sleep(1)
96+
play_message()
97+
sleep(1)
98+
amp_enable.value = False
99+
boundary_violations += 1
100+
else:
101+
boundary_violations = 0
102+
103+
else: # Docked
104+
boundary_violations = 0
105+
voltage = battery.value * 3.3 / 65535 * 2
106+
if voltage < 3.7:
107+
pulse.period = 1 # Speed up LED pulse for low battery
108+
else:
109+
pulse.period = 3
110+
pulse.animate()

0 commit comments

Comments
 (0)