# Samsung serial VFD — ESPHome component An ESPHome external component for the Samsung 2-line × 20-character serial VFD (vacuum fluorescent display) that takes 5 V TTL serial at 9600 baud, 8N1. It keeps a copy of the screen in RAM and only sends data when something changes. Updates overwrite the screen in place instead of clearing it first, so the clock doesn't flicker. ``` components/samsung_vfd/ the component (Python schema + C++) examples/samsung-vfd.yaml full example: clock + two Home Assistant text entities examples/secrets.yaml.example ``` ## Using it from your ESPHome server Add this to your device YAML. ESPHome fetches the component from git when it compiles. ```yaml external_components: - source: github://REPO_OWNER/REPO_NAME@main components: [samsung_vfd] refresh: 1d uart: id: uart_vfd tx_pin: GPIO17 baud_rate: 9600 time: # needed by the component (used by samsung_vfd.printf) - platform: sntp id: sntp_time samsung_vfd: id: vfd uart_id: uart_vfd ``` For a complete device, copy [examples/samsung-vfd.yaml](examples/samsung-vfd.yaml) into your ESPHome config folder. Add the keys from [examples/secrets.yaml.example](examples/secrets.yaml.example) to your `secrets.yaml`. ## Wiring The component only sends to the display. The ESP32's 3.3 V output is enough for most 5 V TTL inputs. ESP32 GPIOs are **not** 5 V tolerant, so never connect the display's TX back to the ESP32 without a level shifter or divider. | Display | ESP32 | |---------|-------| | RX | GPIO17 (UART TX) | | GND | GND | | 5 V | external 5 V supply | The display draws more current than a dev-board regulator can comfortably supply. Power it from its own supply and connect the grounds together. To use GPIO1 (TX0, shared with USB logging), set `tx_pin: GPIO1` and `logger: baud_rate: 0` so log output doesn't end up on the display. If the display stays blank at 3.3 V levels, add a 74HCT125 or similar level shifter. ## Configuration ```yaml samsung_vfd: id: vfd uart_id: uart_vfd cols: 20 # default 20 (1–80) rows: 2 # default 2 (1–8) send_newlines: false # default false; send CR LF between lines ``` The UART must be 9600 baud with a `tx_pin`. The component requires a `time:` component in the config. ## Actions | Action | Options | |--------|---------| | `samsung_vfd.print` | `text` (templatable). Optional `line:` (0-based) replaces one line. Without `line:`, the text is word-wrapped over the whole screen; `\n` forces a new line. Optional `centered: true`. | | `samsung_vfd.printf` | Shows the current time formatted with strftime, e.g. `format: "%H:%M:%S"`. Requires `time_id:`. Takes the same `line:` and `centered:` options. Does nothing until the clock has synced. | | `samsung_vfd.clear` | Clears the screen. | | `samsung_vfd.home` | Moves the cursor home. | ```yaml - samsung_vfd.print: id: vfd line: 0 text: !lambda 'return "Temp " + to_string((int) id(temp).state) + " C";' - samsung_vfd.printf: id: vfd time_id: sntp_time line: 1 centered: true format: "%a %d %b %H:%M" ``` From a lambda you can call `id(vfd).print(...)`, `print_line(line, text, centered)`, `clear()`, `home()` and `line_text(line)`. Text is converted to one byte per character. Accented Latin-1 letters lose their accent (é → e), other non-ASCII characters become `?`, and control characters become spaces. ## What the example config does - On boot: clears the screen, shows `Hello World!` for 3 s, then restores line 1. - Bottom line: a live clock, `%a %d %b %H:%M:%S`, updated every second (SNTP, Europe/Amsterdam). - Two Home Assistant `text` entities: - **VFD line 1** (max 20 chars) is shown on the top line and kept across reboots. - **VFD status** (max 40 chars) shows a full-screen, word-wrapped, centred banner for 10 s. The clock pauses meanwhile, then line 1 and the clock come back. - Wi-Fi with a captive-portal fallback AP, OTA updates and an encrypted native API. ## Protocol | Bytes | Effect | |-------|--------| | `1B 40` (`ESC @`) | init / reset | | `0C` | clear screen | | `0B` | cursor home | | text | printed at the cursor; wraps to the next line by itself | Each update sends `0B` (home) followed by both lines, each padded to exactly `cols` characters. ## Troubleshooting - **Line 2 lands on the wrong row, or text runs together:** try `send_newlines: true`. - **The screen scrolls up a line after each update:** the display scrolls as soon as the last cell is written. Use `cols: 19` together with `send_newlines: true`. - **A stray character appears top-left:** the display doesn't treat `0B` as home. Change `CMD_HOME` in [samsung_vfd.h](components/samsung_vfd/samsung_vfd.h). - **Garbled characters:** check that `uart:` is at 9600 baud and that the display takes 5 V TTL levels, not RS-232 levels. A real RS-232 input needs a MAX232 inverter.