diff --git a/esphome/bambu-display/README.md b/esphome/bambu-display/README.md index edd4aaf..aee6655 100644 --- a/esphome/bambu-display/README.md +++ b/esphome/bambu-display/README.md @@ -84,17 +84,22 @@ printer rotation are outside its current scope. ## Install -1. Keep `esphome/bambu-printer-display.yaml` and the entire `bambu-display/` folder - together in the ESPHome configuration directory. The generated package is checked - in, so the ESPHome dashboard can compile it without running the generator first. +1. Keep both device files and the entire `bambu-display/` folder together in the + ESPHome configuration directory. `bambu-printer-display.yaml` is the first board + and `bambu-printer-display-2.yaml` is the second. They share `board.yaml` and the + generated fleet package, which is checked in, so the ESPHome dashboard can compile + either file without running the generator first. 2. Supply the existing `api_encryption_key`, `wifi_iot_ssid` and `wifi_password` entries in that directory's `secrets.yaml`. -3. Use ESPHome **2026.9.0 or newer**. Compile and install - `bambu-printer-display.yaml` over the board's USB-to-UART bridge for the first - flash; subsequent installs can use encrypted OTA. -4. Add **Bambu Printer Display** through Home Assistant's ESPHome integration using - the same API encryption key. The display only subscribes to entities, so it does - not require permission to perform Home Assistant actions. +3. Use ESPHome **2026.9.0 or newer**. Compile and install the matching device file + over that board's USB-to-UART bridge for the first flash; subsequent installs can + use encrypted OTA. Flash `bambu-printer-display.yaml` to the first panel and + `bambu-printer-display-2.yaml` to the second. Each file has its own ESPHome name, + so both panels can be online together. +4. Add **Bambu Printer Display** or **Bambu Printer Display 2** through Home + Assistant's ESPHome integration using the same API encryption key. Each display + only subscribes to entities, so it does not require permission to perform Home + Assistant actions. 5. Confirm all pages receive data and verify touch direction and color order on the physical panel. Entity IDs match the repository's `ha-entities.txt` snapshot; renamed or disabled entities in live HA must be corrected/enabled there. @@ -103,7 +108,7 @@ The USB D+/D− GPIO19/20 pins are used by the board's touch bus. Logging theref uses UART0. ESPHome may still warn about these two pins; they are intentional for this board. If GT911 is not found at `0x5D`, inspect the I²C scan and use its reported address (some hardware revisions select `0x14`). Backlight is GPIO2; RGB data pins -and timings are explicit in the main YAML rather than borrowed from a 5″ board. +and timings are explicit in `board.yaml` rather than borrowed from a 5″ board. The display and LVGL both use **big-endian RGB565**. With `mipi_rgb`'s named `red`/`green`/`blue` pin groups, its generated bus pin map already exchanges the @@ -121,7 +126,9 @@ CLI checks from the repository root: ```sh esphome config esphome/bambu-printer-display.yaml +esphome config esphome/bambu-printer-display-2.yaml esphome compile esphome/bambu-printer-display.yaml +esphome compile esphome/bambu-printer-display-2.yaml ``` ## Change or expand the fleet diff --git a/esphome/bambu-display/board.yaml b/esphome/bambu-display/board.yaml new file mode 100644 index 0000000..c0f8a50 --- /dev/null +++ b/esphome/bambu-display/board.yaml @@ -0,0 +1,114 @@ +# Shared Sunton ESP32-8048S043C board for every fleet display. +# Device name and friendly name come from the top-level YAML substitutions. +esphome: + name: ${device_name} + friendly_name: ${friendly_name} + min_version: 2026.9.0 + includes: + - bambu-display/dashboard.h + +esp32: + board: esp32-s3-devkitc-1 + flash_size: 16MB + flash_mode: dio + cpu_frequency: 240MHz + framework: + type: esp-idf + sdkconfig_options: + CONFIG_ESP32S3_DATA_CACHE_64KB: "y" + CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y" + CONFIG_SPIRAM_FETCH_INSTRUCTIONS: "y" + CONFIG_SPIRAM_RODATA: "y" + +psram: + mode: octal + speed: 80MHz + +logger: + hardware_uart: UART0 # GPIO19/20 are the touch bus, not native USB. + +api: + id: ha_api + encryption: + key: !secret api_encryption_key + +ota: + - platform: esphome + encryption: + key: !secret api_encryption_key + +wifi: + ssid: !secret wifi_iot_ssid + password: !secret wifi_password + +i2c: + id: touch_bus + sda: GPIO19 + scl: GPIO20 + scan: true + +display: + - platform: mipi_rgb + id: panel_display + model: RPI + dimensions: 800x480 + color_order: RGB + # Named RGB data_pins are byte-swapped by mipi_rgb's pin mapping. + # Send big-endian RGB565 pixels to match that wiring transformation. + byte_order: big_endian + de_pin: GPIO40 + hsync_pin: GPIO39 + vsync_pin: GPIO41 + pclk_pin: GPIO42 + pclk_inverted: true + pclk_frequency: 16MHz + hsync_front_porch: 8 + hsync_pulse_width: 4 + hsync_back_porch: 8 + vsync_front_porch: 8 + vsync_pulse_width: 4 + vsync_back_porch: 8 + data_pins: + red: [GPIO45, GPIO48, GPIO47, GPIO21, GPIO14] + green: [GPIO5, GPIO6, GPIO7, GPIO15, GPIO16, GPIO4] + blue: [GPIO8, GPIO3, GPIO46, GPIO9, GPIO1] + auto_clear_enabled: false + update_interval: never + +touchscreen: + - platform: gt911 + id: panel_touch + display: panel_display + i2c_id: touch_bus + address: 0x5D + # Polling avoids the GT911 INT pin's boot/address-selection behaviour. + update_interval: 20ms + +output: + - platform: ledc + id: backlight_output + pin: GPIO2 + +light: + - platform: monochromatic + id: panel_backlight + name: Backlight + output: backlight_output + restore_mode: ALWAYS_ON + default_transition_length: 0s + +time: + - platform: homeassistant + id: ha_time + timezone: America/New_York + +lvgl: + id: dashboard + displays: [panel_display] + touchscreens: [panel_touch] + buffer_size: 12% + color_depth: 16 + byte_order: big_endian # Must match mipi_rgb's named RGB pin mapping above. + bg_color: 0x000000 + text_color: 0xEEEEEE + default_font: montserrat_18 diff --git a/esphome/bambu-display/test_generate.py b/esphome/bambu-display/test_generate.py index fc3c900..9397d38 100644 --- a/esphome/bambu-display/test_generate.py +++ b/esphome/bambu-display/test_generate.py @@ -123,7 +123,7 @@ class FleetTests(unittest.TestCase): pass for tag in ('!secret', '!include'): Loader.add_constructor(tag, lambda loader, node: loader.construct_scalar(node)) - config = yaml.load((HERE.parent / 'bambu-printer-display.yaml').read_text(), Loader=Loader) + config = yaml.load((HERE / 'board.yaml').read_text(), Loader=Loader) display = config['display'][0] pins = display['data_pins'] natural = pins['blue'] + pins['green'] + pins['red'] @@ -135,6 +135,18 @@ class FleetTests(unittest.TestCase): for i, pin in enumerate(driver)) self.assertEqual(panel_word, color, f'RGB565 color {color:#06x} is wired incorrectly') + def test_both_boards_share_one_hardware_package(self): + class Loader(yaml.SafeLoader): + pass + Loader.add_constructor('!include', lambda loader, node: loader.construct_scalar(node)) + names = set() + for filename in ('bambu-printer-display.yaml', 'bambu-printer-display-2.yaml'): + config = yaml.load((HERE.parent / filename).read_text(), Loader=Loader) + names.add(config['substitutions']['device_name']) + self.assertEqual(config['packages']['board'], 'bambu-display/board.yaml') + self.assertEqual(config['packages']['fleet'], 'bambu-display/generated.yaml') + self.assertEqual(len(names), 2) + def test_diagnostic_color_page_is_skipped_during_normal_navigation(self): package = generate(self.printers) page = next(page for page in package['lvgl']['pages'] if page['id'] == 'color_test_page') diff --git a/esphome/bambu-printer-display-2.yaml b/esphome/bambu-printer-display-2.yaml new file mode 100644 index 0000000..03dbf1e --- /dev/null +++ b/esphome/bambu-printer-display-2.yaml @@ -0,0 +1,10 @@ +# Second Sunton ESP32-8048S043C fleet display. Same pages and hardware as +# bambu-printer-display.yaml, with its own ESPHome name so both boards can +# join Home Assistant. Edit bambu-display/printers.yaml, then run generate.py. +substitutions: + device_name: bambu-printer-display-2 + friendly_name: Bambu Printer Display 2 + +packages: + board: !include bambu-display/board.yaml + fleet: !include bambu-display/generated.yaml diff --git a/esphome/bambu-printer-display.yaml b/esphome/bambu-printer-display.yaml index 46f51fe..787d4cd 100644 --- a/esphome/bambu-printer-display.yaml +++ b/esphome/bambu-printer-display.yaml @@ -1,121 +1,10 @@ # Sunton ESP32-8048S043C: 4.3" 800x480 RGB LCD + GT911 capacitive touch. # Edit bambu-display/printers.yaml, then run its generate.py to change the fleet. +# The second board is bambu-printer-display-2.yaml; both include bambu-display/board.yaml. substitutions: device_name: bambu-printer-display friendly_name: Bambu Printer Display -esphome: - name: ${device_name} - friendly_name: ${friendly_name} - min_version: 2026.9.0 - includes: - - bambu-display/dashboard.h - -esp32: - board: esp32-s3-devkitc-1 - flash_size: 16MB - flash_mode: dio - cpu_frequency: 240MHz - framework: - type: esp-idf - sdkconfig_options: - CONFIG_ESP32S3_DATA_CACHE_64KB: "y" - CONFIG_ESP32S3_DATA_CACHE_LINE_64B: "y" - CONFIG_SPIRAM_FETCH_INSTRUCTIONS: "y" - CONFIG_SPIRAM_RODATA: "y" - -psram: - mode: octal - speed: 80MHz - -logger: - hardware_uart: UART0 # GPIO19/20 are the touch bus, not native USB. - -api: - id: ha_api - encryption: - key: !secret api_encryption_key - -ota: - - platform: esphome - encryption: - key: !secret api_encryption_key - -wifi: - ssid: !secret wifi_iot_ssid - password: !secret wifi_password - -i2c: - id: touch_bus - sda: GPIO19 - scl: GPIO20 - scan: true - -display: - - platform: mipi_rgb - id: panel_display - model: RPI - dimensions: 800x480 - color_order: RGB - # Named RGB data_pins are byte-swapped by mipi_rgb's pin mapping. - # Send big-endian RGB565 pixels to match that wiring transformation. - byte_order: big_endian - de_pin: GPIO40 - hsync_pin: GPIO39 - vsync_pin: GPIO41 - pclk_pin: GPIO42 - pclk_inverted: true - pclk_frequency: 16MHz - hsync_front_porch: 8 - hsync_pulse_width: 4 - hsync_back_porch: 8 - vsync_front_porch: 8 - vsync_pulse_width: 4 - vsync_back_porch: 8 - data_pins: - red: [GPIO45, GPIO48, GPIO47, GPIO21, GPIO14] - green: [GPIO5, GPIO6, GPIO7, GPIO15, GPIO16, GPIO4] - blue: [GPIO8, GPIO3, GPIO46, GPIO9, GPIO1] - auto_clear_enabled: false - update_interval: never - -touchscreen: - - platform: gt911 - id: panel_touch - display: panel_display - i2c_id: touch_bus - address: 0x5D - # Polling avoids the GT911 INT pin's boot/address-selection behaviour. - update_interval: 20ms - -output: - - platform: ledc - id: backlight_output - pin: GPIO2 - -light: - - platform: monochromatic - id: panel_backlight - name: Backlight - output: backlight_output - restore_mode: ALWAYS_ON - default_transition_length: 0s - -time: - - platform: homeassistant - id: ha_time - timezone: America/New_York - packages: + board: !include bambu-display/board.yaml fleet: !include bambu-display/generated.yaml - -lvgl: - id: dashboard - displays: [panel_display] - touchscreens: [panel_touch] - buffer_size: 12% - color_depth: 16 - byte_order: big_endian # Must match mipi_rgb's named RGB pin mapping above. - bg_color: 0x000000 - text_color: 0xEEEEEE - default_font: montserrat_18