# Waveshare 2.9" Touch ePaper Panel ESPHome project for the [Waveshare 2.9inch Touch e-Paper HAT](https://www.waveshare.com/2.9inch-Touch-e-Paper-HAT.htm) on an ESP32-WROOM-32 (NodeMCU-32S). Drives an LVGL UI with 2-bit grayscale rendering and touchscreen input. ## Hardware - **MCU:** ESP32-WROOM-32 (NodeMCU-32S) - **Display:** SSD1680, 296×128, 2-bit grayscale via custom component - **Touchscreen:** GT1151 / ICNT86X (I2C, polling mode) ### Wiring | Function | ESP Pin | HAT Pin | |--- |--- |--- | | Display SCLK | GPIO18 | Pin23/GPIO11/SPI0_SCLK | | Display MOSI | GPIO23 | Pin19/GPIO10/SPI0_MOSI | | Display CS | GPIO19 | Pin24/GPIO8/SPI0_CE0 | | Display DC | GPIO17 | Pin22/GPIO25 | | Display BUSY | GPIO4 | Pin18/GPIO24 | | Display RST | GPIO5 | Pin11/GPIO17/SPI1_CE1 | | Touch SDA | GPIO21 | Pin3/GPIO2/I2C1_SDA | | Touch SCL | GPIO22 | Pin5/GPIO3/I2C1_SCL | | Touch RST | GPIO15 | Pin13/GPIO27 | | Touch INT | GPIO16 | Pin15/GPIO22 | ## Project Structure ``` waveshare-panel/ ├── waveshare-test.yaml # Main ESPHome config (edit LVGL layout here) ├── secrets.yaml # WiFi/API credentials (not committed) ├── FreeSans.ttf # Font used in LVGL └── custom_components/ ├── waveshare_epaper_2bit/ # 2-bit grayscale display driver └── icnt86x/ # ICNT86X touchscreen driver ``` ## Build Environment Setup ### 1. Install Python 3.11 ESPHome 2026.1.0 requires Python 3.11. Check your version: ```bash python3 --version ``` On Ubuntu/Debian, install it if needed: ```bash sudo apt update sudo apt install python3.11 python3.11-venv python3.11-dev ``` On macOS with Homebrew: ```bash brew install python@3.11 ``` ### 2. Create a virtual environment for ESPHome 2026.1.0 Using a dedicated venv keeps this version isolated from other ESPHome installs. ```bash python3.11 -m venv ~/esphome-env/esphome-2026.1.0 source ~/esphome-env/esphome-2026.1.0/bin/activate ``` ### 3. Install ESPHome 2026.1.0 ```bash pip install esphome==2026.1.0 ``` Verify the install: ```bash esphome version # Expected: Version: 2026.1.0 ``` ### 4. Activate the environment (each session) ```bash source ~/esphome-env/esphome-2026.1.0/bin/activate ``` You can add this to your shell profile or run it manually before working on the project. ## Building and Flashing All commands assume the venv is active and you are in the project directory. ### Compile only ```bash esphome compile waveshare-test.yaml ``` ### Flash via USB (first flash or if OTA fails) ```bash esphome upload waveshare-test.yaml ``` Connect the ESP32 via USB before running. You may need to hold the BOOT button during flashing if the device doesn't enter download mode automatically. ### Flash via OTA (subsequent flashes) Once the device is on WiFi, OTA upload works without USB: ```bash esphome upload waveshare-test.yaml ``` ESPHome will automatically attempt OTA if the device is reachable. ### Monitor serial output ```bash esphome logs waveshare-test.yaml ``` Or via USB: ```bash esphome logs --device /dev/ttyUSB0 waveshare-test.yaml ``` ## Secrets Copy the secrets template and fill in your credentials: ```bash cp secrets.yaml.example secrets.yaml # if an example exists, otherwise create it ``` `secrets.yaml` format: ```yaml wifi_ssid: "YourNetworkName" wappw: "YourWiFiPassword" enckey: "<32-byte base64 Home Assistant API key>" apipw: "YourOTAPassword" hotspotpw: "FallbackPassword" ``` The `fallbackssid` variable is set in `waveshare-test.yaml` and does not go in secrets. ## Making Layout Changes The LVGL UI is defined in `waveshare-test.yaml` under the `lvgl:` block. The display renders at **296×128 pixels** in a 4-shade grayscale palette: | LVGL color | Shade | |------------|------------| | `0xFFFFFF` | White | | `0xAAAAAA` | Light grey | | `0x555555` | Dark grey | | `0x000000` | Black | After editing the YAML, compile and flash: ```bash esphome upload waveshare-test.yaml ``` The display uses a two-tier refresh: - **Partial refresh** (fast, 1-bit) — triggers immediately after any draw event for interactive feedback - **Full refresh** (2-bit grayscale quality) — triggers 10 seconds after the last draw event Full refresh restores proper 4-shade rendering after the fast partial updates.