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

147 lines
4.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.