From c63712e3aa2a1e9da490a13b2090b1fd2083ed46 Mon Sep 17 00:00:00 2001 From: Adolfo Reyna Date: Wed, 17 Jun 2026 22:35:47 -0400 Subject: [PATCH] Implement dynamic hardware auto-detection in board_config.py to support both Hosyond and Waveshare RLCD boards out-of-the-box --- boot.py | 90 +++++++++++---------- lib/audio_util.py | 123 ++++++++++++++++------------ lib/board_config.py | 191 ++++++++++++++++++++++++++++++++++++++++++++ main.py | 92 +++++++++------------ upload_files.py | 2 + 5 files changed, 350 insertions(+), 148 deletions(-) create mode 100644 lib/board_config.py diff --git a/boot.py b/boot.py index b325287..fe1e04b 100644 --- a/boot.py +++ b/boot.py @@ -1,41 +1,34 @@ # This file is executed on every boot (including wake-boot from deepsleep) import time import sys +import board_config +import wifi_config try: import network has_network = True except ImportError: has_network = False -if sys.platform == 'rp2': - import st7796 as display_module -else: - import ili9341 as display_module -from machine import Pin, SPI -import wifi_config def connect_wifi(): if sys.platform == 'rp2': # Skip display and connection setup on RP2 (no network/Wi-Fi hardware) - # Keep the sleep window to make REPL interruption easy time.sleep(1.5) return - # Initialize display to show connection progress - display = None - try: - # ESP32-S3 configuration for Hosyond Board - spi = SPI(1, baudrate=40000000, polarity=0, phase=0, sck=Pin(12), mosi=Pin(11), miso=Pin(13)) - display = display_module.ILI9341(spi, cs=Pin(10), dc=Pin(46), bl=Pin(45), rst=None) - display.clear(0) - - display.text("Hosyond ESP32-S3", 10, 10, 1) - display.line(10, 20, 310, 20, 1) - display.text("Connecting to Wi-Fi...", 10, 35, 1) - display.text(f"SSID: {wifi_config.WIFI_SSID}", 10, 50, 1) - display.show() - except Exception as e: - print("Display init failed in boot.py:", e) + # Use the pre-initialized display from board_config + display = board_config.display_instance + if display: + try: + display.clear(0) + board_name = "ESP32-S3 " + str(board_config.BOARD_TYPE) + display.text(board_name, 10, 10, 1) + display.line(10, 20, display.width - 10, 20, 1) + display.text("Connecting to Wi-Fi...", 10, 35, 1) + display.text(f"SSID: {wifi_config.WIFI_SSID}", 10, 50, 1) + display.show() + except Exception as e: + print("Display setup failed in boot.py:", e) # Initialize Wi-Fi Station if not has_network: @@ -62,34 +55,45 @@ def connect_wifi(): timeout -= 1 print("Connecting...") if display: - display.text(".", dot_x, 70, 1) - dot_x += 10 - display.show() + try: + display.text(".", dot_x, 70, 1) + dot_x += 10 + display.show() + except: + pass if wlan.isconnected(): ip = wlan.ifconfig()[0] print(f"Wi-Fi Connected! IP Address: {ip}") if display: - display.clear(0) - display.text("Hosyond ESP32-S3", 10, 10, 1) - display.line(10, 20, 310, 20, 1) - display.text("Wi-Fi Status: Connected!", 10, 35, 1) - display.text(f"SSID: {wifi_config.WIFI_SSID}", 10, 50, 1) - display.text(f"IP: {ip}", 10, 65, 1) - display.text("Starting MCP Server...", 10, 90, 1) - display.show() - time.sleep(1.5) + try: + display.clear(0) + board_name = "ESP32-S3 " + str(board_config.BOARD_TYPE) + display.text(board_name, 10, 10, 1) + display.line(10, 20, display.width - 10, 20, 1) + display.text("Wi-Fi Status: Connected!", 10, 35, 1) + display.text(f"SSID: {wifi_config.WIFI_SSID}", 10, 50, 1) + display.text(f"IP: {ip}", 10, 65, 1) + display.text("Starting MCP Server...", 10, 90, 1) + display.show() + time.sleep(1.5) + except: + pass else: print("Wi-Fi Connection Failed.") if display: - display.clear(0) - display.text("Hosyond ESP32-S3", 10, 10, 1) - display.line(10, 20, 310, 20, 1) - display.text("Wi-Fi Status: Failed!", 10, 35, 1) - display.text("Check credentials in:", 10, 55, 1) - display.text("wifi_config.py", 20, 70, 1) - display.text("Starting offline...", 10, 95, 1) - display.show() - time.sleep(2) + try: + display.clear(0) + board_name = "ESP32-S3 " + str(board_config.BOARD_TYPE) + display.text(board_name, 10, 10, 1) + display.line(10, 20, display.width - 10, 20, 1) + display.text("Wi-Fi Status: Failed!", 10, 35, 1) + display.text("Check credentials in:", 10, 55, 1) + display.text("wifi_config.py", 20, 70, 1) + display.text("Starting offline...", 10, 95, 1) + display.show() + time.sleep(2) + except: + pass connect_wifi() diff --git a/lib/audio_util.py b/lib/audio_util.py index 9615e47..906958f 100644 --- a/lib/audio_util.py +++ b/lib/audio_util.py @@ -1,6 +1,7 @@ import time import machine from machine import Pin, I2C, I2S +import board_config class ES7210: """MicroPython driver for the ES7210 4-Channel Audio ADC (Microphone Array). @@ -79,32 +80,41 @@ def record_audio(duration_seconds=5, filename='recording.pcm'): duration_seconds (int): How long to record in seconds. filename (str): Name of output raw PCM file on the device. """ - # 1. Start I2C Control Bus (SDA=16, SCL=15) - i2c = I2C(0, sda=Pin(16), scl=Pin(15)) + # 1. Use I2C Control Bus from board_config + i2c = board_config.i2c_bus - # 1a. Setup Master Clock (MCLK) on GPIO 4 using PWM (needed for ES8311 ADC) - mclk_pin = Pin(4, Pin.OUT) - mclk_pwm = machine.PWM(mclk_pin) - mclk_pwm.freq(6144000) - mclk_pwm.duty_u16(32768) + # 1a. Setup Master Clock (MCLK) using PWM if configured + mclk_pwm = None + if board_config.audio_mclk_pin is not None: + mclk_pin = Pin(board_config.audio_mclk_pin, Pin.OUT) + mclk_pwm = machine.PWM(mclk_pin) + mclk_pwm.freq(board_config.audio_mclk_freq) + mclk_pwm.duty_u16(32768) # 2. Configure I2S Receiver - # Pins: sck=BCLK (GPIO 5), ws=WS/LRCK (GPIO 7), sd=DIN (GPIO 6) i2s = I2S(1, - sck=Pin(5), - ws=Pin(7), - sd=Pin(6), + sck=Pin(board_config.audio_i2s_sck), + ws=Pin(board_config.audio_i2s_ws), + sd=Pin(board_config.audio_i2s_rx_sd), mode=I2S.RX, ibuf=16000, rate=16000, bits=16, format=I2S.STEREO) - # 3. Wake up and configure the ES8311 codec chip - mic_adc = ES8311(i2c) - if not mic_adc.init(sample_rate=16000): - i2s.deinit() - return False + # 3. Wake up and configure the microphone chip (ES7210 vs ES8311) + if board_config.audio_mic_codec == "ES7210": + mic_adc = ES7210(i2c) + if not mic_adc.init(sample_rate=16000, bit_width=16): + i2s.deinit() + if mclk_pwm: mclk_pwm.deinit() + return False + else: + mic_adc = ES8311(i2c) + if not mic_adc.init(sample_rate=16000): + i2s.deinit() + if mclk_pwm: mclk_pwm.deinit() + return False print(f"Recording {duration_seconds} seconds of audio...") @@ -130,8 +140,15 @@ def record_audio(duration_seconds=5, filename='recording.pcm'): return False finally: # Always release the I2S peripheral resources - i2s.deinit() - mclk_pwm.deinit() + try: + i2s.deinit() + except: + pass + if mclk_pwm: + try: + mclk_pwm.deinit() + except: + pass print("I2S receiver and MCLK deinitialized.") @@ -226,37 +243,40 @@ def play_tone(frequency=440, duration_ms=1000, volume=50): print(f"Playing tone: {frequency}Hz for {duration_ms}ms (vol={volume})...") - # 1. Setup Master Clock (MCLK) on GPIO 4 using PWM - mclk_pin = Pin(4, Pin.OUT) - mclk_pwm = machine.PWM(mclk_pin) - mclk_pwm.freq(6144000) - mclk_pwm.duty_u16(32768) + # 1. Setup Master Clock (MCLK) using PWM if configured + mclk_pwm = None + if board_config.audio_mclk_pin is not None: + mclk_pin = Pin(board_config.audio_mclk_pin, Pin.OUT) + mclk_pwm = machine.PWM(mclk_pin) + mclk_pwm.freq(board_config.audio_mclk_freq) + mclk_pwm.duty_u16(32768) - # 2. Start I2C Control Bus (SDA=16, SCL=15) - i2c = I2C(0, sda=Pin(16), scl=Pin(15)) + # 2. Use dynamic I2C Control Bus from board_config + i2c = board_config.i2c_bus # 3. Initialize the ES8311 DAC dac = ES8311(i2c) if not dac.init(sample_rate=16000): - mclk_pwm.deinit() + if mclk_pwm: mclk_pwm.deinit() return False dac.set_volume(volume) # 4. Configure I2S TX - # Pins: sck=BCLK (GPIO 5), ws=WS/LRCK (GPIO 7), sd=DOUT (GPIO 8) i2s = I2S(1, - sck=Pin(5), - ws=Pin(7), - sd=Pin(8), + sck=Pin(board_config.audio_i2s_sck), + ws=Pin(board_config.audio_i2s_ws), + sd=Pin(board_config.audio_i2s_tx_sd), mode=I2S.TX, ibuf=8000, rate=16000, bits=16, format=I2S.STEREO) - # 5. Enable Speaker Amplifier (GPIO 1, Active Low) - amp_pin = Pin(1, Pin.OUT, value=0) + # 5. Enable Speaker Amplifier + on_val = 0 if board_config.audio_amp_active_level == 0 else 1 + off_val = 1 if board_config.audio_amp_active_level == 0 else 0 + amp_pin = Pin(board_config.audio_amp_pin, Pin.OUT, value=on_val) # 6. Generate sine wave cycle # Approximate frequency to make integer number of samples per cycle @@ -284,9 +304,9 @@ def play_tone(frequency=440, duration_ms=1000, volume=50): # 7. Clean up time.sleep_ms(100) # Let the remaining buffer play out - amp_pin.value(1) # Disable amp + amp_pin.value(off_val) # Disable amp i2s.deinit() - mclk_pwm.deinit() + if mclk_pwm: mclk_pwm.deinit() print("Tone playback complete.") return True @@ -344,39 +364,42 @@ def play_wav(filename, volume=50): print(f"WAV Info: {sample_rate}Hz, {bits} bits, {'Mono' if channels == 1 else 'Stereo'}") - # 2. Setup Master Clock (MCLK) on GPIO 4 using PWM - mclk_pin = Pin(4, Pin.OUT) - mclk_pwm = machine.PWM(mclk_pin) - mclk_pwm.freq(6144000) - mclk_pwm.duty_u16(32768) + # 2. Setup Master Clock (MCLK) using PWM if configured + mclk_pwm = None + if board_config.audio_mclk_pin is not None: + mclk_pin = Pin(board_config.audio_mclk_pin, Pin.OUT) + mclk_pwm = machine.PWM(mclk_pin) + mclk_pwm.freq(board_config.audio_mclk_freq) + mclk_pwm.duty_u16(32768) - # 3. Start I2C Control Bus (SDA=16, SCL=15) - i2c = I2C(0, sda=Pin(16), scl=Pin(15)) + # 3. Use dynamic I2C Control Bus from board_config + i2c = board_config.i2c_bus # 4. Initialize the ES8311 DAC dac = ES8311(i2c) if not dac.init(sample_rate=16000): - mclk_pwm.deinit() + if mclk_pwm: mclk_pwm.deinit() f.close() return False dac.set_volume(volume) # 5. Configure I2S TX - # Pins: sck=BCLK (GPIO 5), ws=WS/LRCK (GPIO 7), sd=DOUT (GPIO 8) i2s_format = I2S.MONO if channels == 1 else I2S.STEREO i2s = I2S(1, - sck=Pin(5), - ws=Pin(7), - sd=Pin(8), + sck=Pin(board_config.audio_i2s_sck), + ws=Pin(board_config.audio_i2s_ws), + sd=Pin(board_config.audio_i2s_tx_sd), mode=I2S.TX, ibuf=4096, rate=sample_rate, bits=bits, format=i2s_format) - # 6. Enable Speaker Amplifier (GPIO 1, Active Low) - amp_pin = Pin(1, Pin.OUT, value=0) + # 6. Enable Speaker Amplifier + on_val = 0 if board_config.audio_amp_active_level == 0 else 1 + off_val = 1 if board_config.audio_amp_active_level == 0 else 0 + amp_pin = Pin(board_config.audio_amp_pin, Pin.OUT, value=on_val) # 7. Read and stream chunks to I2S buf = bytearray(2048) @@ -388,9 +411,9 @@ def play_wav(filename, volume=50): # 8. Clean up time.sleep_ms(100) # Let the remaining buffer play out - amp_pin.value(1) # Disable amp + amp_pin.value(off_val) # Disable amp i2s.deinit() - mclk_pwm.deinit() + if mclk_pwm: mclk_pwm.deinit() f.close() print("WAV playback complete.") return True diff --git a/lib/board_config.py b/lib/board_config.py new file mode 100644 index 0000000..9cb9371 --- /dev/null +++ b/lib/board_config.py @@ -0,0 +1,191 @@ +import sys +import machine +from machine import Pin, I2C, SPI + +# Global configuration variables +BOARD_TYPE = None # 'HOSYOND', 'WAVESHARE_RLCD', or 'RP2' +DISPLAY_TYPE = None # 'ILI9341', 'RLCD', or 'ST7796' +DISPLAY_WIDTH = 320 +DISPLAY_HEIGHT = 240 + +# Bus and display references +spi_bus = None +i2c_bus = None +display_instance = None +touch = None + +# Component support flags +has_sensor = False +has_rtc = False + +# WS2812 NeoPixel pin +led_pin = None + +# Audio pins, clocks, and codecs config +audio_mclk_pin = None +audio_mclk_freq = 6144000 +audio_i2c_sda = None +audio_i2c_scl = None +audio_i2s_sck = None +audio_i2s_ws = None +audio_i2s_tx_sd = None +audio_i2s_rx_sd = None +audio_amp_pin = None +audio_amp_active_level = 0 # 0 = Active Low, 1 = Active High +audio_mic_codec = "ES8311" # "ES7210" or "ES8311" + +def detect_board(): + global BOARD_TYPE, DISPLAY_TYPE, DISPLAY_WIDTH, DISPLAY_HEIGHT + global spi_bus, i2c_bus, display_instance, touch + global has_sensor, has_rtc, led_pin + global audio_mclk_pin, audio_mclk_freq, audio_i2c_sda, audio_i2c_scl + global audio_i2s_sck, audio_i2s_ws, audio_i2s_tx_sd, audio_i2s_rx_sd + global audio_amp_pin, audio_amp_active_level, audio_mic_codec + + # 1. Check if running on RP2 platform (e.g. Raspberry Pi Pico / RP2350) + if sys.platform == 'rp2': + print("Auto-detected: Raspberry Pi RP2 platform") + BOARD_TYPE = 'RP2' + DISPLAY_TYPE = 'ST7796' + DISPLAY_WIDTH = 480 + DISPLAY_HEIGHT = 320 + led_pin = 25 + + # Setup SPI + spi_bus = SPI(1, baudrate=32000000, polarity=0, phase=0, sck=Pin(10), mosi=Pin(11)) + + # Setup Display: ST7796 + import st7796 + display_instance = st7796.ST7796(spi_bus, cs=Pin(7), dc=Pin(4), rst=Pin(9), bl=Pin(6)) + + # Setup Touch: FT6336U on I2C(1) + try: + touch_i2c = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000) + from ft6336u import FT6336U + touch = FT6336U(touch_i2c, rst_pin=28, int_pin=25) + except Exception as e: + print("Failed to initialize touch on RP2:", e) + return + + # 2. We are on ESP32 platform. + # Try scanning I2C(0) on Hosyond pins (SDA=16, SCL=15) + try: + test_i2c = I2C(0, sda=Pin(16), scl=Pin(15)) + devices = test_i2c.scan() + # FT6336U touchscreen is at 0x38 on Hosyond + if 0x38 in devices: + print("Auto-detected: Hosyond ESP32-S3 Touchscreen board") + BOARD_TYPE = 'HOSYOND' + DISPLAY_TYPE = 'ILI9341' + DISPLAY_WIDTH = 320 + DISPLAY_HEIGHT = 240 + has_sensor = False + has_rtc = False + led_pin = 48 + + i2c_bus = test_i2c + + # Setup SPI + spi_bus = SPI(1, baudrate=40000000, polarity=0, phase=0, sck=Pin(12), mosi=Pin(11), miso=Pin(13)) + + # Setup Display: ILI9341 + import ili9341 + display_instance = ili9341.ILI9341(spi_bus, cs=Pin(10), dc=Pin(46), bl=Pin(45), rst=None) + + # Setup Touch: FT6336U + try: + from ft6336u import FT6336U + touch = FT6336U(i2c_bus, rst_pin=18, int_pin=17, width=320, height=240, swap_xy=True, invert_x=False, invert_y=True) + except Exception as te: + print("Failed to initialize touchscreen:", te) + + # Audio pins & clocks configuration + audio_mclk_pin = 4 + audio_mclk_freq = 6144000 + audio_i2c_sda = 16 + audio_i2c_scl = 15 + audio_i2s_sck = 5 + audio_i2s_ws = 7 + audio_i2s_tx_sd = 8 + audio_i2s_rx_sd = 6 + audio_amp_pin = 1 + audio_amp_active_level = 0 # Active Low (0 = enabled) + audio_mic_codec = "ES8311" + return + + except Exception as e: + print("I2C scan on Hosyond pins failed:", e) + + # 3. Try scanning I2C(0) on Waveshare RLCD pins (SDA=13, SCL=14) + try: + test_i2c = I2C(0, sda=Pin(13), scl=Pin(14)) + devices = test_i2c.scan() + # SHTC3 is at 0x70, PCF85063 RTC is at 0x51 + if 0x70 in devices or 0x51 in devices: + print("Auto-detected: Waveshare ESP32-S3-RLCD-4.2 board") + BOARD_TYPE = 'WAVESHARE_RLCD' + DISPLAY_TYPE = 'RLCD' + DISPLAY_WIDTH = 400 + DISPLAY_HEIGHT = 300 + has_sensor = True + has_rtc = True + led_pin = 38 + + i2c_bus = test_i2c + + # Setup SPI + spi_bus = SPI(1, baudrate=20000000, polarity=0, phase=0, sck=Pin(11), mosi=Pin(12)) + + # Setup Display: RLCD + import rlcd + display_instance = rlcd.RLCD(spi_bus, cs=Pin(40), dc=Pin(5), rst=Pin(41)) + + # Audio pins & clocks configuration + audio_mclk_pin = 16 + audio_mclk_freq = 12288000 + audio_i2c_sda = 13 + audio_i2c_scl = 14 + audio_i2s_sck = 9 + audio_i2s_ws = 45 + audio_i2s_tx_sd = 8 + audio_i2s_rx_sd = 10 + audio_amp_pin = 46 + audio_amp_active_level = 1 # Active High (1 = enabled) + audio_mic_codec = "ES7210" + return + + except Exception as e: + print("I2C scan on Waveshare RLCD pins failed:", e) + + # 4. Fallback default if auto-detection failed completely + print("Auto-detection failed. Falling back to Hosyond ESP32-S3 defaults...") + BOARD_TYPE = 'HOSYOND' + DISPLAY_TYPE = 'ILI9341' + DISPLAY_WIDTH = 320 + DISPLAY_HEIGHT = 240 + led_pin = 48 + + try: + i2c_bus = I2C(0, sda=Pin(16), scl=Pin(15)) + spi_bus = SPI(1, baudrate=40000000, polarity=0, phase=0, sck=Pin(12), mosi=Pin(11), miso=Pin(13)) + import ili9341 + display_instance = ili9341.ILI9341(spi_bus, cs=Pin(10), dc=Pin(46), bl=Pin(45), rst=None) + from ft6336u import FT6336U + touch = FT6336U(i2c_bus, rst_pin=18, int_pin=17, width=320, height=240, swap_xy=True, invert_x=False, invert_y=True) + except Exception as e: + print("Fallback hardware setup failed:", e) + + audio_mclk_pin = 4 + audio_mclk_freq = 6144000 + audio_i2c_sda = 16 + audio_i2c_scl = 15 + audio_i2s_sck = 5 + audio_i2s_ws = 7 + audio_i2s_tx_sd = 8 + audio_i2s_rx_sd = 6 + audio_amp_pin = 1 + audio_amp_active_level = 0 + audio_mic_codec = "ES8311" + +# Run dynamic detection immediately on module load +detect_board() diff --git a/main.py b/main.py index 0246991..95a89b1 100644 --- a/main.py +++ b/main.py @@ -8,11 +8,7 @@ try: has_network = True except ImportError: has_network = False - -if sys.platform == 'rp2': - import st7796 as display_module -else: - import ili9341 as display_module +import board_config class DummyMCP: def __init__(self): @@ -74,61 +70,45 @@ local_led_mode_idx = 1 # Green breathing def main(): global local_led_mode_idx - print("=== Starting ESP32-S3-RLCD-4.2 Main Boot ===") + import board_config - # 1. Initialize shared buses and peripherals - i2c = None - if sys.platform != 'rp2': - try: - i2c = I2C(0, sda=Pin(16), scl=Pin(15)) - except Exception as e: - print("Failed to initialize I2C0:", e) + print("=== Starting MCP Server Main Boot (Type: {}) ===".format(board_config.BOARD_TYPE)) - if sys.platform == 'rp2': - spi = SPI(1, baudrate=32000000, polarity=0, phase=0, sck=Pin(10), mosi=Pin(11)) - display = display_module.ST7796(spi, cs=Pin(7), dc=Pin(4), rst=Pin(9), bl=Pin(6)) - - # Touch controller - touch = None - try: - touch_i2c = I2C(1, sda=Pin(2), scl=Pin(3), freq=400000) - from ft6336u import FT6336U - touch = FT6336U(touch_i2c, rst_pin=28, int_pin=25) - except Exception as te: - print("Failed to initialize touch:", te) - else: - spi = SPI(1, baudrate=40000000, polarity=0, phase=0, sck=Pin(12), mosi=Pin(11), miso=Pin(13)) - display = display_module.ILI9341(spi, cs=Pin(10), dc=Pin(46), bl=Pin(45), rst=None) - touch = None - try: - from ft6336u import FT6336U - touch = FT6336U(i2c, rst_pin=18, int_pin=17, width=320, height=240, swap_xy=True, invert_x=False, invert_y=True) - except Exception as te: - print("Failed to initialize touch:", te) + # 1. Use pre-initialized display and buses from board_config + i2c = board_config.i2c_bus + spi = board_config.spi_bus + display = board_config.display_instance + touch = board_config.touch - if sys.platform != 'rp2': - # Configure Audio Amp control pin (GPIO 1, Active Low) to save power - amp_pin = Pin(1, Pin.OUT, value=1) + # Configure Audio Amp control pin to save power + if sys.platform != 'rp2' and board_config.audio_amp_pin is not None: + # Turn OFF amplifier on boot (active-low vs active-high) + off_val = 1 if board_config.audio_amp_active_level == 0 else 0 + amp_pin = Pin(board_config.audio_amp_pin, Pin.OUT, value=off_val) # 2. Initialize utility objects sensor = None rtc_chip = None if i2c is not None: - try: - sensor = SHTC3(i2c) - except Exception as e: - print("Failed to initialize SHTC3:", e) - try: - rtc_chip = PCF85063(i2c) - except Exception as e: - print("Failed to initialize PCF85063:", e) + if board_config.has_sensor: + try: + sensor = SHTC3(i2c) + except Exception as e: + print("Failed to initialize SHTC3:", e) + if board_config.has_rtc: + try: + rtc_chip = PCF85063(i2c) + except Exception as e: + print("Failed to initialize PCF85063:", e) battery = BatteryMonitor() - led = BoardLED() + led = BoardLED(board_config.led_pin) buttons = None if sys.platform != 'rp2': buttons = BoardButtons() - ble_uart = BLEUART(name="ESP32-S3-TFT") + + ble_name = "ESP32-S3-" + ("RLCD" if board_config.BOARD_TYPE == "WAVESHARE_RLCD" else "Touch") + ble_uart = BLEUART(name=ble_name) # Sync system clock from RTC chip if rtc_chip: @@ -229,9 +209,10 @@ def main(): print("Touch detected! Starting Hermes Voice Assistant...") def draw_status_bar(text): - display.line(0, 215, 320, 215, 1) - display.fill_rect(0, 216, 320, 24, 0) - display.text(text, 10, 222, 1) + y_bar = display.height - 25 + display.line(0, y_bar, display.width, y_bar, 1) + display.fill_rect(0, y_bar + 1, display.width, 24, 0) + display.text(text, 10, y_bar + 7, 1) display.show() def clear_status_bar(): @@ -454,10 +435,10 @@ def main(): # Draw standard status dashboard layout display.clear(0) - title_text = "RP2350-TFT MCP SERVER" if sys.platform == 'rp2' else "Hosyond ESP32-S3 Server" - line_w = 470 if sys.platform == 'rp2' else 310 + line_w = display.width - 10 - if sys.platform == 'rp2': + if board_config.BOARD_TYPE == 'WAVESHARE_RLCD' or sys.platform == 'rp2': + title_text = "RP2350-TFT MCP SERVER" if sys.platform == 'rp2' else "Waveshare ESP32-S3-RLCD Server" display.text(title_text, 10, 10, 1) display.line(10, 20, line_w, 20, 1) display.text_large("ENVIRONMENT", 15, 30, scale=2, c=1) @@ -467,7 +448,7 @@ def main(): display.text_large("MCP NET CONNECTION", 15, 105, scale=2, c=1) display.text(f"IP Address : {ip_addr}", 25, 130, 1) display.text(f"Port / Path : 80 /api/mcp", 25, 145, 1) - display.text(f"BLE Name : ESP32-S3-RLCD", 25, 160, 1) + display.text(f"BLE Name : {ble_name}", 25, 160, 1) display.line(10, 185, line_w, 185, 1) display.text_large("SYSTEM STATUS", 15, 195, scale=2, c=1) display.text(f"Battery : {bat_str}", 25, 220, 1) @@ -475,6 +456,7 @@ def main(): display.line(10, 255, line_w, 255, 1) display.text(f"Status: {last_action_str}", 15, 265, 1) else: + title_text = "Hosyond ESP32-S3 Server" display.text(title_text, 10, 8, 1) display.line(10, 18, line_w, 18, 1) # Left Column (System & Environment) @@ -490,7 +472,7 @@ def main(): display.line(170, 38, line_w, 38, 1) display.text(f"IP : {ip_addr}", 170, 46, 1) display.text("Port: 80/api/mcp", 170, 58, 1) - display.text("BLE : S3-TFT", 170, 70, 1) + display.text(f"BLE : {ble_name[-6:]}", 170, 70, 1) # Bottom Status display.line(10, 115, line_w, 115, 1) display.text(f"Status: {last_action_str}", 10, 125, 1) diff --git a/upload_files.py b/upload_files.py index a9c1da4..58e3841 100644 --- a/upload_files.py +++ b/upload_files.py @@ -54,8 +54,10 @@ def main(): # Upload new drivers, utilities, and updated scripts files_to_upload = [ + ("lib/board_config.py", "lib/board_config.py"), ("lib/st7796.py", "lib/st7796.py"), ("lib/ft6336u.py", "lib/ft6336u.py"), + ("lib/rlcd.py", "lib/rlcd.py"), ("lib/battery_util.py", "lib/battery_util.py"), ("lib/rgb_led_util.py", "lib/rgb_led_util.py"), ("lib/audio_util.py", "lib/audio_util.py"),