# Planar EL512.256-H on ESP32 Drive a Planar EL512.256-H (512 × 256, monochrome electroluminescent) panel from an ESP-WROOM-32 (classic ESP32), with an [Adafruit GFX](https://github.com/adafruit/Adafruit-GFX-Library) compatible driver so the usual drawing, text and font APIs work. The panel has no frame memory and needs a continuous video stream. The ESP32's I2S0 peripheral in 8-bit parallel (LCD) mode streams a precomputed frame from DMA, so the CPU is free while the panel refreshes. **Status:** framebuffer, GFX layer, row encoder and I2S/DMA refresh are implemented and run on hardware: the panel shows a correct image (VCLK 5 MHz, HS and VS checked with the ESP32's PCNT). Updates are not yet tear-free. ## Hardware - ESP-WROOM-32 dev board (`esp32dev`) - Planar EL512.256-H, configured for **two-bit parallel mode**: jumper 2 (DCONFIG) of pin strip PS1 removed, jumper 1 (SELFTST) fitted (datasheet Table 3) - Datasheet: [docs/datasheet/EL512.256-H3 FRB.pdf](docs/datasheet/EL512.256-H3%20FRB.pdf) - Check the panel's logic-level and supply requirements in the datasheet before wiring. ## Wiring | Panel signal | Panel pin (Table 1) | Function | ESP32 GPIO | DMA byte bit | |--------------|---------------------|----------------------------------------------|-----------:|-------------:| | VCLK | J1-13 | Video clock, data latched on rising edge | 18 | I2S0 BCK | | VID | J1-15 | Pixel data, even columns (x = 1, 3, …) | 19 | 0 | | TVID | J1-7 | Pixel data, odd columns (x = 0, 2, …) | 21 | 1 | | HS | J1-11 | Horizontal sync | 22 | 2 | | VS | J1-9 | Vertical sync (rising edge used) | 23 | 3 | | ENABLE | J2-6 | Display enable, low = off | 25 | — | | _LOWPWR | J2-5 | Low-power mode, low = on | 26 | — | | GND | J1-6, 8, 10, 12, 14, 16 | Signal return | GND | — | The datasheet numbers columns 1 to 512 from the left; x in the code is 0-based, so x = 0 is column 1 (odd, TVID). Power (Table 1, Table 4): Vcc1 +5 V logic on J1-3, 4 (4.75–5.25 V, 0.2 A max); Vcc2 +11…+30 V on J1-1, 2 (0.9 A max at 12 V). J1-5 is reserved: do not connect. The panel inputs are HCT compatible with internal pull-ups of unstated voltage, and the ESP32 is not 5 V tolerant, so drive them through a 74HCT245 or 74AHCT541 powered from 5 V (see the plan). ENABLE is pulled high inside the panel, so the panel scans while the ESP32 is still booting and VCLK is not running yet; add a pull-down (for example 10 kΩ) on the buffer's ENABLE input so the panel stays off until `begin()` starts the stream. Keep the cable under 300 mm, or add 47 Ω series resistors for up to 2 m. The pin map lives in [include/pins.h](include/pins.h). ## Timing | Parameter | Value | Datasheet limit (Tables 5, 6) | |----------------------|-----------------------------------------|---------------------------------| | Pixel clock (VCLK) | 5 MHz, 2 pixels per clock | 30 MHz max, keep running | | HS high (T7) | 256 clocks | 256 in two-bit mode, even | | HS low (T6) | 16 clocks | 4 clocks min | | HS period (T8) | 272 clocks = 54.4 µs | 50 µs min | | Lines per frame | 261 (256 visible + 5 blanking) | 256 rows + T1 | | Front porch (T1) | 220.8 µs (last row end to VS rise) | 100 µs min | | Refresh | 5 MHz / (272 × 261) ≈ 70.4 Hz | 70 Hz typ, 75 Hz max | The datasheet ([docs/datasheet/](docs/datasheet/EL512.256-H3%20FRB.pdf)) is the source of truth; if anything here disagrees with it, the datasheet wins. ## Layout ``` platformio.ini build config: envs still_alive (default) and esp32dev include/pins.h pin map src/still_alive/ Portal-style end-credits demo (env still_alive) src/test_images/ test sketch: cycles through 12 test images (env esp32dev) lib/EL512/ local library src/EL512Panel.* framebuffer, row encoder, I2S DMA refresh src/EL512_GFX.* Adafruit_GFX subclass tools/ import_still_alive.py test/ unit tests (placeholder) docs/ datasheet and notes ``` ## Build and flash Requires [PlatformIO](https://platformio.org/) (CLI or the VS Code extension). The upload and monitor port is set to COM20 in `platformio.ini`. ```bash pio run -e still_alive -t upload # end-credits demo pio run -e esp32dev -t upload # test images pio device monitor ``` ## Still Alive demo ![Still Alive demo running on the EL512.256-H](docs/images/still_alive.jpg) A recreation of Portal's ending: timed song text typed into a console on the left, credits scrolling top right, ASCII art bottom right. The text, timing, art and credits in `src/still_alive/imported.h` come from [SDSkyKlouD/still-alive-web](https://github.com/SDSkyKlouD/still-alive-web) and can be regenerated with: ```bash python tools/import_still_alive.py pio run -e still_alive -t upload ``` Without `imported.h` the demo plays placeholder text. Reset the board and start the song when the serial log says (7.75 s after reset with the imported data). **Disclaimer:** "Still Alive" was written by Jonathan Coulton for Portal (2007). Portal, its credits and ASCII art are © Valve Corporation (see [Valve Legal Info](https://store.steampowered.com/legal/)); the web recreation they are imported from is by [SD SkyKlouD](https://github.com/SDSkyKlouD/still-alive-web). They are included only for personal, non-commercial use in this hobby project, and all rights remain with their owners. This project is not affiliated with or endorsed by Valve. ## Using the driver ```cpp #include #include "pins.h" EL512Panel panel({el512pins::VCLK, el512pins::VID, el512pins::TVID, el512pins::HS, el512pins::VS, el512pins::ENABLE, el512pins::LOWPWR_N}); EL512_GFX display(panel); void setup() { display.begin(); display.setTextColor(1); display.print("Hello"); display.display(); // push the drawing buffer to the refresh stream } ``` See [docs/README.md](docs/README.md) for design notes and the plan.