Files
waveshare-panel/README.md
T

173 lines
4.4 KiB
Markdown
Raw Normal View History

2026-05-09 22:50:52 -07:00
# 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 | Pin24/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.