-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcode.py
executable file
·195 lines (159 loc) · 5.58 KB
/
code.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
"""
MP3 player using the I2S bus.
"""
import os
import random
import time
import math
import board
import audiomp3
import audiobusio
import adafruit_rgbled
from digitalio import DigitalInOut, Direction, Pull
FOLDER_PATH = "/mp3"
WAIT_TIME = 5*60 # Seconds (+- 30%) to wait before playing the next mp3
WAIT_VARIANCE = 30/100 # 30% variance in wait time
audio = audiobusio.I2SOut(board.GP0, board.GP1, board.GP2)
# Create a RGB LED object
rgbled1 = adafruit_rgbled.RGBLED(board.GP10, board.GP11, board.GP12, invert_pwm=True)
rgbled2 = adafruit_rgbled.RGBLED(board.GP18, board.GP19, board.GP20, invert_pwm=True)
button = DigitalInOut(board.GP16)
button.direction = Direction.INPUT
button.pull = Pull.UP
COLOUR_RED = (255, 0, 0)
COLOUR_GREEN = (0, 255, 0)
COLOUR_BLUE = (0, 0, 255)
COLOUR_YELLOW = (255, 255, 0)
COLOUR_MAGENTA = (255, 0, 255)
COLOUR_CYAN = (0, 255, 255)
COLOUR_WHITE = (255, 255, 255)
COLOUR_ORANGE = (255, 165, 0)
COLOUR_PURPLE = (128, 0, 128)
COLOUR_PINK = (255, 192, 203)
COLOUR_OFF = (0, 0, 0)
EYE_COLOURS = [
COLOUR_RED,
COLOUR_GREEN,
COLOUR_BLUE,
COLOUR_YELLOW,
COLOUR_MAGENTA,
COLOUR_CYAN,
COLOUR_WHITE,
COLOUR_ORANGE,
COLOUR_PURPLE,
COLOUR_PINK
]
prev_eye_colour = None
button_last_value = button.value
def cycle_eyes():
"""Cycle both eyes through a circular rainbow pattern"""
for i in range(256):
r = int(255 * abs(math.sin(i / 255.0 * math.pi)))
g = int(255 * abs(math.sin((i / 255.0 + 1.0 / 3.0) * math.pi)))
b = int(255 * abs(math.sin((i / 255.0 + 2.0 / 3.0) * math.pi)))
rgbled1.color = (r, g, b)
rgbled2.color = (255 - r, 255 - g, 255 - b)
time.sleep(0.001)
def flash_eyes(colour1, colour2, speed, eyes_together=True):
"""Animate LED eyes with the given colours and speed"""
sleep_time = (11 - speed) / 20.0 * 0.5
if eyes_together:
rgbled1.color = colour1
rgbled2.color = colour1
time.sleep(sleep_time)
rgbled1.color = colour2
rgbled2.color = colour2
time.sleep(sleep_time)
else:
rgbled1.color = colour1
rgbled2.color = colour2
time.sleep(sleep_time)
rgbled1.color = colour2
rgbled2.color = colour1
time.sleep(sleep_time)
def play_mp3(mp3_file):
global prev_eye_colour
global button_last_value
# Load and play the selected mp3 file
mp3 = audiomp3.MP3Decoder(open(FOLDER_PATH + os.sep + mp3_file, "rb"))
audio.play(mp3)
# Randomly select a new eye colour that is different from the previous one
eye_colour = random.choice(list(set(EYE_COLOURS) - {prev_eye_colour}))
# Randomly select an eye function with the specified weighting
# 1 = flash_eyes fast with random colour
# 2 = flash_eyes alternating at random speed with random colour
# 3 = cycle_eyes
r = random.random()
if r < 0.6:
eye_animation_choice = 1
elif r < 0.8:
eye_animation_choice = 2
eye_colour2 = random.choice(list(set(EYE_COLOURS) - {eye_colour}))
flash_speed = random.randint(1, 10)
else:
eye_animation_choice = 3
# Flash the LED while the MP3 is playing
while audio.playing:
# Call the selected function with the selected colours and speed
if eye_animation_choice == 1:
# print("Animation 1")
flash_eyes(eye_colour, COLOUR_OFF, 10, True)
elif eye_animation_choice == 2:
# print("Animation 2")
flash_eyes(eye_colour, eye_colour2, flash_speed, False)
elif eye_animation_choice == 3:
# print("Animation 3")
cycle_eyes()
# Set the previous eye colour to the current one
prev_eye_colour = eye_colour
# Check if the button has been pressed
if button.value != button_last_value:
# Exit the loop if the button has been pressed
audio.stop()
break
rgbled1.color = COLOUR_OFF
rgbled2.color = COLOUR_OFF
def main():
"""Run my rat"""
global button_last_value
print("Running my Tory rat")
try:
play_mp3("startup.mp3")
except OSError:
print("The file 'startup.mp3' does not exist.")
current_mp3s = []
for filename in os.listdir(FOLDER_PATH):
if filename.endswith(".mp3") and not filename.startswith("._"):
current_mp3s.append(filename)
if not current_mp3s:
print("No mp3 files found in /mp3 directory")
return
else:
print(current_mp3s)
# Only play startup.mp3 once, on boot
if "startup.mp3" in current_mp3s:
current_mp3s.remove("startup.mp3")
# Make a copy of the original list of mp3s to restore on reset
reset_mp3s = current_mp3s.copy()
mp3_file = None
try:
while True:
# Wait for a time before automatically playing the next mp3
delay = random.randint(int(WAIT_TIME*(1-WAIT_VARIANCE)), int(WAIT_TIME*(1+WAIT_VARIANCE)))
print(f"Delay set to {delay} seconds")
for i in range(delay * 10):
if button.value != button_last_value: # Make the on/off button into a toggle switch
break
time.sleep(0.1)
button_last_value = button.value
mp3_file = random.choice(current_mp3s)
current_mp3s.remove(mp3_file)
if not current_mp3s:
current_mp3s = reset_mp3s.copy()
play_mp3(mp3_file)
except KeyboardInterrupt:
print("Program stopped by user")
except OSError:
print(f"The file '{mp3_file}' does not exist.")
if __name__ == "__main__":
main()