-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
118 lines (92 loc) · 2.85 KB
/
main.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
import esp32
from machine import Pin, PWM, deepsleep, DAC, I2S
import time
import _thread
import math
# wake up sensor configuration
WAKE_UP_PIN = 36 # Will be used to wake up
# LED configuration
LED_PIN = 23 # PINs for LED
# I2S configuration
SCK_PIN = 26 # I2S PINs for speaker
WS_PIN = 25 # I2S PINs for speaker
SD_PIN = 22 # I2S PINs for speaker
I2S_ID = 0
BUFFER_LENGTH_IN_BYTES = 5000
# Audio configuration
CRY_FILE = "248_tyranitar.wav" # File to play
WAV_SAMPLE_SIZE_IN_BITS = 32
FORMAT = I2S.STEREO
SAMPLE_RATE_IN_HZ = 24000
class Light:
def __init__(self, pin: int = LED_PIN):
self.light = PWM(Pin(pin, Pin.OUT))
self.light.duty(512)
def intensive(self, sec: int = 5):
self.light.freq(10)
time.sleep(sec)
self.light.freq(5000)
self.relax()
def relax(self, ms: int = 60000):
start = time.ticks_ms()
while time.ticks_diff(time.ticks_ms(), start) <= ms:
duty = int((math.sin(time.ticks_ms() / 500) + 1) * 512)
self.light.duty(duty)
time.sleep_ms(10)
self.light.duty(1023)
def sleep(self):
self.light.off()
class Pokemon:
def __init__(
self,
name: str = None,
uptime: int = 20,
cry_file: str = None,
):
# variables
self.name = name
self.uptime = uptime
self.cry_file = cry_file
# AUDIO
self.audio_out = I2S(
I2S_ID,
sck=Pin(SCK_PIN),
ws=Pin(WS_PIN),
sd=Pin(SD_PIN),
mode=I2S.TX,
bits=WAV_SAMPLE_SIZE_IN_BITS,
format=FORMAT,
rate=SAMPLE_RATE_IN_HZ,
ibuf=BUFFER_LENGTH_IN_BYTES,
)
# LED
self.light = Light(LED_PIN)
def awake(self):
_thread.start_new_thread(self.cry, ())
_thread.start_new_thread(self.light.intensive, ())
def cry(self):
# file validation
if not self.cry_file:
raise ValueError("No cry file provided")
if not self.cry_file.endswith(".wav"):
raise ValueError("File must be a .wav file")
wav = open(self.cry_file, "rb")
wav.seek(44) # Skip the header
wav_samples = bytearray(1000)
wav_samples_mv = memoryview(wav_samples)
num_read = wav.readinto(wav_samples_mv)
while num_read:
self.audio_out.write(wav_samples_mv[:num_read])
num_read = wav.readinto(wav_samples_mv)
def main():
tyranitar = Pokemon(name="Tyranitar", uptime=20, cry_file=CRY_FILE)
# pin to wake up from deep sleep mode
esp32.wake_on_ext0(pin=Pin(WAKE_UP_PIN, Pin.IN), level=esp32.WAKEUP_ANY_HIGH)
# action after wake up
tyranitar.awake()
time.sleep(tyranitar.uptime)
# deep sleep to save battery
deepsleep()
if __name__ == "__main__":
print("ESP32 initialized")
main()