196 lines
5.6 KiB
Python
196 lines
5.6 KiB
Python
import machine
|
|
import time
|
|
import struct
|
|
import gc
|
|
import network
|
|
import st7789py as st7789
|
|
from config import CURRENT_CONFIG
|
|
from audio import AudioPlayer, Microphone
|
|
from display import Display
|
|
from websocket_client import WebSocketClient
|
|
import uselect
|
|
|
|
WIFI_SSID = "Tangledup-AI"
|
|
WIFI_PASS = "djt12345678"
|
|
SERVER_IP = "6.6.6.88"
|
|
SERVER_PORT = 8000
|
|
SERVER_URL = f"ws://{SERVER_IP}:{SERVER_PORT}/ws/audio"
|
|
|
|
|
|
def connect_wifi(max_retries=3):
|
|
wlan = network.WLAN(network.STA_IF)
|
|
|
|
try:
|
|
wlan.active(False)
|
|
time.sleep(1)
|
|
wlan.active(True)
|
|
time.sleep(1)
|
|
except Exception as e:
|
|
print(f"WiFi init error: {e}")
|
|
return False
|
|
|
|
for attempt in range(max_retries):
|
|
try:
|
|
if wlan.isconnected():
|
|
print('WiFi connected')
|
|
return True
|
|
|
|
print(f'Connecting to WiFi {WIFI_SSID}...')
|
|
wlan.connect(WIFI_SSID, WIFI_PASS)
|
|
|
|
start_time = time.ticks_ms()
|
|
while not wlan.isconnected():
|
|
if time.ticks_diff(time.ticks_ms(), start_time) > 20000:
|
|
print("WiFi timeout!")
|
|
break
|
|
time.sleep(0.5)
|
|
|
|
if wlan.isconnected():
|
|
print('WiFi connected!')
|
|
return True
|
|
|
|
if attempt < max_retries - 1:
|
|
wlan.disconnect()
|
|
time.sleep(2)
|
|
|
|
except Exception as e:
|
|
print(f"WiFi error: {e}")
|
|
if attempt < max_retries - 1:
|
|
time.sleep(3)
|
|
|
|
print("WiFi connection failed!")
|
|
return False
|
|
|
|
|
|
def print_asr(text, display=None):
|
|
print(f"ASR: {text}")
|
|
if display and display.tft:
|
|
display.fill_rect(0, 40, 240, 160, st7789.BLACK)
|
|
display.text(text, 0, 40, st7789.WHITE)
|
|
|
|
|
|
def main():
|
|
print("\n=== ESP32 Audio ASR ===\n")
|
|
|
|
boot_btn = machine.Pin(0, machine.Pin.IN, machine.Pin.PULL_UP)
|
|
|
|
bl_pin = CURRENT_CONFIG.pins.get('bl')
|
|
if bl_pin:
|
|
try:
|
|
bl = machine.Pin(bl_pin, machine.Pin.OUT)
|
|
bl.on()
|
|
except:
|
|
pass
|
|
|
|
speaker = AudioPlayer()
|
|
mic = Microphone()
|
|
display = Display()
|
|
|
|
if display.tft:
|
|
display.init_ui()
|
|
|
|
is_recording = False
|
|
ws = None
|
|
|
|
def connect_ws():
|
|
nonlocal ws
|
|
try:
|
|
if ws:
|
|
ws.close()
|
|
except:
|
|
pass
|
|
ws = None
|
|
|
|
try:
|
|
print(f"Connecting to {SERVER_URL}")
|
|
ws = WebSocketClient(SERVER_URL)
|
|
print("WebSocket connected!")
|
|
if display:
|
|
display.set_ws(ws)
|
|
return True
|
|
except Exception as e:
|
|
print(f"WS connection failed: {e}")
|
|
return False
|
|
|
|
if connect_wifi():
|
|
connect_ws()
|
|
else:
|
|
print("Running in offline mode")
|
|
|
|
read_buf = bytearray(4096)
|
|
|
|
while True:
|
|
try:
|
|
btn_val = boot_btn.value()
|
|
|
|
if btn_val == 0:
|
|
if not is_recording:
|
|
print(">>> Recording...")
|
|
is_recording = True
|
|
if display.tft:
|
|
display.fill(st7789.WHITE)
|
|
|
|
if ws is None or not ws.is_connected():
|
|
connect_ws()
|
|
|
|
if ws and ws.is_connected():
|
|
try:
|
|
ws.send("START_RECORDING")
|
|
except:
|
|
ws = None
|
|
|
|
if mic.i2s:
|
|
num_read = mic.readinto(read_buf)
|
|
if num_read > 0:
|
|
if ws and ws.is_connected():
|
|
try:
|
|
ws.send(read_buf[:num_read], opcode=2)
|
|
|
|
poller = uselect.poll()
|
|
poller.register(ws.sock, uselect.POLLIN)
|
|
events = poller.poll(0)
|
|
if events:
|
|
msg = ws.recv()
|
|
if isinstance(msg, str) and msg.startswith("ASR:"):
|
|
print_asr(msg[4:], display)
|
|
|
|
except:
|
|
ws = None
|
|
|
|
continue
|
|
|
|
elif is_recording:
|
|
print(">>> Stop")
|
|
is_recording = False
|
|
|
|
if display.tft:
|
|
display.init_ui()
|
|
|
|
if ws:
|
|
try:
|
|
ws.send("STOP_RECORDING")
|
|
|
|
t_wait = time.ticks_add(time.ticks_ms(), 500)
|
|
while time.ticks_diff(t_wait, time.ticks_ms()) > 0:
|
|
poller = uselect.poll()
|
|
poller.register(ws.sock, uselect.POLLIN)
|
|
events = poller.poll(100)
|
|
if events:
|
|
msg = ws.recv()
|
|
if isinstance(msg, str) and msg.startswith("ASR:"):
|
|
print_asr(msg[4:], display)
|
|
except:
|
|
ws = None
|
|
|
|
gc.collect()
|
|
|
|
time.sleep(0.01)
|
|
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
time.sleep(1)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|