Files
esphome-samsung-vfd/README.md
T
mangavalkandClaude Opus 5.5 bd9389e04a ESPHome external component for Samsung 2x20 serial VFD
Component (components/samsung_vfd), example device config, README and
CLAUDE.md.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-31 17:29:09 +01:00

4.8 KiB
Raw Blame History

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.

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 into your ESPHome config folder. Add the keys from 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

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.
- 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.
  • 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.