Skip to content

Commit 60b97cc

Browse files
author
Kevin J Walters
committed
Merge branch 'rockpaperscissors' of https://github.com/kevinjwalters/Adafruit_Learning_System_Guides into rockpaperscissors
2 parents da9216b + 2feef1a commit 60b97cc

File tree

14 files changed

+34800
-0
lines changed

14 files changed

+34800
-0
lines changed
25.1 KB
Binary file not shown.
Binary file not shown.
218 KB
Loading

Astrophotography_Tracker/mount_plate.dxf

Lines changed: 5242 additions & 0 deletions
Large diffs are not rendered by default.
27.5 KB
Loading

Matrix_On_Air/BellotaText-Bold-21.bdf

Lines changed: 29191 additions & 0 deletions
Large diffs are not rendered by default.

Matrix_On_Air/matrix_on_air.py

Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
# ON AIR sign for YouTube livestreaming
2+
# Runs on Airlift Metro M4 with 64x32 RGB Matrix display & shield
3+
4+
import time
5+
import board
6+
import displayio
7+
import adafruit_display_text.label
8+
from adafruit_display_shapes.rect import Rect
9+
from adafruit_display_shapes.polygon import Polygon
10+
from adafruit_bitmap_font import bitmap_font
11+
from adafruit_matrixportal.network import Network
12+
from adafruit_matrixportal.matrix import Matrix
13+
14+
# Get wifi details and more from a secrets.py file
15+
try:
16+
from secrets import secrets
17+
except ImportError:
18+
print("WiFi secrets are kept in secrets.py, please add them there!")
19+
raise
20+
21+
# Set up where we'll be fetching data from
22+
# Adafruit YouTube channel:
23+
CHANNEL_ID = (
24+
"UCpOlOeQjj7EsVnDh3zuCgsA" # this isn't a secret but you have to look it up
25+
)
26+
27+
DATA_SOURCE = (
28+
"https://www.googleapis.com/youtube/v3/search?part=snippet&channelId="
29+
+ CHANNEL_ID
30+
+ "&type=video&eventType=live&key="
31+
+ secrets["youtube_token"]
32+
)
33+
DATA_LOCATION1 = ["items"]
34+
35+
# Number of seconds between checking, if this is too quick the query quota will run out
36+
UPDATE_DELAY = 300
37+
38+
# Times are in 24-hour format for simplification
39+
OPERATING_TIME_START = "12:00" # what hour to start checking
40+
OPERATING_TIME_END = "19:00" # what hour to stop checking
41+
42+
# --- Display setup ---
43+
matrix = Matrix()
44+
display = matrix.display
45+
network = Network(status_neopixel=board.NEOPIXEL, debug=False)
46+
47+
# --- Drawing setup ---
48+
# Create a Group
49+
group = displayio.Group(max_size=22)
50+
# Create a bitmap object
51+
bitmap = displayio.Bitmap(64, 32, 2) # width, height, bit depth
52+
# Create a color palette
53+
color = displayio.Palette(4)
54+
color[0] = 0x000000 # black
55+
color[1] = 0xFF0000 # red
56+
color[2] = 0x444444 # dim white
57+
color[3] = 0xDD8000 # gold
58+
# Create a TileGrid using the Bitmap and Palette
59+
tile_grid = displayio.TileGrid(bitmap, pixel_shader=color)
60+
# Add the TileGrid to the Group
61+
group.append(tile_grid)
62+
63+
# draw the frame for startup
64+
rect1 = Rect(0, 0, 2, 32, fill=color[2])
65+
rect2 = Rect(62, 0, 2, 32, fill=color[2])
66+
rect3 = Rect(2, 0, 9, 2, fill=color[0])
67+
rect4 = Rect(53, 0, 9, 2, fill=color[0])
68+
rect5 = Rect(2, 30, 12, 2, fill=color[0])
69+
rect6 = Rect(50, 30, 12, 2, fill=color[0])
70+
71+
group.append(rect1)
72+
group.append(rect2)
73+
group.append(rect3)
74+
group.append(rect4)
75+
group.append(rect5)
76+
group.append(rect6)
77+
78+
79+
def redraw_frame(): # to adjust spacing at bottom later
80+
rect3.fill = color[2]
81+
rect4.fill = color[2]
82+
rect5.fill = color[2]
83+
rect6.fill = color[2]
84+
85+
86+
# draw the wings w polygon shapes
87+
wing_polys = []
88+
89+
wing_polys.append(Polygon([(3, 3), (9, 3), (9, 4), (4, 4)], outline=color[1]))
90+
wing_polys.append(Polygon([(5, 6), (9, 6), (9, 7), (6, 7)], outline=color[1]))
91+
wing_polys.append(Polygon([(7, 9), (9, 9), (9, 10), (8, 10)], outline=color[1]))
92+
wing_polys.append(Polygon([(54, 3), (60, 3), (59, 4), (54, 4)], outline=color[1]))
93+
wing_polys.append(Polygon([(54, 6), (58, 6), (57, 7), (54, 7)], outline=color[1]))
94+
wing_polys.append(Polygon([(54, 9), (56, 9), (55, 10), (54, 10)], outline=color[1]))
95+
96+
for wing_poly in wing_polys:
97+
group.append(wing_poly)
98+
99+
100+
def redraw_wings(index): # to change colors
101+
for wing in wing_polys:
102+
wing.outline = color[index]
103+
104+
105+
# --- Content Setup ---
106+
deco_font = bitmap_font.load_font("/BellotaText-Bold-21.bdf")
107+
108+
# Create two lines of text. Besides changing the text, you can also
109+
# customize the color and font (using Adafruit_CircuitPython_Bitmap_Font).
110+
111+
# text positions
112+
on_x = 15
113+
on_y = 9
114+
off_x = 12
115+
off_y = 9
116+
air_x = 15
117+
air_y = 25
118+
119+
120+
text_line1 = adafruit_display_text.label.Label(
121+
deco_font, color=color[3], text="OFF", max_glyphs=6
122+
)
123+
text_line1.x = off_x
124+
text_line1.y = off_y
125+
126+
text_line2 = adafruit_display_text.label.Label(
127+
deco_font, color=color[1], text="AIR", max_glyphs=6
128+
)
129+
text_line2.x = air_x
130+
text_line2.y = air_y
131+
132+
# Put each line of text into the Group
133+
group.append(text_line1)
134+
group.append(text_line2)
135+
136+
137+
def startup_text():
138+
text_line1.text = "ADA"
139+
text_line1.x = 10
140+
text_line1.color = color[2]
141+
text_line2.text = "FRUIT"
142+
text_line2.x = 2
143+
text_line2.color = color[2]
144+
redraw_wings(0)
145+
display.show(group)
146+
147+
148+
startup_text() # display the startup text
149+
150+
151+
def update_text(state):
152+
if state: # if switch is on, text is "ON" at startup
153+
text_line1.text = "ON"
154+
text_line1.x = on_x
155+
text_line1.color = color[1]
156+
text_line2.text = "AIR"
157+
text_line2.x = air_x
158+
text_line2.color = color[1]
159+
redraw_wings(1)
160+
redraw_frame()
161+
display.show(group)
162+
else: # else, text if "OFF" at startup
163+
text_line1.text = "OFF"
164+
text_line1.x = off_x
165+
text_line1.color = color[3]
166+
text_line2.text = "AIR"
167+
text_line2.x = air_x
168+
text_line2.color = color[3]
169+
redraw_wings(3)
170+
redraw_frame()
171+
display.show(group)
172+
173+
174+
def get_status():
175+
"""
176+
Get the status whether we are on/off air within operating hours
177+
If outside of hours, return False
178+
"""
179+
# Get the time values we need
180+
now = time.localtime()
181+
start_hour, start_minute = OPERATING_TIME_START.split(":")
182+
end_hour, end_minute = OPERATING_TIME_END.split(":")
183+
184+
# Convert time into a float for easy calculations
185+
start_time = int(start_hour) + (int(start_minute) / 60)
186+
end_time = int(end_hour) + (int(end_minute) / 60)
187+
current_time = now[3] + (now[4] / 60)
188+
189+
if start_time <= current_time < end_time:
190+
try:
191+
on_air = network.fetch_data(DATA_SOURCE, json_path=(DATA_LOCATION1,))
192+
if len(on_air) > 0:
193+
return True
194+
except RuntimeError:
195+
return False
196+
197+
return False
198+
199+
200+
# Synchronize Board's clock to Internet
201+
network.get_local_time()
202+
mode_state = get_status()
203+
update_text(mode_state)
204+
last_check = None
205+
206+
207+
while True:
208+
if last_check is None or time.monotonic() > last_check + UPDATE_DELAY:
209+
try:
210+
status = get_status()
211+
if status:
212+
if mode_state == 0: # state has changed, toggle it
213+
update_text(1)
214+
mode_state = 1
215+
else:
216+
if mode_state == 1:
217+
update_text(0)
218+
mode_state = 0
219+
print("On Air:", status)
220+
last_check = time.monotonic()
221+
except RuntimeError as e:
222+
print("Some error occured, retrying! -", e)

Ocean_Resin_Lightbox/README.txt

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Ocean_Resin_Lightbox
2+
3+
Code to accompany this tutorial:
4+
https://learn.adafruit.com/ocean-epoxy-resin-art-with-rgb-led-matrix-animations
5+
6+
Ocean Epoxy Resin LightBox with RGB LED Matrix Animations
7+
Adafruit invests time and resources providing this open source code.
8+
Please support Adafruit and open source hardware by purchasing
9+
products from Adafruit!
10+
Written by Jeff Epler, Erin St Blaine & Limor Fried for Adafruit Industries
11+
Copyright (c) 2020 Adafruit Industries
12+
Licensed under the MIT license.
13+
All text above must be included in any redistribution.

Ocean_Resin_Lightbox/code.py

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
"""
2+
RGB Matrix Ocean Scroller
3+
Adafruit invests time and resources providing this open source code.
4+
Please support Adafruit and open source hardware by purchasing
5+
products from Adafruit!
6+
Written by Jeff Epler & Limor Fried for Adafruit Industries
7+
Copyright (c) 2019-2020 Adafruit Industries
8+
Licensed under the MIT license.
9+
All text above must be included in any redistribution.
10+
"""
11+
12+
import math
13+
import time
14+
import random
15+
16+
import adafruit_imageload.bmp
17+
import board
18+
import displayio
19+
import framebufferio
20+
import rgbmatrix
21+
import ulab
22+
23+
displayio.release_displays()
24+
25+
class Reshader:
26+
'''reshader fades the image to mimic brightness control'''
27+
def __init__(self, palette):
28+
self.palette = palette
29+
ulab_palette = ulab.zeros((len(palette), 3))
30+
for i in range(len(palette)):
31+
rgb = int(palette[i])
32+
ulab_palette[i, 2] = rgb & 0xff
33+
ulab_palette[i, 1] = (rgb >> 8) & 0xff
34+
ulab_palette[i, 0] = rgb >> 16
35+
self.ulab_palette = ulab_palette
36+
37+
def reshade(self, brightness):
38+
'''reshader'''
39+
palette = self.palette
40+
shaded = ulab.array(self.ulab_palette * brightness, dtype=ulab.uint8)
41+
for i in range(len(palette)):
42+
palette[i] = tuple(shaded[i])
43+
44+
def do_crawl_down(image_file, *,
45+
speed=12, weave=4, pulse=.5,
46+
weave_speed=1/6, pulse_speed=1/7):
47+
# pylint:disable=too-many-locals
48+
'''function to scroll the image'''
49+
the_bitmap, the_palette = adafruit_imageload.load(
50+
image_file,
51+
bitmap=displayio.Bitmap,
52+
palette=displayio.Palette)
53+
54+
shader = Reshader(the_palette)
55+
56+
group = displayio.Group()
57+
tile_grid = displayio.TileGrid(bitmap=the_bitmap, pixel_shader=the_palette)
58+
group.append(tile_grid)
59+
display.show(group)
60+
61+
start_time = time.monotonic_ns()
62+
start_y = display.height # High enough to be "off the top"
63+
end_y = -the_bitmap.height # Low enough to be "off the bottom"
64+
65+
# Mix up how the bobs and brightness change on each run
66+
r1 = random.random() * math.pi
67+
r2 = random.random() * math.pi
68+
69+
y = start_y
70+
while y > end_y:
71+
now = time.monotonic_ns()
72+
y = start_y - speed * ((now - start_time) / 1e9)
73+
group.y = round(y)
74+
75+
# wave from side to side
76+
group.x = round(weave * math.cos(y * weave_speed + r1))
77+
78+
# Change the brightness
79+
if pulse > 0:
80+
shader.reshade((1 - pulse) + pulse * math.sin(y * pulse_speed + r2))
81+
82+
display.refresh(minimum_frames_per_second=0, target_frames_per_second=60)
83+
84+
def do_pulse(image_file, *, duration=4, pulse_speed=1/8, pulse=.5):
85+
'''pulse animation'''
86+
the_bitmap, the_palette = adafruit_imageload.load(
87+
image_file,
88+
bitmap=displayio.Bitmap,
89+
palette=displayio.Palette)
90+
91+
shader = Reshader(the_palette)
92+
93+
group = displayio.Group()
94+
tile_grid = displayio.TileGrid(bitmap=the_bitmap, pixel_shader=the_palette)
95+
group.append(tile_grid)
96+
group.x = (display.width - the_bitmap.width) // 2
97+
group.y = (display.height - the_bitmap.height) // 2
98+
display.show(group)
99+
100+
start_time = time.monotonic_ns()
101+
end_time = start_time + int(duration * 1e9)
102+
103+
now_ns = time.monotonic_ns()
104+
while now_ns < end_time:
105+
now_ns = time.monotonic_ns()
106+
current_time = (now_ns - start_time) / 1e9
107+
108+
shader.reshade((1 - pulse) - pulse
109+
* math.cos(2*math.pi*current_time*pulse_speed)**2)
110+
111+
display.refresh(minimum_frames_per_second=0, target_frames_per_second=60)
112+
113+
matrix = rgbmatrix.RGBMatrix(
114+
width=64, height=32, bit_depth=5,
115+
rgb_pins=[board.D6, board.D5, board.D9, board.D11, board.D10, board.D12],
116+
addr_pins=[board.A5, board.A4, board.A3, board.A2],
117+
clock_pin=board.D13, latch_pin=board.D0, output_enable_pin=board.D1)
118+
display = framebufferio.FramebufferDisplay(matrix, auto_refresh=False)
119+
120+
# Image playlist - set to run randomly. Set pulse from 0 to .5
121+
while True:
122+
show_next = random.randint(1, 5) #change to reflect how many images you add
123+
if show_next == 1:
124+
do_crawl_down("/ray.bmp")
125+
elif show_next == 2:
126+
do_crawl_down("/waves1.bmp", speed=7, weave=0, pulse=.35)
127+
elif show_next == 3:
128+
do_crawl_down("/waves2.bmp", speed=9, weave=0, pulse=.35)
129+
elif show_next == 4:
130+
do_pulse("/heart.bmp", duration=4, pulse=.45)
131+
elif show_next == 5:
132+
do_crawl_down("/dark.bmp")

Ocean_Resin_Lightbox/dark.bmp

2.25 KB
Binary file not shown.

0 commit comments

Comments
 (0)