Skip to content

Commit dc43693

Browse files
committed
Copy CLUE projects to new CLUE subdirectory
To "clean up" the Learn System repo, we need to move groups of guides into subdirectories. This PR duplicates the CLUE guides into the CLUE subdirectory so guides may be changed prior to deleting redundant project repos to make more space.
1 parent 0e17763 commit dc43693

File tree

112 files changed

+283061
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

112 files changed

+283061
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
CLUE_Altimeter/clue_altimeter.py 26: Access to a protected member _pressure of a client class (protected-access)
2+
CLUE_Altimeter/clue_altimeter.py 27: Access to a protected member _pressure of a client class (protected-access)
3+
CLUE_Altimeter/clue_altimeter.py 28: Access to a protected member _pressure of a client class (protected-access)
4+
CLUE_Altimeter/clue_altimeter.py 29: Access to a protected member _pressure of a client class (protected-access)
5+
CLUE_Altimeter/clue_altimeter.py 30: Access to a protected member _pressure of a client class (protected-access)
6+
CLUE_Altimeter/clue_altimeter.py 121: Redefining name 'now' from outer scope (line 172) (redefined-outer-name)
7+
CLUE_Altimeter/clue_altimeter.py 110: Unused argument 'current_sea_level_pressure' (unused-argument)
8+
CLUE_Altimeter/clue_altimeter.py 7: Unused bitmap_font imported from adafruit_bitmap_font (unused-import)

CLUE/CLUE_Altimeter/code.py

Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
# SPDX-FileCopyrightText: 2020 Carter Nelson for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
import time
6+
import struct
7+
import displayio
8+
import terminalio
9+
from microcontroller import nvm
10+
from adafruit_display_text import label
11+
import adafruit_imageload
12+
from adafruit_clue import clue
13+
14+
# ==| USER CONFIG |=====================
15+
USE_METRIC = False
16+
DISPLAY_UPDATE = 1
17+
HOLD_TO_SET = 1
18+
FONT = terminalio.FONT
19+
BLUE = 0x53E4FF
20+
ORANGE = 0xFCDF03
21+
RED = 0xFA0000
22+
DEBOUNCE = 0.05
23+
SAMPLES = 10
24+
DELAY = 0.05
25+
STD_SLP = 1013.25
26+
# ==| USER CONFIG |=====================
27+
28+
# configure pressure sensor (see Table 15 in datasheet)
29+
clue._pressure.mode = 0x03 # normal
30+
clue._pressure.overscan_pressure = 0x05 # x16
31+
clue._pressure.overscan_temperature = 0x02 # x2
32+
clue._pressure.iir_filter = 0x02 # 4
33+
clue._pressure.standby_period = 0x01 # 62.5 ms
34+
35+
# restore saved sea level pressure from NVM
36+
slp = struct.unpack("f", nvm[0:4])[0]
37+
clue.sea_level_pressure = slp if 0 < slp < 2000 else STD_SLP
38+
39+
# --------------------------------------------------------------------
40+
# D I S P L A Y S E T U P
41+
# --------------------------------------------------------------------
42+
43+
# create main display group
44+
splash = displayio.Group()
45+
clue.display.root_group = splash
46+
47+
# background
48+
bg_bmp, bg_pal = adafruit_imageload.load(
49+
"images/network23.bmp", bitmap=displayio.Bitmap, palette=displayio.Palette
50+
)
51+
for i, color in enumerate(bg_pal):
52+
if color == 0xFF0000:
53+
bg_pal.make_transparent(i)
54+
break
55+
background = displayio.TileGrid(bg_bmp, pixel_shader=bg_pal)
56+
57+
# a group for both altitude readouts
58+
alti_readouts = displayio.Group(scale=6)
59+
60+
# altitude (corrected)
61+
alti_disp = label.Label(FONT, text="12345", color=ORANGE)
62+
alti_disp.anchor_point = (0, 0)
63+
alti_disp.anchored_position = (7, 2)
64+
65+
# altitude (uncorrected)
66+
alt2_disp = label.Label(FONT, text="12345", color=ORANGE)
67+
alt2_disp.anchor_point = (0, 0)
68+
alt2_disp.anchored_position = (7, 15)
69+
70+
# add both alti's to group
71+
alti_readouts.append(alti_disp)
72+
alti_readouts.append(alt2_disp)
73+
74+
# barometric pressure and temperature
75+
aux_data = label.Label(FONT, text="P: 1234.56 T: 123.4", color=BLUE)
76+
aux_data.anchor_point = (0, 0)
77+
aux_data.anchored_position = (16, 212)
78+
79+
# calibration mode indicator
80+
cal_mode = label.Label(FONT, text=" ", color=RED, scale=4, x=150, y=200)
81+
82+
# add everything to splash
83+
splash.append(background)
84+
splash.append(alti_readouts)
85+
splash.append(aux_data)
86+
splash.append(cal_mode)
87+
88+
# --------------------------------------------------------------------
89+
# H E L P E R F U N C T I O N S
90+
# --------------------------------------------------------------------
91+
def compute_altitude(barometric_pressure, sea_level_pressure):
92+
"""Compute altitude (m) from barometric pressure (hPa) and sea level pressure (hPa)."""
93+
# https://www.weather.gov/media/epz/wxcalc/pressureAltitude.pdf
94+
return 44307.69396 * (1 - pow((barometric_pressure / sea_level_pressure), 0.190284))
95+
96+
97+
def compute_sea_level_pressure(barometric_pressure, altitude):
98+
"""Compute sea level pressure (hPa) from barometric pressure (hPa) and altitude (m)."""
99+
return barometric_pressure * pow((1 - (altitude / 44307.69396)), -5.2553)
100+
101+
102+
def average_readings(samples=10, delay=0.05):
103+
"""Return averaged readings for pressure and temperature."""
104+
pressure = 0
105+
temperature = 0
106+
for _ in range(samples):
107+
pressure += clue.pressure
108+
temperature += clue.temperature
109+
time.sleep(delay)
110+
return pressure / samples, temperature / samples
111+
112+
113+
def recalibrate(current_sea_level_pressure=None):
114+
"""Enter current altitude."""
115+
cal_mode.text = "CAL"
116+
alt2_disp.text = "-----"
117+
# wait for release if still being held
118+
while clue.button_a and clue.button_b:
119+
pass
120+
# get current value
121+
altitude = int(alti_disp.text)
122+
done = False
123+
while not done:
124+
now = time.monotonic()
125+
# increase
126+
if clue.button_a and not clue.button_b:
127+
altitude -= 1
128+
time.sleep(DEBOUNCE)
129+
# decrease
130+
elif clue.button_b and not clue.button_a:
131+
altitude += 1
132+
time.sleep(DEBOUNCE)
133+
# hold both to set
134+
elif clue.button_a and clue.button_b:
135+
while clue.button_a and clue.button_b:
136+
if time.monotonic() - now > HOLD_TO_SET:
137+
print("done")
138+
done = True
139+
break
140+
alti_disp.text = "{:5d}".format(altitude)
141+
cal_mode.text = " "
142+
# change clue settings
143+
if not USE_METRIC:
144+
altitude *= 0.3048
145+
# get current local pressure
146+
barometric_pressure, _ = average_readings(SAMPLES, DELAY)
147+
# compute sea level pressure and set
148+
clue.sea_level_pressure = compute_sea_level_pressure(barometric_pressure, altitude)
149+
# store in NVM for later use
150+
nvm[0:4] = struct.pack("f", clue.sea_level_pressure)
151+
152+
153+
def update_display():
154+
"""Update the display with latest info."""
155+
barometric_pressure, temperature = average_readings(SAMPLES, DELAY)
156+
altitude = compute_altitude(barometric_pressure, clue.sea_level_pressure)
157+
alt2tude = compute_altitude(barometric_pressure, STD_SLP)
158+
if not USE_METRIC:
159+
altitude *= 3.28084 # ft
160+
alt2tude *= 3.28084
161+
# barometric_pressure *= 0.0145038 # psi
162+
temperature = 32 + 1.8 * temperature # deg F
163+
alti_disp.text = "{:5d}".format(int(altitude))
164+
alt2_disp.text = "{:5d}".format(int(alt2tude))
165+
aux_data.text = "P: {:7.2f} T: {:5.1f}".format(barometric_pressure, temperature)
166+
167+
168+
# --------------------------------------------------------------------
169+
# M A I N L O O P
170+
# --------------------------------------------------------------------
171+
last_update = time.monotonic()
172+
173+
while True:
174+
175+
now = time.monotonic()
176+
177+
# update display with latest info
178+
if now - last_update > DISPLAY_UPDATE:
179+
update_display()
180+
last_update = now
181+
182+
# hold both to recalibrate
183+
if clue.button_a and clue.button_b:
184+
# accumulate hold time
185+
while clue.button_a and clue.button_b:
186+
if time.monotonic() - now > HOLD_TO_SET:
187+
print("set")
188+
recalibrate(clue.sea_level_pressure)
189+
break
190+
# wait for release if still being held
191+
while clue.button_a and clue.button_b:
192+
pass
28.3 KB
Binary file not shown.

CLUE/CLUE_BBQ/code.py

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
# SPDX-FileCopyrightText: 2020 John Park for Adafruit Industries
2+
#
3+
# SPDX-License-Identifier: MIT
4+
5+
# Adafruit BBQ display works with ibbq protocol-based BLE temperature probes
6+
7+
import time
8+
9+
import displayio
10+
import _bleio
11+
import adafruit_ble
12+
from adafruit_ble.advertising.standard import ProvideServicesAdvertisement
13+
from adafruit_ble_ibbq import IBBQService
14+
from adafruit_clue import clue
15+
from adafruit_display_shapes.circle import Circle
16+
from adafruit_display_text import label
17+
from adafruit_bitmap_font import bitmap_font
18+
19+
clue.display.brightness = 1.0
20+
homescreen_screen = displayio.Group()
21+
temperatures_screen = displayio.Group()
22+
23+
# define custom colors
24+
GREEN = 0x00D929
25+
BLUE = 0x0000FF
26+
RED = 0xFF0000
27+
ORANGE = 0xFF6A00
28+
YELLOW = 0xFFFF00
29+
PURPLE = 0xE400FF
30+
BLACK = 0x000000
31+
WHITE = 0xFFFFFF
32+
BURNT = 0xBB4E00
33+
34+
unit_mode = False # set the temperature unit_mode. True = centigrade, False = farenheit
35+
36+
# Setup homescreen
37+
color_bitmap = displayio.Bitmap(120, 120, 1)
38+
color_palette = displayio.Palette(1)
39+
color_palette[0] = BURNT
40+
bg_sprite = displayio.TileGrid(color_bitmap, x=120, y=0, pixel_shader=color_palette)
41+
homescreen_screen.append(bg_sprite)
42+
43+
clue_color = [GREEN, BLUE, RED, ORANGE, YELLOW, PURPLE]
44+
45+
outer_circle = Circle(120, 120, 119, fill=BLACK, outline=BURNT)
46+
homescreen_screen.append(outer_circle)
47+
48+
49+
title_font = bitmap_font.load_font("/font/GothamBlack-50.bdf")
50+
title_font.load_glyphs("BQLUE".encode("utf-8"))
51+
title_label = label.Label(title_font, text="BBQLUE", color=clue.ORANGE)
52+
title_label.x = 12
53+
title_label.y = 120
54+
homescreen_screen.append(title_label)
55+
56+
clue.display.root_group = homescreen_screen
57+
58+
# Setup temperatures screen
59+
temp_font = bitmap_font.load_font("/font/GothamBlack-25.bdf")
60+
temp_font.load_glyphs("0123456789FC.-<".encode("utf-8"))
61+
62+
my_labels_config = [
63+
(0, "", GREEN, 2, 100),
64+
(1, "", BLUE, 2, 150),
65+
(2, "", RED, 2, 200),
66+
(3, "", ORANGE, 135, 100),
67+
(4, "", YELLOW, 135, 150),
68+
(5, "", PURPLE, 135, 200),
69+
]
70+
71+
my_labels = {} # dictionary of configured my_labels
72+
73+
text_group = displayio.Group()
74+
75+
for label_config in my_labels_config:
76+
(name, text, color, x, y) = label_config # unpack a tuple into five var names
77+
templabel = label.Label(temp_font, text=text, color=color)
78+
templabel.x = x
79+
templabel.y = y
80+
my_labels[name] = templabel
81+
text_group.append(templabel)
82+
83+
temperatures_screen.append(text_group)
84+
85+
temp_title_label = label.Label(title_font, text="BBQLUE", color=clue.ORANGE)
86+
temp_title_label.x = 12
87+
temp_title_label.y = 30
88+
temperatures_screen.append(temp_title_label)
89+
90+
# PyLint can't find BLERadio for some reason so special case it here.
91+
ble = adafruit_ble.BLERadio() # pylint: disable=no-member
92+
93+
ibbq_connection = None
94+
95+
while True:
96+
# re-display homescreen here
97+
clue.display.root_group = homescreen_screen
98+
99+
print("Scanning...")
100+
for adv in ble.start_scan(ProvideServicesAdvertisement, timeout=5):
101+
clue.pixel.fill((50, 50, 0))
102+
if IBBQService in adv.services:
103+
print("found an IBBq advertisement")
104+
ibbq_connection = ble.connect(adv)
105+
print("Connected")
106+
break
107+
108+
# Stop scanning whether or not we are connected.
109+
ble.stop_scan()
110+
111+
try:
112+
if ibbq_connection and ibbq_connection.connected:
113+
clue.pixel.fill((0, 0, 50))
114+
ibbq_service = ibbq_connection[IBBQService]
115+
ibbq_service.init()
116+
while ibbq_connection.connected:
117+
118+
if clue.button_a: # hold a to swap between C and F
119+
print("unit_mode swapped")
120+
unit_mode = not unit_mode
121+
clue.red_led = True
122+
clue.play_tone(1200, 0.1)
123+
clue.red_led = False
124+
time.sleep(0.1) # debounce
125+
126+
temps = ibbq_service.temperatures
127+
batt = ibbq_service.battery_level
128+
if temps is not None:
129+
probe_count = len(temps) # check how many probes there are
130+
for i in range(probe_count):
131+
if temps[i] != 0 and temps[i] < 1000: # unplugged probes
132+
if unit_mode:
133+
clue.pixel.fill((50, 0, 0))
134+
temp = temps[i]
135+
my_labels[i].text = "{} C".format(temp)
136+
clue.pixel.fill((0, 0, 0))
137+
print("Probe", i + 1, "Temperature:", temp, "C")
138+
else: # F
139+
clue.pixel.fill((50, 0, 0))
140+
temp = temps[i] * 9 / 5 + 32
141+
my_labels[i].text = "{} F".format(temp)
142+
clue.pixel.fill((0, 0, 0))
143+
print("Probe", i + 1, "Temperature:", temp, "F")
144+
else:
145+
print(
146+
"Probe", i + 1, "is unplugged",
147+
)
148+
my_labels[i].text = " ---"
149+
clue.display.root_group = temperatures_screen
150+
151+
except _bleio.ConnectionError:
152+
continue

0 commit comments

Comments
 (0)